code_generator/
as_case.rs1use core::{fmt::Display, str::Chars};
2use crate::CaseType;
5
6pub const CASE_SEPARATOR: char = '`';
7
8pub struct Cased<'a, T: ?Sized> {
9 case_type: CaseType,
10 source: &'a T,
11}
12
13pub trait AsCase<'a> {
14 fn as_case(&'a self, case_type: CaseType) -> impl Display + 'a;
15}
16
17impl<'a> AsCase<'a> for str {
18 fn as_case(&'a self, case_type: CaseType) -> impl Display + 'a {
19 Cased {
20 case_type,
21 source: self
22 }
23 }
24}
25
26impl<'a> AsCase<'a> for String {
27 fn as_case(&self, case_type: CaseType) -> impl Display {
28 Cased {
29 case_type,
30 source: self
31 }
32 }
33}
34
35impl<'a, T: ?Sized> Cased<'a, T> {
36 fn write_first_char(case_type: CaseType, char: char, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
37 match case_type {
38 CaseType::FlatCase => { write!(f, "{}", char.to_lowercase()) }
39 CaseType::ScreamingCase => { write!(f, "{}", char.to_uppercase()) }
40 CaseType::CamelCase => { write!(f, "{}", char.to_lowercase()) }
41 CaseType::PascalCase => { write!(f, "{}", char.to_uppercase()) }
42 CaseType::SnakeCase => { write!(f, "{}", char.to_lowercase()) }
43 CaseType::ScreamingSnakeCase => { write!(f, "{}", char.to_uppercase()) }
44 }
45 }
46 fn write_first_char_in_chunk(case_type: CaseType, char: char, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47 match case_type {
48 CaseType::FlatCase => { write!(f, "{}", char.to_lowercase()) }
49 CaseType::ScreamingCase => { write!(f, "{}", char.to_uppercase()) }
50 CaseType::CamelCase => { write!(f, "{}", char.to_uppercase()) }
51 CaseType::PascalCase => { write!(f, "{}", char.to_uppercase()) }
52 CaseType::SnakeCase => { write!(f, "{}", char.to_lowercase()) }
53 CaseType::ScreamingSnakeCase => { write!(f, "{}", char.to_uppercase()) }
54 }
55 }
56 fn write_default_char(case_type: CaseType, char: char, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
57 match case_type {
58 CaseType::FlatCase => { write!(f, "{}", char.to_lowercase()) }
59 CaseType::ScreamingCase => { write!(f, "{}", char.to_uppercase()) }
60 CaseType::CamelCase => { write!(f, "{}", char.to_lowercase()) }
61 CaseType::PascalCase => { write!(f, "{}", char.to_lowercase()) }
62 CaseType::SnakeCase => { write!(f, "{}", char.to_lowercase()) }
63 CaseType::ScreamingSnakeCase => { write!(f, "{}", char.to_uppercase()) }
64 }
65 }
66 fn write_chunk_separator(case_type: CaseType, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
67 match case_type {
68 CaseType::FlatCase => { core::fmt::Result::Ok(()) }
69 CaseType::ScreamingCase => { core::fmt::Result::Ok(()) }
70 CaseType::CamelCase => { core::fmt::Result::Ok(()) }
71 CaseType::PascalCase => { core::fmt::Result::Ok(()) }
72 CaseType::SnakeCase => { write!(f, "{}", '_') }
73 CaseType::ScreamingSnakeCase => { write!(f, "{}", '_') }
74 }
75 }
76 fn casify(chars: Chars<'_>, case_type: CaseType, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
77 let mut result = core::fmt::Result::Ok(());
78
79 let mut is_first_in_chunk = false;
80 let mut is_first = true;
81
82 for char in chars {
83 if char == CASE_SEPARATOR {
84 is_first_in_chunk = true;
85 continue;
86 }
87
88 if char.is_uppercase() {
89 is_first_in_chunk = true;
90 }
91
92 match (is_first, is_first_in_chunk) {
93 (true, _) => {result = result.and(Self::write_first_char(case_type, char, f));}
94 (_, true) => {
95 result = result.and(Self::write_chunk_separator(case_type, f));
96 result = result.and(Self::write_first_char_in_chunk(case_type, char, f));
97 }
98 (_, false) => {result = result.and(Self::write_default_char(case_type, char, f));}
99 }
100
101 is_first_in_chunk = false;
102 is_first = false;
103 }
104
105 result
106 }
107}
108
109impl<'a> Display for Cased<'a, str> {
110 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
111 Self::casify(self.source.chars(), self.case_type, f)
112 }
113}
114
115impl<'a> Display for Cased<'a, String> {
116 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
117 Self::casify(self.source.chars(), self.case_type, f)
118 }
119}