diff options
author | Aleksey Kladov <[email protected]> | 2018-08-08 18:25:35 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-08 18:25:35 +0100 |
commit | 1fa5b2ffbc0f1dd3cfc45adff0329e1bdd46c131 (patch) | |
tree | 5ebfc103a7d5c69705fdfc1166dbf60e61a9e441 /src | |
parent | cc4c90aa2cf4da819dd324a7bbf8b36f6a068a6d (diff) |
smol strings
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/smol_str.rs | 60 | ||||
-rw-r--r-- | src/yellow/green.rs | 7 |
3 files changed, 65 insertions, 3 deletions
diff --git a/src/lib.rs b/src/lib.rs index 0ae8082f1..91b0c9c55 100644 --- a/src/lib.rs +++ b/src/lib.rs | |||
@@ -35,6 +35,7 @@ mod grammar; | |||
35 | mod parser_impl; | 35 | mod parser_impl; |
36 | 36 | ||
37 | mod syntax_kinds; | 37 | mod syntax_kinds; |
38 | mod smol_str; | ||
38 | mod yellow; | 39 | mod yellow; |
39 | /// Utilities for simple uses of the parser. | 40 | /// Utilities for simple uses of the parser. |
40 | pub mod utils; | 41 | pub mod utils; |
diff --git a/src/smol_str.rs b/src/smol_str.rs new file mode 100644 index 000000000..2a330c343 --- /dev/null +++ b/src/smol_str.rs | |||
@@ -0,0 +1,60 @@ | |||
1 | use std::{sync::Arc}; | ||
2 | |||
3 | const INLINE_CAP: usize = 22; | ||
4 | |||
5 | #[derive(Clone, Debug)] | ||
6 | pub(crate) enum SmolStr { | ||
7 | Heap(Arc<str>), | ||
8 | Inline { | ||
9 | len: u8, | ||
10 | buf: [u8; INLINE_CAP], | ||
11 | }, | ||
12 | } | ||
13 | |||
14 | impl SmolStr { | ||
15 | pub fn new(text: &str) -> SmolStr { | ||
16 | let len = text.len(); | ||
17 | if len <= INLINE_CAP { | ||
18 | let mut buf = [0; INLINE_CAP]; | ||
19 | buf[..len].copy_from_slice(text.as_bytes()); | ||
20 | SmolStr::Inline { len: len as u8, buf } | ||
21 | } else { | ||
22 | SmolStr::Heap( | ||
23 | text.to_string().into_boxed_str().into() | ||
24 | ) | ||
25 | } | ||
26 | } | ||
27 | |||
28 | pub fn as_str(&self) -> &str { | ||
29 | match self { | ||
30 | SmolStr::Heap(data) => &*data, | ||
31 | SmolStr::Inline { len, buf } => { | ||
32 | let len = *len as usize; | ||
33 | let buf = &buf[..len]; | ||
34 | unsafe { ::std::str::from_utf8_unchecked(buf) } | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | } | ||
39 | |||
40 | #[cfg(test)] | ||
41 | mod tests { | ||
42 | use super::*; | ||
43 | |||
44 | #[test] | ||
45 | #[cfg(target_pointer_width = "64")] | ||
46 | fn smol_str_is_smol() { | ||
47 | assert_eq!(::std::mem::size_of::<SmolStr>(), 8 + 8 + 8) | ||
48 | } | ||
49 | |||
50 | #[test] | ||
51 | fn test_round_trip() { | ||
52 | let mut text = String::new(); | ||
53 | for n in 0..256 { | ||
54 | let smol = SmolStr::new(&text); | ||
55 | assert_eq!(smol.as_str(), text.as_str()); | ||
56 | text.push_str(&n.to_string()); | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
diff --git a/src/yellow/green.rs b/src/yellow/green.rs index 3ade46f45..26df76af6 100644 --- a/src/yellow/green.rs +++ b/src/yellow/green.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | use { | 2 | use { |
3 | smol_str::SmolStr, | ||
3 | SyntaxKind::{self, *}, | 4 | SyntaxKind::{self, *}, |
4 | TextUnit, | 5 | TextUnit, |
5 | }; | 6 | }; |
@@ -116,7 +117,7 @@ pub(crate) enum GreenLeaf { | |||
116 | }, | 117 | }, |
117 | Token { | 118 | Token { |
118 | kind: SyntaxKind, | 119 | kind: SyntaxKind, |
119 | text: Option<Arc<str>>, | 120 | text: Option<SmolStr>, |
120 | }, | 121 | }, |
121 | } | 122 | } |
122 | 123 | ||
@@ -137,7 +138,7 @@ impl GreenLeaf { | |||
137 | debug_assert_eq!(t, text); | 138 | debug_assert_eq!(t, text); |
138 | None | 139 | None |
139 | } | 140 | } |
140 | None => Some(text.to_owned().into_boxed_str().into()), | 141 | None => Some(SmolStr::new(text)), |
141 | }; | 142 | }; |
142 | GreenLeaf::Token { kind, text } | 143 | GreenLeaf::Token { kind, text } |
143 | } | 144 | } |
@@ -159,7 +160,7 @@ impl GreenLeaf { | |||
159 | } | 160 | } |
160 | GreenLeaf::Token { kind, text } => match text { | 161 | GreenLeaf::Token { kind, text } => match text { |
161 | None => kind.static_text().unwrap(), | 162 | None => kind.static_text().unwrap(), |
162 | Some(t) => t, | 163 | Some(t) => t.as_str(), |
163 | }, | 164 | }, |
164 | } | 165 | } |
165 | } | 166 | } |