datex_core/values/core_values/
text.rs1use crate::traits::structural_eq::StructuralEq;
2use serde::{Deserialize, Serialize};
3use std::{
4 fmt::Display,
5 ops::{Add, AddAssign},
6};
7
8use super::super::core_value_trait::CoreValueTrait;
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
11pub struct Text(pub String);
12
13impl Display for Text {
14 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
16 write!(f, "\"{}\"", self.0)
17 }
18}
19
20impl Text {
21 pub fn length(&self) -> usize {
22 self.0.len()
23 }
24 pub fn to_uppercase(&self) -> Text {
25 Text(self.0.to_uppercase())
26 }
27 pub fn to_lowercase(&self) -> Text {
28 Text(self.0.to_lowercase())
29 }
30 pub fn as_str(&self) -> &str {
31 &self.0
32 }
33 pub fn as_string(&self) -> String {
34 self.0.clone()
35 }
36 pub fn char_at(&self, index: usize) -> Option<char> {
37 self.0.chars().nth(index)
38 }
39 pub fn substring(&self, start: usize, end: usize) -> Option<Text> {
40 if start > end || end > self.0.len() {
41 return None;
42 }
43 Some(Text(self.0[start..end].to_string()))
44 }
45 pub fn contains(&self, substring: &str) -> bool {
46 self.0.contains(substring)
47 }
48 pub fn starts_with(&self, prefix: &str) -> bool {
49 self.0.starts_with(prefix)
50 }
51 pub fn ends_with(&self, suffix: &str) -> bool {
52 self.0.ends_with(suffix)
53 }
54 pub fn index_of(&self, substring: &str) -> Option<usize> {
55 self.0.find(substring)
56 }
57 pub fn last_index_of(&self, substring: &str) -> Option<usize> {
58 self.0.rfind(substring)
59 }
60 pub fn is_empty(&self) -> bool {
61 self.0.is_empty()
62 }
63 pub fn trim(&self) -> Text {
64 Text(self.0.trim().to_string())
65 }
66 pub fn trim_start(&self) -> Text {
67 Text(self.0.trim_start().to_string())
68 }
69 pub fn split(&self, delimiter: &str) -> Vec<Text> {
70 self.0
71 .split(delimiter)
72 .map(|s| Text(s.to_string()))
73 .collect()
74 }
75 pub fn join(texts: &[Text], separator: &str) -> Text {
76 let joined = texts
77 .iter()
78 .map(|t| t.0.as_str())
79 .collect::<Vec<&str>>()
80 .join(separator);
81 Text(joined)
82 }
83 pub fn repeat(&self, n: usize) -> Text {
84 Text(self.0.repeat(n))
85 }
86}
87
88impl Text {
90 pub fn clear(&mut self) {
91 self.0.clear();
92 }
93 pub fn reverse(&mut self) {
94 let reversed = self.0.chars().rev().collect::<String>();
95 self.0 = reversed;
96 }
97 pub fn push_str(&mut self, s: &str) {
98 self.0.push_str(s);
99 }
100 pub fn push_char(&mut self, c: char) {
101 self.0.push(c);
102 }
103 pub fn pop_char(&mut self) -> Option<char> {
104 self.0.pop()
105 }
106 pub fn insert(&mut self, index: usize, s: &str) -> Result<(), String> {
107 if index > self.0.len() {
108 return Err("Index out of bounds".to_string());
109 }
110 self.0.insert_str(index, s);
111 Ok(())
112 }
113 pub fn remove(&mut self, index: usize) -> Result<char, String> {
115 if index >= self.0.len() {
116 return Err("Index out of bounds".to_string());
117 }
118 Ok(self.0.remove(index))
119 }
120 pub fn replace(&mut self, from: &str, to: &str) {
121 self.0 = self.0.replace(from, to);
122 }
123 pub fn replace_range(
124 &mut self,
125 range: std::ops::Range<usize>,
126 replace_with: &str,
127 ) -> Result<(), String> {
128 if range.start > range.end || range.end > self.0.len() {
129 return Err("Range out of bounds".to_string());
130 }
131 self.0.replace_range(range, replace_with);
132 Ok(())
133 }
134 pub fn set_char_at(&mut self, index: usize, c: char) -> Result<(), String> {
135 let mut chars: Vec<char> = self.0.chars().collect();
136 if index >= chars.len() {
137 return Err("Index out of bounds".to_string());
138 }
139 chars[index] = c;
140 self.0 = chars.iter().collect();
141 Ok(())
142 }
143}
144
145impl CoreValueTrait for Text {}
146
147impl StructuralEq for Text {
148 fn structural_eq(&self, other: &Self) -> bool {
149 self.0 == other.0
150 }
151}
152
153impl From<&str> for Text {
156 fn from(s: &str) -> Self {
157 Text(s.to_string())
158 }
159}
160
161impl From<String> for Text {
162 fn from(s: String) -> Self {
163 Text(s)
164 }
165}
166
167impl AddAssign<Text> for Text {
170 fn add_assign(&mut self, rhs: Text) {
171 self.0 += &rhs.0;
172 }
173}
174
175impl Add for Text {
176 type Output = Self;
177
178 fn add(self, rhs: Self) -> Self::Output {
179 Text(self.0 + &rhs.0)
180 }
181}
182
183impl Add for &Text {
184 type Output = Text;
185
186 fn add(self, rhs: Self) -> Self::Output {
187 Text(self.0.clone() + &rhs.0)
188 }
189}
190
191impl Add<Text> for &Text {
192 type Output = Text;
193
194 fn add(self, rhs: Text) -> Self::Output {
195 Text(self.0.clone() + &rhs.0)
196 }
197}
198
199impl Add<&Text> for Text {
200 type Output = Text;
201
202 fn add(self, rhs: &Text) -> Self::Output {
203 Text(self.0 + &rhs.0)
204 }
205}
206
207impl Add<&str> for Text {
208 type Output = Text;
209
210 fn add(self, rhs: &str) -> Self::Output {
211 Text(self.0 + rhs)
212 }
213}