enhanced_magic_string/utils/
char_string.rs

1use std::fmt::{Debug, Display};
2
3#[derive(Clone, PartialEq, Eq)]
4pub struct CharString {
5  chars: Vec<char>,
6}
7
8impl CharString {
9  pub fn new(str: &str) -> Self {
10    Self {
11      chars: str.chars().collect(),
12    }
13  }
14
15  pub fn get(&self, index: usize) -> Option<&char> {
16    self.chars.get(index)
17  }
18
19  pub fn get_mut(&mut self, index: usize) -> Option<&mut char> {
20    self.chars.get_mut(index)
21  }
22
23  pub fn slice(&self, start: usize, end: usize) -> Self {
24    Self {
25      chars: self.chars[start..end].to_vec(),
26    }
27  }
28
29  pub fn split(&self, separator: char) -> Vec<Self> {
30    let mut result = vec![];
31    let mut start = 0;
32
33    for (index, char) in self.chars.iter().enumerate() {
34      if *char == separator {
35        result.push(self.slice(start, index));
36        start = index + 1;
37      }
38    }
39
40    result.push(self.slice(start, self.len()));
41
42    result
43  }
44
45  pub fn len(&self) -> usize {
46    self.chars.len()
47  }
48
49  pub fn is_empty(&self) -> bool {
50    self.chars.is_empty()
51  }
52
53  pub fn insert(&mut self, index: usize, char: char) {
54    self.chars.insert(index, char);
55  }
56
57  pub fn remove(&mut self, index: usize) -> Option<char> {
58    if index >= self.chars.len() {
59      return None;
60    }
61
62    Some(self.chars.remove(index))
63  }
64
65  pub fn append_str(&mut self, other: &str) {
66    self.chars.extend(other.chars());
67  }
68
69  pub fn append(&mut self, other: &CharString) {
70    self.chars.extend(other.chars.iter());
71  }
72}
73
74impl From<&str> for CharString {
75  fn from(str: &str) -> Self {
76    Self::new(str)
77  }
78}
79
80impl From<String> for CharString {
81  fn from(str: String) -> Self {
82    Self::new(&str)
83  }
84}
85
86impl From<&String> for CharString {
87  fn from(str: &String) -> Self {
88    Self::new(str)
89  }
90}
91
92impl From<char> for CharString {
93  fn from(char: char) -> Self {
94    Self { chars: vec![char] }
95  }
96}
97
98impl Display for CharString {
99  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100    write!(f, "{}", self.chars.iter().collect::<String>())
101  }
102}
103
104impl Debug for CharString {
105  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106    write!(f, "{:?}", self.chars.iter().collect::<String>())
107  }
108}
109
110#[cfg(test)]
111mod tests {
112  use super::*;
113
114  #[test]
115  fn test_char_string() {
116    let str = CharString::new("hello world");
117    assert_eq!(str.len(), 11);
118    assert_eq!(str.get(0), Some(&'h'));
119    assert_eq!(str.get(1), Some(&'e'));
120    assert_eq!(str.get(2), Some(&'l'));
121    assert_eq!(str.get(3), Some(&'l'));
122    assert_eq!(str.get(4), Some(&'o'));
123    assert_eq!(str.get(5), Some(&' '));
124    assert_eq!(str.get(6), Some(&'w'));
125    assert_eq!(str.get(7), Some(&'o'));
126    assert_eq!(str.get(8), Some(&'r'));
127    assert_eq!(str.get(9), Some(&'l'));
128    assert_eq!(str.get(10), Some(&'d'));
129    assert_eq!(str.get(11), None);
130
131    let mut str = CharString::new("hello world");
132    str.insert(5, '!');
133    assert_eq!(str.to_string(), "hello! world");
134
135    let mut str = CharString::new("hello world");
136    str.remove(5);
137    assert_eq!(str.to_string(), "helloworld");
138
139    let str = CharString::new("hello world");
140    assert_eq!(str.slice(0, 5).to_string(), "hello");
141    assert_eq!(str.slice(6, 11).to_string(), "world");
142    assert_eq!(str.slice(0, 11).to_string(), "hello world");
143  }
144
145  #[test]
146  fn test_split() {
147    let str = CharString::new("hello world");
148    let result = str.split(' ');
149    assert_eq!(result.len(), 2);
150    assert_eq!(result[0].to_string(), "hello");
151    assert_eq!(result[1].to_string(), "world");
152
153    let str = CharString::new("hello world");
154    let result = str.split('o');
155    assert_eq!(result.len(), 3);
156    assert_eq!(result[0].to_string(), "hell");
157    assert_eq!(result[1].to_string(), " w");
158    assert_eq!(result[2].to_string(), "rld");
159
160    let str = CharString::new("\n");
161    let result = str.split('\n');
162    assert_eq!(result.len(), 2);
163    assert_eq!(result[0].to_string(), "");
164    assert_eq!(result[1].to_string(), "");
165  }
166}