rustbasic_core/support/
str.rs1use crate::uuid::Uuid;
2use rand::distr::{Alphanumeric, SampleString};
3
4pub struct Stringable(String);
5
6impl Stringable {
7 pub fn new(val: String) -> Self {
8 Self(val)
9 }
10
11 pub fn upper(mut self) -> Self {
13 self.0 = self.0.to_uppercase();
14 self
15 }
16
17 pub fn lower(mut self) -> Self {
19 self.0 = self.0.to_lowercase();
20 self
21 }
22
23 pub fn append(mut self, val: &str) -> Self {
25 self.0.push_str(val);
26 self
27 }
28
29 pub fn prepend(mut self, val: &str) -> Self {
31 self.0.insert_str(0, val);
32 self
33 }
34
35 pub fn slug(mut self) -> Self {
37 self.0 = Str::slug(&self.0);
38 self
39 }
40
41 pub fn after(mut self, search: &str) -> Self {
43 self.0 = Str::after(&self.0, search);
44 self
45 }
46
47 pub fn before(mut self, search: &str) -> Self {
49 self.0 = Str::before(&self.0, search);
50 self
51 }
52
53 pub fn between(mut self, from: &str, to: &str) -> Self {
55 self.0 = Str::between(&self.0, from, to);
56 self
57 }
58
59 pub fn limit(mut self, max: usize, end: &str) -> Self {
61 self.0 = Str::limit(&self.0, max, end);
62 self
63 }
64
65 pub fn replace(mut self, search: &str, replace: &str) -> Self {
67 self.0 = Str::replace(search, replace, &self.0);
68 self
69 }
70
71 pub fn get(self) -> String {
73 self.0
74 }
75}
76
77pub struct Str;
78
79impl Str {
80 pub fn of(value: &str) -> Stringable {
82 Stringable::new(value.to_string())
83 }
84
85 pub fn uuid() -> String {
87 Uuid::new_v4().to_string()
88 }
89
90 pub fn random(length: usize) -> String {
92 Alphanumeric.sample_string(&mut rand::rng(), length)
93 }
94
95 pub fn slug(title: &str) -> String {
97 title
98 .to_lowercase()
99 .chars()
100 .map(|c| if c.is_alphanumeric() { c } else { '-' })
101 .collect::<String>()
102 .split('-')
103 .filter(|s| !s.is_empty())
104 .collect::<Vec<_>>()
105 .join("-")
106 }
107
108 pub fn after(subject: &str, search: &str) -> String {
110 subject.split_once(search).map(|(_, right)| right).unwrap_or(subject).to_string()
111 }
112
113 pub fn before(subject: &str, search: &str) -> String {
115 subject.split_once(search).map(|(left, _)| left).unwrap_or(subject).to_string()
116 }
117
118 pub fn between(subject: &str, from: &str, to: &str) -> String {
120 subject.split(from).nth(1).and_then(|s| s.split(to).next()).unwrap_or("").to_string()
121 }
122
123 pub fn contains(haystack: &str, needle: &str) -> bool {
125 haystack.contains(needle)
126 }
127
128 pub fn starts_with(subject: &str, needle: &str) -> bool {
130 subject.starts_with(needle)
131 }
132
133 pub fn ends_with(subject: &str, needle: &str) -> bool {
135 subject.ends_with(needle)
136 }
137
138 pub fn is_uuid(value: &str) -> bool {
140 Uuid::parse_str(value).is_ok()
141 }
142
143 pub fn lower(value: &str) -> String {
145 value.to_lowercase()
146 }
147
148 pub fn upper(value: &str) -> String {
150 value.to_uppercase()
151 }
152
153 pub fn limit(value: &str, max: usize, end: &str) -> String {
155 if value.chars().count() <= max {
156 value.to_string()
157 } else {
158 format!("{}{}", value.chars().take(max).collect::<String>(), end)
159 }
160 }
161
162 pub fn replace(search: &str, replace: &str, subject: &str) -> String {
164 subject.replace(search, replace)
165 }
166}