aboutsummaryrefslogtreecommitdiff
path: root/src/smol_str.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/smol_str.rs')
-rw-r--r--src/smol_str.rs83
1 files changed, 0 insertions, 83 deletions
diff --git a/src/smol_str.rs b/src/smol_str.rs
deleted file mode 100644
index abf69dce7..000000000
--- a/src/smol_str.rs
+++ /dev/null
@@ -1,83 +0,0 @@
1use std::{sync::Arc};
2
3const INLINE_CAP: usize = 22;
4const WS_TAG: u8 = (INLINE_CAP + 1) as u8;
5
6#[derive(Clone, Debug)]
7pub(crate) enum SmolStr {
8 Heap(Arc<str>),
9 Inline {
10 len: u8,
11 buf: [u8; INLINE_CAP],
12 },
13}
14
15impl SmolStr {
16 pub fn new(text: &str) -> SmolStr {
17 let len = text.len();
18 if len <= INLINE_CAP {
19 let mut buf = [0; INLINE_CAP];
20 buf[..len].copy_from_slice(text.as_bytes());
21 return SmolStr::Inline { len: len as u8, buf };
22 }
23
24 let newlines = text.bytes().take_while(|&b| b == b'\n').count();
25 let spaces = text[newlines..].bytes().take_while(|&b| b == b' ').count();
26 if newlines + spaces == len && newlines <= N_NEWLINES && spaces <= N_SPACES {
27 let mut buf = [0; INLINE_CAP];
28 buf[0] = newlines as u8;
29 buf[1] = spaces as u8;
30 return SmolStr::Inline { len: WS_TAG, buf };
31 }
32
33 SmolStr::Heap(
34 text.to_string().into_boxed_str().into()
35 )
36 }
37
38 pub fn as_str(&self) -> &str {
39 match self {
40 SmolStr::Heap(data) => &*data,
41 SmolStr::Inline { len, buf } => {
42 if *len == WS_TAG {
43 let newlines = buf[0] as usize;
44 let spaces = buf[1] as usize;
45 assert!(newlines <= N_NEWLINES && spaces <= N_SPACES);
46 return &WS[N_NEWLINES - newlines..N_NEWLINES + spaces]
47 }
48
49 let len = *len as usize;
50 let buf = &buf[..len];
51 unsafe { ::std::str::from_utf8_unchecked(buf) }
52 }
53 }
54 }
55}
56
57const N_NEWLINES: usize = 32;
58const N_SPACES: usize = 128;
59const WS: &str =
60 "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n ";
61
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 #[cfg(target_pointer_width = "64")]
69 fn smol_str_is_smol() {
70 assert_eq!(::std::mem::size_of::<SmolStr>(), 8 + 8 + 8)
71 }
72
73 #[test]
74 fn test_round_trip() {
75 let mut text = String::new();
76 for n in 0..256 {
77 let smol = SmolStr::new(&text);
78 assert_eq!(smol.as_str(), text.as_str());
79 text.push_str(&n.to_string());
80 }
81 }
82}
83