mod text_position;
pub use text_position::*;
pub const trait StringExtensions {
fn is_number(&self) -> bool;
fn rjust(&self, length: usize, fillchar: Option<char>) -> String;
fn ljust(&self, length: usize, fillchar: Option<char>) -> String;
fn center(&self, length: usize, fillchar: Option<char>) -> String;
fn expand_tabs(&self) -> String;
fn replace_first_occurrence(
&self,
target: &str,
replacement: &str,
) -> String;
fn replace_nth_occurrence(
&self,
target: &str,
replacement: &str,
n: usize,
) -> String;
fn reversed(&self) -> String;
fn length(&self) -> usize;
fn split_file_name(&self) -> Option<(&str, &str)>;
}
impl StringExtensions for str {
fn length(&self) -> usize {
self.chars().count()
}
fn is_number(&self) -> bool {
self.chars().all(char::is_numeric)
}
fn rjust(&self, length: usize, fillchar: Option<char>) -> String {
let pad = length.saturating_sub(self.len());
let fill = fillchar.unwrap_or(' ');
format!("{}{}", fill.to_string().repeat(pad), self)
}
fn ljust(&self, length: usize, fillchar: Option<char>) -> String {
let pad = length.saturating_sub(self.len());
let fill = fillchar.unwrap_or(' ');
format!("{}{}", self, fill.to_string().repeat(pad))
}
fn center(&self, length: usize, fillchar: Option<char>) -> String {
let pad = length.saturating_sub(self.len());
let left_pad = pad / 2;
let right_pad = pad - left_pad;
let fill = fillchar.unwrap_or(' ');
format!(
"{}{}{}",
fill.to_string().repeat(left_pad),
self,
fill.to_string().repeat(right_pad)
)
}
fn expand_tabs(&self) -> String {
self.replace('\t', " ")
}
fn replace_nth_occurrence(
&self,
target: &str,
replacement: &str,
n: usize,
) -> String {
let mut start = 0;
for _ in 0..n {
if let Some(pos) = self[start..].find(target) {
start += pos + target.len();
} else {
return self.to_string(); }
}
let mut text = self.to_string();
if let Some(pos) = self[start..].find(target) {
let idx = start + pos;
text.replace_range(idx..idx + target.len(), replacement);
}
text
}
fn replace_first_occurrence(
&self,
target: &str,
replacement: &str,
) -> String {
let mut result = self.to_string();
if let Some(pos) = result.find(target) {
result.replace_range(pos..pos + target.len(), replacement);
}
result
}
fn reversed(&self) -> String {
self.chars().rev().collect::<String>()
}
fn split_file_name(&self) -> Option<(&str, &str)> {
Some(self.split_at(self.find('.')?))
}
}
pub const trait RemoveChar {
fn remove_char_at(&mut self, pos: usize);
fn pop_char_at(&mut self, pos: usize) -> Option<char>;
fn remove_chars_at(&mut self, pos: usize, amount: usize);
fn pop_chars_at(&mut self, pos: usize, amount: usize) -> Option<Vec<char>>;
}
impl RemoveChar for String {
fn remove_char_at(&mut self, pos: usize) {
if pos < self.chars().count() {
let mut chars: Vec<char> = self.chars().collect();
chars.remove(pos);
*self = chars.into_iter().collect();
}
}
fn pop_char_at(&mut self, pos: usize) -> Option<char> {
if pos < self.chars().count() {
let mut chars: Vec<char> = self.chars().collect();
let removed = chars.remove(pos);
*self = chars.into_iter().collect();
Some(removed)
} else {
None
}
}
fn remove_chars_at(&mut self, pos: usize, amount: usize) {
let len = self.chars().count();
if pos < len {
let mut chars: Vec<char> = self.chars().collect();
let end = (pos + amount).min(len);
chars.drain(pos..end);
*self = chars.into_iter().collect();
}
}
fn pop_chars_at(&mut self, pos: usize, amount: usize) -> Option<Vec<char>> {
let mut rt = Vec::new();
if pos < self.chars().count() {
for _ in 0..amount {
let mut chars: Vec<char> = self.chars().collect();
let removed = chars.remove(pos);
*self = chars.into_iter().collect();
rt.push(removed);
}
Some(rt)
} else {
None
}
}
}
pub const trait ConcatenateString {
fn concatenate(&self) -> String;
}
impl ConcatenateString for Vec<&str> {
fn concatenate(&self) -> String {
let mut final_string = String::new();
for i in self {
final_string.push_str(i);
}
final_string
}
}
impl ConcatenateString for Vec<String> {
fn concatenate(&self) -> String {
let mut final_string = String::new();
for i in self {
final_string.push_str(i);
}
final_string
}
}
impl ConcatenateString for Vec<char> {
fn concatenate(&self) -> String {
let mut final_string = String::new();
for i in self {
final_string.push(*i);
}
final_string
}
}