Skip to main content

canic_utils/case/
mod.rs

1use derive_more::Display;
2
3mod constant;
4mod snake;
5mod title;
6
7pub use snake::to_snake_case;
8
9///
10/// case
11///
12/// all case operations come through here as we have to include
13/// multiple crates to get the desired behaviour
14///
15
16// Case
17#[derive(Clone, Copy, Debug, Display)]
18pub enum Case {
19    Camel,
20    Constant, // adheres to rust constant rules, more strict than UPPER_SNAKE
21    Kebab,
22    Lower,
23    Sentence,
24    Snake,
25    Title,
26    Upper,
27    UpperCamel, // or PascalCase
28    UpperSnake, // or SCREAMING_SNAKE
29    UpperKebab, // or TRAIN-CASE
30}
31
32///
33/// Casing
34///
35
36pub trait Casing<T: std::fmt::Display> {
37    fn to_case(&self, case: Case) -> String;
38    fn is_case(&self, case: Case) -> bool;
39}
40
41impl<T: std::fmt::Display> Casing<T> for T
42where
43    String: PartialEq<T>,
44{
45    // to_case
46    // don't use convert_case:: Lower and Upper because they add spaces, and other
47    // unexpected behaviour
48    fn to_case(&self, case: Case) -> String {
49        use convert_case as cc;
50        let s = &self.to_string();
51
52        match case {
53            // rust
54            Case::Lower => s.to_lowercase(),
55            Case::Upper => s.to_uppercase(),
56
57            // custom
58            Case::Title => title::to_title_case(s),
59            Case::Snake => snake::to_snake_case(s),
60            Case::UpperSnake => snake::to_snake_case(s).to_uppercase(),
61            Case::Constant => constant::to_constant_case(s).to_uppercase(),
62
63            // convert_case
64            Case::Camel => cc::Casing::to_case(s, cc::Case::Camel),
65            Case::Kebab => cc::Casing::to_case(s, cc::Case::Kebab),
66            Case::Sentence => cc::Casing::to_case(s, cc::Case::Sentence),
67            Case::UpperCamel => cc::Casing::to_case(s, cc::Case::UpperCamel),
68            Case::UpperKebab => cc::Casing::to_case(s, cc::Case::Kebab).to_uppercase(),
69        }
70    }
71
72    // is_case
73    fn is_case(&self, case: Case) -> bool {
74        &self.to_case(case) == self
75    }
76}