cheap_string/
lib.rs

1use std::{fmt::{self, write}, ops::{Index, IndexMut}, rc::Rc, slice::SliceIndex, str::Chars};
2
3/// Stores an Rc<str> which allows for the standard stack
4/// strings to be stored on heap, it also allows shallow
5/// cloning which just bumps the ref counter up, which is where
6/// the name cheap string comes from.
7/// # Example
8/// ```
9/// use cheap_string::CheapString;
10/// 
11/// let str = CheapString::from("Hello, world!");
12/// println!("{}", str);
13/// ```
14#[derive(Debug, Eq, PartialOrd, Ord)]
15pub struct CheapString {
16    inner: Rc<str>,
17}
18
19impl CheapString {
20    #[inline]
21    pub fn from(str: &str) -> Self {
22        Self { inner: Rc::from(str) }
23    }
24    
25    #[inline]
26    #[must_use]
27    pub fn chars(&self) -> Chars { self.inner.chars() }
28    
29    #[inline]
30    #[must_use]
31    pub fn len(&self) -> usize { self.inner.len() }
32    
33    #[inline]
34    #[must_use]
35    pub fn as_str(&self) -> &str { &self.inner }
36}
37
38impl Clone for CheapString {
39    #[inline]
40    fn clone(&self) -> Self {
41        Self { inner: self.inner.clone() }
42    }
43}
44
45impl PartialEq<&str> for CheapString {
46    fn eq(&self, other: &&str) -> bool {
47        self.inner.as_ref() == *other
48    }
49}
50
51impl PartialEq<String> for CheapString {
52    fn eq(&self, other: &String) -> bool {
53        self.inner.as_ref() == other
54    }
55}
56
57impl PartialEq<CheapString> for CheapString {
58    fn eq(&self, other: &CheapString) -> bool {
59        self == other
60    }
61}
62
63impl<I> Index<I> for CheapString
64where
65    I: SliceIndex<str>,
66{
67    type Output = I::Output;
68
69    #[inline]
70    fn index(&self, index: I) -> &I::Output {
71        self.as_str().get(index).unwrap()
72    }
73}
74
75impl fmt::Display for CheapString {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        write!(f, "{}", self.inner.as_ref())
78    }
79}
80
81pub trait AsCheapString {
82    fn as_cheap_string(&self) -> CheapString;
83}
84
85impl AsCheapString for str {
86    fn as_cheap_string(&self) -> CheapString { CheapString::from(self) }
87}