cesu8str/ngstr/
mutf8str.rs

1
2use super::prelude::*;
3
4/// A borrowed MUTF-8 string.
5#[derive(PartialEq, Eq, PartialOrd, Ord)]
6#[repr(transparent)]
7pub struct Mutf8Str {
8    inner: [u8],
9}
10
11impl Mutf8Str {
12    impl_str_encoding_meths!(base, Mutf8Str, any, "MUTF-8");
13    impl_str_encoding_meths!(str, Mutf8Str, any, "MUTF-8");
14}
15
16impl Mutf8Str {
17    /// Determines if this string encoding uses literal nul bytes. If true, then literal nul bytes are not allowed
18    /// within the string's contents.
19    pub const ENCODE_NUL: bool = true;
20    /// Determines if this string maintains a literal nul byte as a terminator. This makes it functionally equilavent
21    /// to a [`CStr`], including any encoding guarantees provided by the string type.
22    /// 
23    /// If this is `true`, then [`Self::ENCODE_NUL`] must also be `true`.
24    pub const NUL_TERM: bool = false;
25
26    /// Uses pointer magic to transmute a byte slice to an instance of Mutf8Str
27    /// 
28    /// # Safety
29    /// The byte string should be encoded in MUTF8. That is, UTF8 with 4-byte-sequences re-encoded as 2, 3-byte
30    /// sequences, and with nul bytes re-encoded as as [0xC0, 0x80]
31    pub(crate) const unsafe fn _from_bytes_unchecked(bytes: &[u8]) -> &Self {
32        // &[u8]
33        // *const [u8]
34        // *const Mutf8Str
35        // &Mutf8Str
36
37        // should be a no-op
38
39        &*(bytes as *const [u8] as *const Self)
40    }
41    
42    pub(crate) const fn _raw_bytes(&self) -> &[u8] {
43        unsafe { &*(self as *const Self as *const [u8]) }
44    }
45}
46
47// don't impl Deref as it can make nul-terminator inclusion ambiguous for Mutf8CStr -> Mutf8Str -> [u8]
48impl ToOwned for Mutf8Str {
49    type Owned = Mutf8String;
50    fn to_owned(&self) -> Self::Owned {
51        // SAFETY: string has already been validated as mutf8
52        unsafe { Self::Owned::from_bytes_unchecked(self.inner.to_vec()) }
53    }
54}
55impl Default for &Mutf8Str {
56    fn default() -> Self {
57        const EMPTY: &[u8] = &[];
58        unsafe { Mutf8Str::from_bytes_unchecked(EMPTY) }
59    }
60}
61