smartstring/
inline.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use crate::{config::MAX_INLINE, marker_byte::Marker, ops::GenericString};
6use core::{
7    ops::{Deref, DerefMut},
8    str::{from_utf8_unchecked, from_utf8_unchecked_mut},
9};
10
11#[cfg(target_endian = "little")]
12#[repr(C)]
13#[cfg_attr(target_pointer_width = "64", repr(align(8)))]
14#[cfg_attr(target_pointer_width = "32", repr(align(4)))]
15pub(crate) struct InlineString {
16    pub(crate) marker: Marker,
17    pub(crate) data: [u8; MAX_INLINE],
18}
19
20#[cfg(target_endian = "big")]
21#[repr(C)]
22#[cfg_attr(target_pointer_width = "64", repr(align(8)))]
23#[cfg_attr(target_pointer_width = "32", repr(align(4)))]
24pub(crate) struct InlineString {
25    pub(crate) data: [u8; MAX_INLINE],
26    pub(crate) marker: Marker,
27}
28
29impl Clone for InlineString {
30    fn clone(&self) -> Self {
31        unreachable!("InlineString should be copy!")
32    }
33}
34
35impl Copy for InlineString {}
36
37impl Deref for InlineString {
38    type Target = str;
39
40    fn deref(&self) -> &Self::Target {
41        #[allow(unsafe_code)]
42        unsafe {
43            from_utf8_unchecked(&self.data[..self.len()])
44        }
45    }
46}
47
48impl DerefMut for InlineString {
49    fn deref_mut(&mut self) -> &mut Self::Target {
50        let len = self.len();
51        #[allow(unsafe_code)]
52        unsafe {
53            from_utf8_unchecked_mut(&mut self.data[..len])
54        }
55    }
56}
57
58impl GenericString for InlineString {
59    fn set_size(&mut self, size: usize) {
60        self.marker.set_data(size as u8);
61    }
62
63    fn as_mut_capacity_slice(&mut self) -> &mut [u8] {
64        self.data.as_mut()
65    }
66}
67
68impl InlineString {
69    pub(crate) const fn new() -> Self {
70        Self {
71            marker: Marker::empty(),
72            data: [0; MAX_INLINE],
73        }
74    }
75
76    pub(crate) fn len(&self) -> usize {
77        let len = self.marker.data() as usize;
78        debug_assert!(len <= MAX_INLINE);
79        len
80    }
81}
82
83impl From<&str> for InlineString {
84    fn from(string: &str) -> Self {
85        let len = string.len();
86        debug_assert!(len <= MAX_INLINE);
87        let mut out = Self::new();
88        out.marker = Marker::new_inline(len as u8);
89        out.data.as_mut()[..len].copy_from_slice(string.as_bytes());
90        out
91    }
92}