flexstr_support/
traits.rs

1#[cfg(feature = "cstr")]
2use alloc::ffi::CString;
3#[cfg(all(not(feature = "std"), feature = "bytes"))]
4use alloc::vec::Vec;
5#[cfg(not(feature = "std"))]
6use alloc::{borrow::ToOwned, boxed::Box, string::String};
7#[cfg(feature = "cstr")]
8use core::ffi::CStr;
9#[cfg(all(feature = "std", feature = "osstr"))]
10use std::ffi::{OsStr, OsString};
11#[cfg(all(feature = "std", feature = "path"))]
12use std::path::{Path, PathBuf};
13
14// *** StringToFromBytes ***
15
16/// Trait for string types that can be converted to and from bytes
17pub trait StringToFromBytes: ToOwned + 'static {
18    /// Convert bytes to a string type
19    fn bytes_as_self(bytes: &[u8]) -> &Self;
20
21    /// Convert a string type to bytes (excludes nul for CStr)
22    #[inline]
23    fn self_as_bytes(&self) -> &[u8] {
24        self.self_as_raw_bytes()
25    }
26
27    /// Convert a string type to raw bytes (inludes nul for CStr)
28    fn self_as_raw_bytes(&self) -> &[u8];
29}
30
31// *** StringFromBytesMut ***
32
33/// Trait for string types that can be converted from bytes to mutable string reference
34pub trait StringFromBytesMut: StringToFromBytes {
35    /// Convert bytes to a mutable string reference
36    fn bytes_as_self_mut(bytes: &mut [u8]) -> &mut Self;
37}
38
39// *** StringLike ***
40
41/// Trait for string types that provide various operations
42pub trait StringLike<S: ?Sized + StringToFromBytes>
43where
44    Self: Sized,
45{
46    /// Borrow a string reference as `&S`
47    fn as_ref_type(&self) -> &S;
48
49    /// Borrow the string as bytes
50    fn as_bytes(&self) -> &[u8];
51
52    /// Consume a string and convert it to an owned string. `S::to_owned` is called on Borrowed/Inlined/RefCounted variants.
53    /// Boxed variants are converted directly into `S::Owned` (most likely without copy or allocation).
54    fn into_owned_type(self) -> S::Owned
55    where
56        S::Owned: From<Box<S>>;
57
58    /// Convert a string reference to an owned string. `S::to_owned` is called on all variants.
59    fn to_owned_type(&self) -> S::Owned;
60
61    /// Returns true if this is an empty string
62    fn is_empty(&self) -> bool {
63        self.as_bytes().is_empty()
64    }
65
66    /// Returns the length of this string in bytes
67    fn len(&self) -> usize {
68        self.as_bytes().len()
69    }
70
71    /// Borrow the string as an `&str`
72    fn as_str(&self) -> &str
73    where
74        S: AsRef<str>,
75    {
76        self.as_ref_type().as_ref()
77    }
78
79    #[cfg(all(feature = "std", feature = "osstr"))]
80    /// Borrow the string as an `&OsStr`
81    fn as_os_str(&self) -> &OsStr
82    where
83        S: AsRef<OsStr>,
84    {
85        self.as_ref_type().as_ref()
86    }
87
88    #[cfg(all(feature = "std", feature = "path"))]
89    /// Borrow the string as a `&Path`
90    fn as_path(&self) -> &Path
91    where
92        S: AsRef<Path>,
93    {
94        self.as_ref_type().as_ref()
95    }
96
97    #[cfg(feature = "cstr")]
98    /// Borrow the string as a `&CStr`
99    fn as_c_str(&self) -> &CStr
100    where
101        S: AsRef<CStr>,
102    {
103        self.as_ref_type().as_ref()
104    }
105
106    /// Consume a string and convert it to a [String]
107    fn into_string(self) -> String
108    where
109        S::Owned: Into<String> + From<Box<S>>,
110    {
111        self.into_owned_type().into()
112    }
113
114    #[cfg(all(feature = "std", feature = "osstr"))]
115    /// Consume a string and convert it to an [OsString]
116    fn into_os_string(self) -> OsString
117    where
118        S::Owned: Into<OsString> + From<Box<S>>,
119    {
120        self.into_owned_type().into()
121    }
122
123    #[cfg(all(feature = "std", feature = "path"))]
124    /// Consume a string and convert it to a [PathBuf]
125    fn into_path_buf(self) -> PathBuf
126    where
127        S::Owned: Into<PathBuf> + From<Box<S>>,
128    {
129        self.into_owned_type().into()
130    }
131
132    #[cfg(feature = "cstr")]
133    /// Consume a string and convert it to a [CString]
134    fn into_c_string(self) -> CString
135    where
136        S::Owned: Into<CString> + From<Box<S>>,
137    {
138        self.into_owned_type().into()
139    }
140
141    #[cfg(feature = "bytes")]
142    /// Consume a string and convert it to a [`Vec<u8>`]
143    fn into_vec_bytes(self) -> Vec<u8>
144    where
145        S::Owned: Into<Vec<u8>> + From<Box<S>>,
146    {
147        self.into_owned_type().into()
148    }
149
150    /// Convert a string reference to a [String]
151    fn to_string(&self) -> String
152    where
153        S::Owned: Into<String>,
154    {
155        self.to_owned_type().into()
156    }
157
158    #[cfg(all(feature = "std", feature = "osstr"))]
159    /// Convert a string reference to an [OsString]
160    fn to_os_string(&self) -> OsString
161    where
162        S::Owned: Into<OsString>,
163    {
164        self.to_owned_type().into()
165    }
166
167    #[cfg(all(feature = "std", feature = "path"))]
168    /// Convert a string reference to a [PathBuf]
169    fn to_path_buf(&self) -> PathBuf
170    where
171        S::Owned: Into<PathBuf>,
172    {
173        self.to_owned_type().into()
174    }
175
176    #[cfg(feature = "cstr")]
177    /// Convert a string reference to a [CString]
178    fn to_c_string(&self) -> CString
179    where
180        S::Owned: Into<CString>,
181    {
182        self.to_owned_type().into()
183    }
184
185    #[cfg(feature = "bytes")]
186    /// Convert a string reference to a [`Vec<u8>`]
187    fn to_vec_bytes(&self) -> Vec<u8>
188    where
189        S::Owned: Into<Vec<u8>>,
190    {
191        self.to_owned_type().into()
192    }
193}