compact_str/repr/
static_str.rs1use core::{
2 mem,
3 ptr,
4 slice,
5 str,
6};
7
8use super::{
9 Repr,
10 MAX_SIZE,
11 STATIC_STR_MASK,
12};
13
14pub(super) const DISCRIMINANT_SIZE: usize = MAX_SIZE - mem::size_of::<&'static str>();
15
16#[derive(Copy, Clone)]
19#[repr(C)]
20pub struct StaticStr {
21 ptr: ptr::NonNull<u8>,
22 len: usize,
23 #[allow(unused)]
24 discriminant: [u8; DISCRIMINANT_SIZE],
25}
26static_assertions::assert_eq_size!(StaticStr, Repr);
27static_assertions::assert_eq_align!(StaticStr, Repr);
28static_assertions::assert_eq_size!(&'static str, (*const u8, usize));
29
30impl StaticStr {
31 #[inline]
32 pub const fn new(text: &'static str) -> Self {
33 let mut discriminant = [0; DISCRIMINANT_SIZE];
34 discriminant[DISCRIMINANT_SIZE - 1] = STATIC_STR_MASK;
35
36 Self {
37 ptr: unsafe { ptr::NonNull::new_unchecked(text.as_ptr() as *mut _) },
40 len: text.len(),
41 discriminant,
42 }
43 }
44
45 #[rustversion::attr(since(1.64), const)]
46 pub(super) fn get_text(&self) -> &'static str {
47 unsafe { str::from_utf8_unchecked(slice::from_raw_parts(self.ptr.as_ptr(), self.len)) }
49 }
50
51 pub(super) unsafe fn set_len(&mut self, len: usize) {
55 *self = Self::new(&self.get_text()[..len]);
56 }
57}