use crate::foundations::{cast, func, Cast, Content, Str}; use crate::text::TextElem; /// Converts a string or content to lowercase. /// /// # Example /// ```example /// #lower("ABC") \ /// #lower[*My Text*] \ /// #lower[already low] /// ``` #[func(title = "Lowercase")] pub fn lower( /// The text to convert to lowercase. text: Caseable, ) -> Caseable { case(text, Case::Lower) } /// Converts a string or content to uppercase. /// /// # Example /// ```example /// #upper("abc") \ /// #upper[*my text*] \ /// #upper[ALREADY HIGH] /// ``` #[func(title = "Uppercase")] pub fn upper( /// The text to convert to uppercase. text: Caseable, ) -> Caseable { case(text, Case::Upper) } /// Change the case of text. fn case(text: Caseable, case: Case) -> Caseable { match text { Caseable::Str(v) => Caseable::Str(case.apply(&v).into()), Caseable::Content(v) => { Caseable::Content(v.styled(TextElem::set_case(Some(case)))) } } } /// A value whose case can be changed. pub enum Caseable { Str(Str), Content(Content), } cast! { Caseable, self => match self { Self::Str(v) => v.into_value(), Self::Content(v) => v.into_value(), }, v: Str => Self::Str(v), v: Content => Self::Content(v), } /// A case transformation on text. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Cast)] pub enum Case { /// Everything is lowercased. Lower, /// Everything is uppercased. Upper, } impl Case { /// Apply the case to a string. pub fn apply(self, text: &str) -> String { match self { Self::Lower => text.to_lowercase(), Self::Upper => text.to_uppercase(), } } }