irox_tools/
str.rs

1// SPDX-License-Identifier: MIT
2// Copyright 2025 IROX Contributors
3//
4
5extern crate alloc;
6use alloc::string::{String, ToString};
7use alloc::sync::Arc;
8use irox_bits::{
9    Bits, Error, MutBits, ReadFromBEBits, ReadFromLEBits, WriteToBEBits, WriteToLEBits,
10};
11
12///
13/// Wrapper enum around the common string representations
14#[derive(Clone, Eq, PartialEq, Debug, Hash)]
15pub enum StrWrapper<'a> {
16    Shared(Arc<String>),
17    Owned(String),
18    Borrowed(&'a str),
19}
20impl Default for StrWrapper<'_> {
21    fn default() -> Self {
22        StrWrapper::Owned(Default::default())
23    }
24}
25impl AsRef<str> for StrWrapper<'_> {
26    fn as_ref(&self) -> &str {
27        self.as_str()
28    }
29}
30impl AsMut<str> for StrWrapper<'_> {
31    fn as_mut(&mut self) -> &mut str {
32        match self {
33            StrWrapper::Owned(o) => o,
34            StrWrapper::Shared(s) => {
35                *self = StrWrapper::Owned(s.to_string());
36                self.as_mut()
37            }
38            StrWrapper::Borrowed(b) => {
39                *self = StrWrapper::Owned((*b).to_string());
40                self.as_mut()
41            }
42        }
43    }
44}
45impl StrWrapper<'_> {
46    #[must_use]
47    pub fn as_str(&self) -> &str {
48        match self {
49            StrWrapper::Shared(s) => s.as_str(),
50            StrWrapper::Owned(s) => s.as_str(),
51            StrWrapper::Borrowed(s) => s,
52        }
53    }
54
55    #[must_use]
56    pub fn len(&self) -> usize {
57        self.as_str().len()
58    }
59
60    #[must_use]
61    pub fn is_empty(&self) -> bool {
62        self.as_str().is_empty()
63    }
64
65    #[must_use]
66    pub fn to_owned(&self) -> Self {
67        match self {
68            StrWrapper::Shared(a) => a.as_ref().clone().into(),
69            StrWrapper::Owned(o) => o.clone().into(),
70            StrWrapper::Borrowed(s) => (*s).to_string().into(),
71        }
72    }
73
74    #[must_use]
75    pub fn to_shared(&self) -> Self {
76        match self {
77            StrWrapper::Shared(a) => a.clone().into(),
78            StrWrapper::Owned(o) => Arc::new(o.clone()).into(),
79            StrWrapper::Borrowed(s) => Arc::new((*s).to_string()).into(),
80        }
81    }
82
83    pub fn make_shared(&mut self) {
84        match self {
85            StrWrapper::Shared(_) => {}
86            StrWrapper::Owned(o) => {
87                *self = StrWrapper::Shared(Arc::new(o.clone()));
88            }
89            StrWrapper::Borrowed(b) => {
90                *self = StrWrapper::Shared(Arc::new((*b).to_string()));
91            }
92        }
93    }
94}
95impl<'a> From<&'a str> for StrWrapper<'a> {
96    fn from(s: &'a str) -> Self {
97        StrWrapper::Borrowed(s)
98    }
99}
100impl From<String> for StrWrapper<'_> {
101    fn from(s: String) -> Self {
102        StrWrapper::Owned(s)
103    }
104}
105impl From<Arc<String>> for StrWrapper<'_> {
106    fn from(s: Arc<String>) -> Self {
107        StrWrapper::Shared(s)
108    }
109}
110impl From<&Arc<String>> for StrWrapper<'_> {
111    fn from(s: &Arc<String>) -> Self {
112        StrWrapper::Shared(s.clone())
113    }
114}
115
116impl WriteToBEBits for StrWrapper<'_> {
117    fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
118        self.as_str().write_be_to(bits)
119    }
120}
121impl ReadFromBEBits for StrWrapper<'_> {
122    fn read_from_be_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
123        ReadFromBEBits::read_from_be_bits(inp).map(StrWrapper::Owned)
124    }
125}
126impl WriteToLEBits for StrWrapper<'_> {
127    fn write_le_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
128        self.as_str().write_le_to(bits)
129    }
130}
131impl ReadFromLEBits for StrWrapper<'_> {
132    fn read_from_le_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
133        ReadFromLEBits::read_from_le_bits(inp).map(StrWrapper::Owned)
134    }
135}