istring/
common.rs

1macro_rules! define_common_bytes {
2    ($name:ident, $union:ident) => {
3impl $name {
4    /// view as Inline.
5    ///
6    /// Panics if the string isn't inlined
7    #[inline(always)]
8    pub unsafe fn as_inline(&mut self) -> &mut Inline {
9        debug_assert!(self.is_inline());
10        &mut self.union.inline
11    }
12
13    /// view as Heap.
14    ///
15    /// Panics if the string isn't on the Heap
16    #[inline(always)]
17    pub unsafe fn as_heap(&mut self) -> &mut Heap {
18        debug_assert!(!self.is_inline());
19        &mut self.union.heap
20    }
21
22    //#[inline]
23    //pub fn as_inline_or_heap(self) 
24    
25    #[inline(always)]
26    pub fn is_inline(&self) -> bool {
27        unsafe {
28            (self.union.inline.len & IS_INLINE) != 0
29        }
30    }
31    
32    #[inline(always)]
33    pub fn len(&self) -> usize {
34        unsafe {
35            if self.is_inline() {
36                (self.union.inline.len & LEN_MASK) as usize
37            } else {
38                self.union.heap.len
39            }
40        }
41    }
42    #[inline(always)]
43    pub fn as_mut_ptr(&mut self) -> *mut u8 {
44        unsafe {
45            if self.is_inline() {
46                &mut self.union.inline.data as *mut u8
47            } else {
48                self.union.heap.ptr
49            }
50        }
51    }
52    #[inline(always)]
53    pub fn as_slice(&self) -> &[u8] {
54        let len = self.len();
55        unsafe {
56            if self.is_inline() {
57                &self.union.inline.data[.. len]
58            } else {
59                slice::from_raw_parts(self.union.heap.ptr, len)
60            }
61        }
62    }
63    
64    #[inline(always)]
65    pub fn as_mut_slice(&mut self) -> &mut [u8] {
66        unsafe {
67            let len = self.len();
68            if self.is_inline() {
69                &mut self.union.inline.data[.. len]
70            } else {
71                slice::from_raw_parts_mut(self.union.heap.ptr, len)
72            }
73        }
74    }
75    /// Deconstruct into the Inline part and the allocator
76    ///
77    /// Assumes the string is inlined and panics otherwhise.
78    #[inline(always)]
79    pub fn to_inline(self) -> Inline {
80        assert_eq!(self.is_inline(), true);
81        unsafe {
82            let mut inline = self.union.inline;
83            mem::forget(self);
84            
85            inline.len &= !IS_INLINE; // clear the bit
86            inline
87        }
88    }
89    pub unsafe fn from_heap(heap: Heap) -> Self {
90        let union = $union { heap: heap };
91        assert_eq!(union.inline.len & IS_INLINE, 0);
92        $name { union: union }
93    }
94    pub unsafe fn from_inline(mut inline: Inline) -> Self {
95        assert!(inline.len as usize <= INLINE_CAPACITY);
96        inline.len |= IS_INLINE; // set inline bit
97        $name {
98            union: $union { inline: inline },
99        }
100    }
101    /// Deconstruct into the Heap part and the allocator
102    ///
103    /// Assumes it is heap-state, panics otherwhise. (you may want to call move_to_heap before this.)
104    /// The caller is responsible to adequatly dispose the owned memory. (for example by calling $name::from_heap)
105    #[inline(always)]
106    pub fn to_heap(self) -> Heap {
107        assert_eq!(self.is_inline(), false);
108        unsafe {
109            let heap = self.union.heap;
110            mem::forget(self);
111            
112            heap
113        }
114    }
115}
116impl ops::Deref for $name {
117    type Target = [u8];
118    
119    #[inline(always)]
120    fn deref(&self) -> &[u8] {
121        self.as_slice()
122    }
123}
124impl ops::DerefMut for $name {
125    #[inline(always)]
126    fn deref_mut(&mut self) -> &mut [u8] {
127        self.as_mut_slice()
128    }
129}
130impl fmt::Debug for $name {
131    #[inline]
132    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133        <[u8] as fmt::Debug>::fmt(&*self, f)
134    }
135}
136impl PartialEq<[u8]> for $name {
137    #[inline(always)]
138    fn eq(&self, rhs: &[u8]) -> bool {
139        self.as_slice() == rhs
140    }
141}
142impl PartialEq for $name {
143    fn eq(&self, rhs: &Self) -> bool {
144        self.as_slice().eq(rhs.as_slice())
145    }
146}
147impl Eq for $name {}
148impl core::hash::Hash for $name {
149    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
150        self.as_slice().hash(state);
151    }
152}
153impl cmp::PartialOrd for $name {
154    #[inline(always)]
155    fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> {
156        self.as_slice().partial_cmp(rhs.as_slice())
157    }
158    #[inline(always)]
159    fn lt(&self, rhs: &Self) -> bool {
160        self.as_slice().lt(rhs.as_slice())
161    }
162    #[inline(always)]
163    fn le(&self, rhs: &Self) -> bool {
164        self.as_slice().le(rhs.as_slice())
165    }
166    #[inline(always)]
167    fn gt(&self, rhs: &Self) -> bool {
168        self.as_slice().gt(rhs.as_slice())
169    }
170    #[inline(always)]
171    fn ge(&self, rhs: &Self) -> bool {
172        self.as_slice().ge(rhs.as_slice())
173    }
174}
175impl cmp::Ord for $name {
176    #[inline(always)]
177    fn cmp(&self, other: &$name) -> cmp::Ordering {
178        self.as_slice().cmp(other.as_slice())
179    }
180}
181impl ops::Index<ops::Range<usize>> for $name {
182    type Output = [u8];
183
184    #[inline]
185    fn index(&self, index: ops::Range<usize>) -> &[u8] {
186        &self[..][index]
187    }
188}
189impl ops::Index<ops::RangeTo<usize>> for $name {
190    type Output = [u8];
191
192    #[inline]
193    fn index(&self, index: ops::RangeTo<usize>) -> &[u8] {
194        &self[..][index]
195    }
196}
197impl ops::Index<ops::RangeFrom<usize>> for $name {
198    type Output = [u8];
199
200    #[inline]
201    fn index(&self, index: ops::RangeFrom<usize>) -> &[u8] {
202        &self[..][index]
203    }
204}
205impl ops::Index<ops::RangeFull> for $name {
206    type Output = [u8];
207
208    #[inline]
209    fn index(&self, _index: ops::RangeFull) -> &[u8] {
210        self.as_slice()
211    }
212}
213impl ops::Index<ops::RangeInclusive<usize>> for $name {
214    type Output = [u8];
215
216    #[inline]
217    fn index(&self, index: ops::RangeInclusive<usize>) -> &[u8] {
218        Index::index(&**self, index)
219    }
220}
221impl ops::Index<ops::RangeToInclusive<usize>> for $name {
222    type Output = [u8];
223
224    #[inline]
225    fn index(&self, index: ops::RangeToInclusive<usize>) -> &[u8] {
226        Index::index(&**self, index)
227    }
228}
229
230impl Borrow<[u8]> for $name {
231    fn borrow(&self) -> &[u8] {
232        self.as_slice()
233    }
234}
235    }
236}
237
238macro_rules! define_common_string {
239    ($name:ident, $union:ident) => {
240impl $name {
241    #[inline(always)]
242    pub fn as_str(&self) -> &str {
243        unsafe {
244            str::from_utf8_unchecked(self.bytes.as_slice())
245        }
246    }
247    
248    #[inline(always)]
249    pub fn as_mut_str(&mut self) -> &mut str {
250        unsafe {
251            str::from_utf8_unchecked_mut(self.bytes.as_mut_slice())
252        }
253    }
254    
255    
256}
257impl $name {
258    #[inline(always)]
259    pub fn into_bytes(self) -> Vec<u8> {
260        let s: String = self.into();
261        s.into_bytes()
262    }
263}
264
265impl<'a> Into<String> for &'a $name {
266    #[inline(always)]
267    fn into(self) -> String {
268        String::from(self.as_str())
269    }
270}
271impl ops::Deref for $name {
272    type Target = str;
273    
274    #[inline(always)]
275    fn deref(&self) -> &str {
276        self.as_str()
277    }
278}
279
280#[cfg(feature="std")]
281impl AsRef<str> for $name {
282    #[inline]
283    fn as_ref(&self) -> &str {
284        self.as_str()
285    }
286}
287#[cfg(feature="std")]
288impl AsRef<[u8]> for $name {
289    #[inline]
290    fn as_ref(&self) -> &[u8] {
291        self.as_bytes()
292    }
293}
294impl fmt::Debug for $name {
295    #[inline]
296    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
297        <str as fmt::Debug>::fmt(&*self, f)
298    }
299}
300impl fmt::Display for $name {
301    #[inline]
302    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
303        <str as fmt::Display>::fmt(&*self, f)
304    }
305}
306
307impl PartialEq<str> for $name {
308    #[inline(always)]
309    fn eq(&self, rhs: &str) -> bool {
310        self.as_str() == rhs
311    }
312}
313impl<'a> PartialEq<&'a str> for $name {
314    #[inline(always)]
315    fn eq(&self, rhs: &&'a str) -> bool {
316        self.as_str() == *rhs
317    }
318}
319impl PartialEq<String> for $name {
320    #[inline(always)]
321    fn eq(&self, rhs: &String) -> bool {
322        self.as_str() == rhs
323    }
324}
325impl PartialEq for $name {
326    fn eq(&self, rhs: &Self) -> bool {
327        self.as_str().eq(rhs.as_str())
328    }
329}
330impl Eq for $name {}
331impl core::hash::Hash for $name {
332    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
333        self.as_str().hash(state);
334    }
335}
336impl core::cmp::PartialOrd for $name {
337    #[inline(always)]
338    fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
339        self.as_str().partial_cmp(rhs.as_str())
340    }
341    #[inline(always)]
342    fn lt(&self, rhs: &Self) -> bool {
343        self.as_str().lt(rhs.as_str())
344    }
345    #[inline(always)]
346    fn le(&self, rhs: &Self) -> bool {
347        self.as_str().le(rhs.as_str())
348    }
349    #[inline(always)]
350    fn gt(&self, rhs: &Self) -> bool {
351        self.as_str().gt(rhs.as_str())
352    }
353    #[inline(always)]
354    fn ge(&self, rhs: &Self) -> bool {
355        self.as_str().ge(rhs.as_str())
356    }
357}
358impl core::cmp::Ord for $name {
359    #[inline(always)]
360    fn cmp(&self, other: &$name) -> core::cmp::Ordering {
361        self.as_str().cmp(other.as_str())
362    }
363}
364impl ops::Index<ops::Range<usize>> for $name {
365    type Output = str;
366
367    #[inline]
368    fn index(&self, index: ops::Range<usize>) -> &str {
369        &self[..][index]
370    }
371}
372impl ops::Index<ops::RangeTo<usize>> for $name {
373    type Output = str;
374
375    #[inline]
376    fn index(&self, index: ops::RangeTo<usize>) -> &str {
377        &self[..][index]
378    }
379}
380impl ops::Index<ops::RangeFrom<usize>> for $name {
381    type Output = str;
382
383    #[inline]
384    fn index(&self, index: ops::RangeFrom<usize>) -> &str {
385        &self[..][index]
386    }
387}
388impl ops::Index<ops::RangeFull> for $name {
389    type Output = str;
390
391    #[inline]
392    fn index(&self, _index: ops::RangeFull) -> &str {
393        self.as_str()
394    }
395}
396impl ops::Index<ops::RangeInclusive<usize>> for $name {
397    type Output = str;
398
399    #[inline]
400    fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
401        Index::index(&**self, index)
402    }
403}
404impl ops::Index<ops::RangeToInclusive<usize>> for $name {
405    type Output = str;
406
407    #[inline]
408    fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
409        Index::index(&**self, index)
410    }
411}
412
413impl Borrow<str> for $name {
414    fn borrow(&self) -> &str {
415        self.as_str()
416    }
417}
418
419    }
420}