aliasable/
string.rs
1use core::ops::{Deref, DerefMut};
4use core::pin::Pin;
5use core::{fmt, str};
6
7use crate::vec::AliasableVec;
8
9pub use alloc::string::String as UniqueString;
10
11pub struct AliasableString(AliasableVec<u8>);
14
15impl AliasableString {
16 pub fn into_bytes(self) -> AliasableVec<u8> {
18 self.0
19 }
20
21 pub fn from_unique(s: UniqueString) -> Self {
23 Self(s.into_bytes().into())
24 }
25
26 #[inline]
28 pub fn into_unique(s: AliasableString) -> UniqueString {
29 let unique_bytes = s.into_bytes().into();
30 unsafe { UniqueString::from_utf8_unchecked(unique_bytes) }
31 }
32
33 pub fn into_unique_pin(pin: Pin<AliasableString>) -> Pin<UniqueString> {
36 unsafe {
38 let aliasable = Pin::into_inner_unchecked(pin);
39 Pin::new_unchecked(AliasableString::into_unique(aliasable))
40 }
41 }
42
43 pub fn from_unique_pin(pin: Pin<UniqueString>) -> Pin<AliasableString> {
46 unsafe {
48 let unique = Pin::into_inner_unchecked(pin);
49 Pin::new_unchecked(AliasableString::from(unique))
50 }
51 }
52}
53
54impl From<UniqueString> for AliasableString {
55 #[inline]
56 fn from(s: UniqueString) -> Self {
57 Self::from_unique(s)
58 }
59}
60
61impl From<AliasableString> for UniqueString {
62 #[inline]
63 fn from(s: AliasableString) -> Self {
64 AliasableString::into_unique(s)
65 }
66}
67
68impl Deref for AliasableString {
69 type Target = str;
70
71 #[inline]
72 fn deref(&self) -> &str {
73 unsafe { str::from_utf8_unchecked(&*self.0) }
75 }
76}
77
78impl DerefMut for AliasableString {
79 #[inline]
80 fn deref_mut(&mut self) -> &mut str {
81 unsafe { str::from_utf8_unchecked_mut(&mut *self.0) }
83 }
84}
85
86impl AsRef<str> for AliasableString {
87 #[inline]
88 fn as_ref(&self) -> &str {
89 &*self
90 }
91}
92
93impl AsMut<str> for AliasableString {
94 fn as_mut(&mut self) -> &mut str {
95 &mut *self
96 }
97}
98
99impl fmt::Debug for AliasableString {
100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101 fmt::Debug::fmt(self.as_ref(), f)
102 }
103}
104
105#[cfg(feature = "traits")]
106unsafe impl crate::StableDeref for AliasableString {}
107
108#[cfg(feature = "traits")]
109unsafe impl crate::AliasableDeref for AliasableString {}
110
111#[cfg(test)]
112mod tests {
113 use super::{AliasableString, AliasableVec, UniqueString};
114 use alloc::{format, vec};
115 use core::pin::Pin;
116
117 #[test]
118 fn test_new() {
119 let aliasable = AliasableString::from_unique(UniqueString::from("hello"));
120 assert_eq!(&*aliasable, &"hello"[..]);
121 let unique = AliasableString::into_unique(aliasable);
122 assert_eq!(&*unique, &"hello"[..]);
123 }
124
125 #[test]
126 fn test_new_pin() {
127 let aliasable = AliasableString::from_unique_pin(Pin::new(UniqueString::from("hello")));
128 assert_eq!(&*aliasable, &"hello"[..]);
129 let unique = AliasableString::into_unique_pin(aliasable);
130 assert_eq!(&*unique, &"hello"[..]);
131 }
132
133 #[test]
134 fn test_refs() {
135 let mut aliasable = AliasableString::from_unique(UniqueString::from("hello"));
136 let ptr: *const str = &*aliasable;
137 let as_mut_ptr: *const str = aliasable.as_mut();
138 let as_ref_ptr: *const str = aliasable.as_ref();
139 assert_eq!(ptr, as_mut_ptr);
140 assert_eq!(ptr, as_ref_ptr);
141 }
142
143 #[test]
144 fn test_debug() {
145 let aliasable = AliasableString::from_unique(UniqueString::from("hello"));
146 assert_eq!(format!("{:?}", aliasable), "\"hello\"");
147 }
148
149 #[test]
150 fn test_into_bytes() {
151 let aliasable = AliasableString::from_unique(UniqueString::from("hello"));
152 assert_eq!(
153 AliasableVec::into_unique(aliasable.into_bytes()),
154 vec![b'h', b'e', b'l', b'l', b'o']
155 );
156 }
157}