non_empty_str/
str.rs

1//! Non-empty [`str`].
2
3#[cfg(feature = "unsafe-assert")]
4use core::hint::assert_unchecked;
5
6use core::{fmt, ops::Deref};
7
8use const_macros::{const_ok, const_try};
9
10#[cfg(feature = "serde")]
11use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
12
13use crate::empty::{Empty, check_str};
14
15/// Represents non-empty [`str`] values.
16#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub struct Str<'s> {
18    value: &'s str,
19}
20
21#[cfg(feature = "serde")]
22impl Serialize for Str<'_> {
23    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
24        self.get().serialize(serializer)
25    }
26}
27
28#[cfg(feature = "serde")]
29type Value<'s> = &'s str;
30
31#[cfg(feature = "serde")]
32impl<'de> Deserialize<'de> for Str<'de> {
33    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
34        let value = Value::deserialize(deserializer)?;
35
36        Self::new(value).map_err(Error::custom)
37    }
38}
39
40impl fmt::Display for Str<'_> {
41    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
42        self.get().fmt(formatter)
43    }
44}
45
46impl<'t> TryFrom<&'t str> for Str<'t> {
47    type Error = Empty;
48
49    fn try_from(value: &'t str) -> Result<Self, Self::Error> {
50        Self::new(value)
51    }
52}
53
54impl<'s> From<Str<'s>> for &'s str {
55    fn from(value: Str<'s>) -> Self {
56        value.take()
57    }
58}
59
60impl AsRef<str> for Str<'_> {
61    fn as_ref(&self) -> &str {
62        self.get()
63    }
64}
65
66impl Deref for Str<'_> {
67    type Target = str;
68
69    fn deref(&self) -> &Self::Target {
70        self.get()
71    }
72}
73
74impl<'s> Str<'s> {
75    /// Constructs [`Self`], provided the given value is non-empty.
76    ///
77    /// # Errors
78    ///
79    /// Returns [`Empty`] if the given string is empty.
80    pub const fn new(value: &'s str) -> Result<Self, Empty> {
81        const_try!(check_str(value));
82
83        Ok(unsafe { Self::new_unchecked(value) })
84    }
85
86    /// Similar to [`new`], but the error is discarded.
87    ///
88    /// [`new`]: Self::new
89    pub const fn new_ok(value: &'s str) -> Option<Self> {
90        const_ok!(Self::new(value))
91    }
92
93    /// Constructs [`Self`] without checking if the given value is non-empty.
94    ///
95    /// # Safety
96    ///
97    /// The caller must ensure that the given value is non-empty.
98    pub const unsafe fn new_unchecked(value: &'s str) -> Self {
99        Self { value }
100    }
101
102    #[cfg(feature = "unsafe-assert")]
103    const fn assert_non_empty(&self) {
104        unsafe { assert_unchecked(!self.value.is_empty()) }
105    }
106
107    /// Consumes [`Self`], returning the wrapped string.
108    pub const fn take(self) -> &'s str {
109        #[cfg(feature = "unsafe-assert")]
110        self.assert_non_empty();
111
112        self.value
113    }
114}
115
116impl Str<'_> {
117    /// Returns the wrapped string reference.
118    pub const fn get(&self) -> &str {
119        #[cfg(feature = "unsafe-assert")]
120        self.assert_non_empty();
121
122        self.value
123    }
124}