use crate::utility;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
pub struct Str {
data: String,
}
impl Str {
pub fn new() -> Self {
Self { data: String::new() }
}
pub fn len(&self) -> i32 {
self.data.len() as i32
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn chars(&self) -> std::str::Chars<'_> {
self.data.chars()
}
pub fn find(&self, pattern: &str) -> Option<usize> {
self.data.find(pattern)
}
pub fn contains(&self, pattern: &str) -> bool {
self.data.contains(pattern)
}
pub fn count(&self, element: char) -> usize {
self.data.chars().filter(|&x| x == element).count()
}
pub fn to_decimal(&self) -> Option<f64> {
self.data.parse().ok()
}
pub fn starts_with(&self, pattern: &str) -> bool {
self.data.starts_with(pattern)
}
pub fn ends_with(&self, pattern: &str) -> bool {
self.data.ends_with(pattern)
}
pub fn lower(&self) -> Self {
Self { data: self.data.to_lowercase() }
}
pub fn upper(&self) -> Self {
Self { data: self.data.to_uppercase() }
}
pub fn replace(&self, old_str: &str, new_str: &str) -> Self {
Self {
data: self.data.replace(old_str, new_str),
}
}
pub fn strip(&self) -> Self {
Self {
data: String::from(self.data.trim()),
}
}
pub fn split(&self, separator: &str) -> crate::List<&str> {
crate::List::from(self.data.split(separator).collect::<Vec<&str>>())
}
pub fn join(&self, str_list: crate::List<&str>) -> Self {
let v: Vec<&str> = str_list.into();
Self {
data: v.join(self.data.as_str()),
}
}
}
impl From<&str> for Str {
fn from(value: &str) -> Self {
utility::check_full(value.len(), i32::MAX as usize);
Self { data: String::from(value) }
}
}
impl<T: std::fmt::Display> From<crate::Deque<T>> for Str {
fn from(value: crate::Deque<T>) -> Self {
Self::from(value.to_string())
}
}
impl From<crate::Fraction> for Str {
fn from(value: crate::Fraction) -> Self {
Self::from(value.to_string())
}
}
impl From<crate::Int> for Str {
fn from(value: crate::Int) -> Self {
Self::from(value.to_string())
}
}
impl<T: std::fmt::Display> From<crate::List<T>> for Str {
fn from(value: crate::List<T>) -> Self {
Self::from(value.to_string())
}
}
impl<T: std::fmt::Display> From<crate::Set<T>> for Str {
fn from(value: crate::Set<T>) -> Self {
Self::from(value.to_string())
}
}
impl std::ops::Index<i32> for Str {
type Output = str;
fn index(&self, index: i32) -> &Self::Output {
utility::check_bounds(index, -self.len(), self.len());
let index = utility::calc_index(index, self.data.len());
&self.data[index..=index]
}
}
impl std::fmt::Display for Str {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\"{}\"", self.data)
}
}
impl FromIterator<char> for Str {
fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> Self {
let data = iter.into_iter().collect();
Self { data }
}
}
impl From<String> for Str {
fn from(value: String) -> Self {
utility::check_full(value.len(), i32::MAX as usize);
Self { data: value }
}
}
impl From<Str> for String {
fn from(value: Str) -> Self {
value.data
}
}