1use std::{fmt::{self, write}, ops::{Index, IndexMut}, rc::Rc, slice::SliceIndex, str::Chars};
2
3#[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}