mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 21:28:51 +00:00
move smol_str to a separare repo
This commit is contained in:
parent
e0a43a159d
commit
6a3f819f79
4 changed files with 2 additions and 176 deletions
|
@ -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" }
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
[package]
|
||||
name = "smol_str"
|
||||
version = "0.1.0"
|
||||
authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
|
||||
|
||||
[dependencies]
|
|
@ -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<str> for SmolStr {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
self.as_str() == other
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<SmolStr> 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<SmolStr> for &'a str {
|
||||
fn eq(&self, other: &SmolStr) -> bool {
|
||||
*self == other
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<String> for SmolStr {
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
self.as_str() == other
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<SmolStr> 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<SmolStr> 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<str>),
|
||||
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::<SmolStr>(), 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue