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