Skip to main content

cbor_core/
text.rs

1use std::borrow::Cow;
2
3use crate::Value;
4
5/// Conversion helper for [`Value::text_string`].
6///
7/// Wraps a `Cow<'a, str>` so that [`Value::text_string`] can accept
8/// owned and borrowed string inputs through a single
9/// `impl Into<TextString>` bound. This mirrors how [`Array`](crate::Array)
10/// and [`Map`](crate::Map) abstract their input shapes.
11///
12/// Supported source types:
13///
14/// - `&'a str` (and any `&'a T` with `T: AsRef<str>`) borrows zero-copy.
15/// - Owned `String` is moved without copying.
16/// - `Cow<'a, str>` is preserved as-is.
17/// - `char` allocates a one-character `String`.
18///
19/// ```
20/// # use cbor_core::Value;
21/// // Borrows from the literal:
22/// let v = Value::text_string("hello");
23/// assert_eq!(v.as_str().unwrap(), "hello");
24///
25/// // Owns its storage:
26/// let v = Value::text_string(String::from("hello"));
27/// assert_eq!(v.as_str().unwrap(), "hello");
28/// ```
29#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
30pub struct TextString<'a>(Cow<'a, str>);
31
32impl<'a> TextString<'a> {
33    /// Create an empty text string.
34    ///
35    /// The result is `Cow::Borrowed("")` and lives for any lifetime.
36    pub const fn new() -> Self {
37        Self(Cow::Borrowed(""))
38    }
39
40    /// Borrow the contents as a `&str`.
41    pub fn as_str(&self) -> &str {
42        self.0.as_ref()
43    }
44
45    /// Borrow the contents as a mutable `String`, cloning if the
46    /// inner `Cow` is currently borrowed.
47    pub fn as_string_mut(&mut self) -> &mut String {
48        self.0.to_mut()
49    }
50
51    /// Detach from any borrow, returning a `TextString` with an
52    /// independent lifetime.
53    ///
54    /// A borrowed `TextString<'a>` is copied into an owned `String`;
55    /// an already-owned one is returned unchanged. The result can
56    /// be assigned to any lifetime, in particular `TextString<'static>`.
57    pub fn into_owned<'b>(self) -> TextString<'b> {
58        match self.0 {
59            Cow::Borrowed(text) => TextString(text.to_string().into()),
60            Cow::Owned(text) => TextString(text.into()),
61        }
62    }
63}
64
65impl<'a> From<char> for TextString<'a> {
66    fn from(value: char) -> Self {
67        Self(value.to_string().into())
68    }
69}
70
71impl<'a, T> From<&'a T> for TextString<'a>
72where
73    T: AsRef<str> + ?Sized,
74{
75    fn from(value: &'a T) -> Self {
76        Self(value.as_ref().into())
77    }
78}
79
80impl<'a> From<String> for TextString<'a> {
81    fn from(value: String) -> Self {
82        Self(value.into())
83    }
84}
85
86impl<'a> From<Cow<'a, str>> for TextString<'a> {
87    fn from(value: Cow<'a, str>) -> Self {
88        Self(value)
89    }
90}
91
92impl<'a> From<TextString<'a>> for Value<'a> {
93    fn from(value: TextString<'a>) -> Self {
94        Self::TextString(value.0)
95    }
96}