mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-26 11:55:04 +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"
|
superslice = "0.1.0"
|
||||||
|
|
||||||
libsyntax2 = { path = "../libsyntax2" }
|
libsyntax2 = { path = "../libsyntax2" }
|
||||||
smol_str = { path = "../smol_str" }
|
smol_str = "0.1.0"
|
||||||
assert_eq_text = { path = "../assert_eq_text" }
|
assert_eq_text = { path = "../assert_eq_text" }
|
||||||
|
|
|
@ -10,7 +10,7 @@ text_unit = "0.1.2"
|
||||||
itertools = "0.7.5"
|
itertools = "0.7.5"
|
||||||
drop_bomb = "0.1.4"
|
drop_bomb = "0.1.4"
|
||||||
parking_lot = "0.6.0"
|
parking_lot = "0.6.0"
|
||||||
smol_str = { path = "../smol_str" }
|
smol_str = "0.1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_eq_text = { path = "../assert_eq_text" }
|
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