1use crate::vec::*;
2use ::core::*;
3use ::core::cmp::*;
4use crate::hash::*;
5use core::fmt::{Arguments, Write};
6
7#[repr(C)]
8pub struct String {
9 data : Vec<u8>
10}
11
12impl String {
13 pub fn with_capacity(c: usize) -> Self {
14 Self { data: Vec::with_capacity(c) }
15 }
16
17 pub fn new() -> Self { Self { data: Vec::new() } }
18 pub fn from(s: &str) -> Self {
19 let mut st = Self::new();
20 for c in s.bytes() {
21 st.data.push(c);
22 }
23 st
24 }
25
26 pub fn as_str(&self) -> &str {
27 ::core::str::from_utf8(self.data.as_slice()).expect("Error getting string out")
28 }
29
30 pub fn push(&mut self, u: u8) {
31 self.data.push(u);
32 }
33
34 pub fn into_bytes(self) -> Vec<u8> { self.data }
35 pub fn as_bytes(&self) -> &[u8] { self.data.as_slice() }
36 pub fn as_bytes_mut(&mut self) -> &mut [u8] { self.data.as_mut_slice() }
37 pub fn as_mut_vec(&mut self) -> &mut Vec<u8> { &mut self.data }
38
39 pub fn push_str(&mut self, s: &str) {
40 for c in s.bytes() {
41 self.data.push(c);
42 }
43 }
44
45 pub fn len(&self) -> usize { self.data.len() }
46
47 pub fn split(&self, pattern: &str) -> Split {
48 let mut v = Vec::<String>::new();
49 let mut i = 0;
50 let ss = self.as_str();
51 let ss_len = ss.len();
52 let mut chars = ss.chars();
53 loop {
54 let mut st = String::new();
55 loop {
56 match chars.next() {
57 Some(c) if pattern.contains(c) => {
58 if st.as_str().len() > 0 {
59 v.push(st);
60 }
61 i += 1;
62 break
63 },
64 Some(c) => {
65 st.push(c as u8);
66 i += 1;
67 },
68 None => {
69 if st.as_str().len() > 0 {
70 v.push(st);
71 }
72 break
73 }
74 }
75 }
76 if i >= ss_len {
77 break
78 }
79 }
80 Split { v: v, idx: 0 }
81 }
82
83 pub fn lines(&self) -> Lines {
84 Lines(self.split("\n"))
85 }
86
87 pub fn from_raw_parts(ptr: *mut u8, len: usize, cap: usize) -> Self {
88 Self { data : Vec::from_raw_parts(ptr, len, cap) }
89 }
90}
91
92pub struct Split {
93 v: Vec<String>,
94 idx: usize,
95}
96
97impl Iterator for Split {
98 type Item = String;
99 fn next(&mut self) -> Option<Self::Item> {
100 if self.idx < self.v.len() {
101 self.idx += 1;
102 return Some(self.v[self.idx - 1].clone());
103 }
104 None
105 }
106}
107
108pub struct Lines(Split);
109impl Iterator for Lines {
110 type Item = String;
111 fn next(&mut self) -> Option<Self::Item> { self.0.next() }
112}
113
114pub trait Append<T> {
115 fn append(&mut self, other: T);
116}
117
118
119impl Append<&String> for String {
120 fn append(&mut self, s: &String) {
121 for c in s.as_str().bytes() {
122 self.data.push(c);
123 }
124 }
125}
126
127impl PartialEq<String> for String {
128 fn eq(&self, other: &Self) -> bool {
129 let ls = self.data.len();
130 let lo = other.data.len();
131 if ls != lo { return false }
132 for i in 0..self.data.len() {
133 if self.data[i] != other.data[i] { return false }
134 }
135 true
136 }
137}
138
139impl Eq for String {}
140
141impl PartialEq<&str> for String {
142 fn eq(&self, other: &&str) -> bool {
143 let ob = (*other).as_bytes();
144 let ls = self.data.len();
145 let lo = ob.len();
146 if ls != lo { return false }
147 for i in 0..self.data.len() {
148 if self.data[i] != ob[i] { return false }
149 }
150 true
151 }
152}
153
154impl Clone for String {
155 fn clone(&self) -> Self {
156 String::from(self.as_str())
157 }
158}
159
160impl fmt::Write for String {
161 #[inline]
162 fn write_str(&mut self, s: &str) -> fmt::Result {
163 self.push_str(s);
164 Ok(())
165 }
166
167 #[inline]
168 fn write_char(&mut self, c: char) -> fmt::Result {
169 self.push(c as u8);
170 Ok(())
171 }
172}
173
174impl fmt::Display for String {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 write!(f, "{}", self.as_str())
177 }
178}
179
180impl Hash for String {
181 fn hash(&self) -> usize {
182 self.as_bytes().hash()
183 }
184}
185
186pub fn format(args: Arguments<'_>) -> String {
187 let mut output = String::new();
188 output.write_fmt(args).expect("a formatting trait implementation returned an error");
189 output
190}
191
192#[macro_export]
193macro_rules! format {
194 ($fmt:expr, $($args:expr),+) => {
195 $crate::string::format(format_args!($fmt, $($args),+))
196 };
197}
198
199#[cfg(test)]
200mod tests {
201 use super::*;
202 #[test]
203 fn test_conversion() {
204 {
205 let u : u32 = 12345;
206 if String::from("12345") != format!("{}", u) {
207 panic!("fail {}", u);
208 }
209 }
210
211 {
212 let i : i32 = -12345;
213 if String::from("-12345") != format!("{}", i) {
214 panic!("fail {}", i);
215 }
216 }
217 }
218
219 #[test]
220 fn test_split() {
221 let s = String::from("v 0/1/2 4/5/6");
222 let ss1 : Vec<String> = s.split(" ").collect();
223
224 assert_eq!(ss1[0].as_str(), "v");
225 assert_eq!(ss1[1].as_str(), "0/1/2");
226 assert_eq!(ss1[2].as_str(), "4/5/6");
227
228 let v = [ ["0", "1", "2"], ["4", "5", "6"] ];
229 for i in 1..3 {
230 let ss2 : Vec<String> = ss1[i].split("/").collect();
231 for j in 0..3 {
232 assert_eq!(ss2[j].as_str(), v[i - 1][j]);
233 }
234 }
235 }
236
237 #[test]
238 fn test_lines() {
239 let s = String::from("hello world\nsomething is different\n\n");
240 let ss1 : Vec<String> = s.lines().collect();
241 assert_eq!(ss1.len(), 2);
242 assert_eq!(ss1[0].as_str(), "hello world");
243 assert_eq!(ss1[1].as_str(), "something is different");
244 }
245
246}