diff --git a/crates/libeditor/Cargo.toml b/crates/libeditor/Cargo.toml index 1d210f3c11..502f532a77 100644 --- a/crates/libeditor/Cargo.toml +++ b/crates/libeditor/Cargo.toml @@ -9,5 +9,5 @@ itertools = "0.7.8" superslice = "0.1.0" libsyntax2 = { path = "../libsyntax2" } -smol_str = { path = "../smol_str" } +smol_str = "0.1.0" assert_eq_text = { path = "../assert_eq_text" } diff --git a/crates/libsyntax2/Cargo.toml b/crates/libsyntax2/Cargo.toml index cfaa3bc9b5..78e9e18a2e 100644 --- a/crates/libsyntax2/Cargo.toml +++ b/crates/libsyntax2/Cargo.toml @@ -10,7 +10,7 @@ text_unit = "0.1.2" itertools = "0.7.5" drop_bomb = "0.1.4" parking_lot = "0.6.0" -smol_str = { path = "../smol_str" } +smol_str = "0.1.0" [dev-dependencies] assert_eq_text = { path = "../assert_eq_text" } diff --git a/crates/smol_str/Cargo.toml b/crates/smol_str/Cargo.toml deleted file mode 100644 index 83ca12f62f..0000000000 --- a/crates/smol_str/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "smol_str" -version = "0.1.0" -authors = ["Aleksey Kladov "] - -[dependencies] diff --git a/crates/smol_str/src/lib.rs b/crates/smol_str/src/lib.rs deleted file mode 100644 index 79b179ef46..0000000000 --- a/crates/smol_str/src/lib.rs +++ /dev/null @@ -1,168 +0,0 @@ -use std::{sync::Arc, ops::Deref, fmt}; - -#[derive(Clone)] -pub struct SmolStr(Repr); - -impl SmolStr { - pub fn new(text: &str) -> SmolStr { - SmolStr(Repr::new(text)) - } - - pub fn as_str(&self) -> &str { - self.0.as_str() - } - - pub fn to_string(&self) -> String { - self.as_str().to_string() - } -} - -impl Deref for SmolStr { - type Target = str; - - fn deref(&self) -> &str { - self.as_str() - } -} - -impl PartialEq for SmolStr { - fn eq(&self, other: &str) -> bool { - self.as_str() == other - } -} - -impl PartialEq for str { - fn eq(&self, other: &SmolStr) -> bool { - other == self - } -} - -impl<'a> PartialEq<&'a str> for SmolStr { - fn eq(&self, other: &&'a str) -> bool { - self == *other - } -} - -impl<'a> PartialEq for &'a str { - fn eq(&self, other: &SmolStr) -> bool { - *self == other - } -} - -impl PartialEq for SmolStr { - fn eq(&self, other: &String) -> bool { - self.as_str() == other - } -} - -impl PartialEq for String { - fn eq(&self, other: &SmolStr) -> bool { - other == self - } -} - -impl<'a> PartialEq<&'a String> for SmolStr { - fn eq(&self, other: &&'a String) -> bool { - self == *other - } -} - -impl<'a> PartialEq for &'a String { - fn eq(&self, other: &SmolStr) -> bool { - *self == other - } -} - -impl fmt::Debug for SmolStr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(self.as_str(), f) - } -} - -impl fmt::Display for SmolStr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self.as_str(), f) - } -} - -const INLINE_CAP: usize = 22; -const WS_TAG: u8 = (INLINE_CAP + 1) as u8; - -#[derive(Clone, Debug)] -enum Repr { - Heap(Arc), - Inline { - len: u8, - buf: [u8; INLINE_CAP], - }, -} - -impl Repr { - fn new(text: &str) -> Repr { - let len = text.len(); - if len <= INLINE_CAP { - let mut buf = [0; INLINE_CAP]; - buf[..len].copy_from_slice(text.as_bytes()); - return Repr::Inline { len: len as u8, buf }; - } - - let newlines = text.bytes().take_while(|&b| b == b'\n').count(); - let spaces = text[newlines..].bytes().take_while(|&b| b == b' ').count(); - if newlines + spaces == len && newlines <= N_NEWLINES && spaces <= N_SPACES { - let mut buf = [0; INLINE_CAP]; - buf[0] = newlines as u8; - buf[1] = spaces as u8; - return Repr::Inline { len: WS_TAG, buf }; - } - - Repr::Heap( - text.to_string().into_boxed_str().into() - ) - } - - fn as_str(&self) -> &str { - match self { - Repr::Heap(data) => &*data, - Repr::Inline { len, buf } => { - if *len == WS_TAG { - let newlines = buf[0] as usize; - let spaces = buf[1] as usize; - assert!(newlines <= N_NEWLINES && spaces <= N_SPACES); - return &WS[N_NEWLINES - newlines..N_NEWLINES + spaces]; - } - - let len = *len as usize; - let buf = &buf[..len]; - unsafe { ::std::str::from_utf8_unchecked(buf) } - } - } - } -} - -const N_NEWLINES: usize = 32; -const N_SPACES: usize = 128; -const WS: &str = - "\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 "; - - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - #[cfg(target_pointer_width = "64")] - fn smol_str_is_smol() { - assert_eq!(::std::mem::size_of::(), 8 + 8 + 8) - } - - #[test] - fn test_round_trip() { - let mut text = String::new(); - for n in 0..256 { - let smol = SmolStr::new(&text); - assert_eq!(smol.as_str(), text.as_str()); - text.push_str(&n.to_string()); - } - } -} -