]>
git.proxmox.com Git - cargo.git/blob - vendor/serde_derive/src/internals/case.rs
1 //! Code to convert the Rust-styled field/variant (e.g. `my_field`, `MyType`) to the
2 //! case of the source (e.g. `my-field`, `MY_FIELD`).
4 // See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
5 #[allow(deprecated, unused_imports)]
6 use std
::ascii
::AsciiExt
;
8 use std
::fmt
::{self, Debug, Display}
;
10 use self::RenameRule
::*;
12 /// The different possible ways to change case of fields in a struct, or variants in an enum.
13 #[derive(Copy, Clone, PartialEq)]
15 /// Don't apply a default rename rule.
17 /// Rename direct children to "lowercase" style.
19 /// Rename direct children to "UPPERCASE" style.
21 /// Rename direct children to "PascalCase" style, as typically used for
24 /// Rename direct children to "camelCase" style.
26 /// Rename direct children to "snake_case" style, as commonly used for
29 /// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly
30 /// used for constants.
32 /// Rename direct children to "kebab-case" style.
34 /// Rename direct children to "SCREAMING-KEBAB-CASE" style.
38 static RENAME_RULES
: &[(&str, RenameRule
)] = &[
39 ("lowercase", LowerCase
),
40 ("UPPERCASE", UpperCase
),
41 ("PascalCase", PascalCase
),
42 ("camelCase", CamelCase
),
43 ("snake_case", SnakeCase
),
44 ("SCREAMING_SNAKE_CASE", ScreamingSnakeCase
),
45 ("kebab-case", KebabCase
),
46 ("SCREAMING-KEBAB-CASE", ScreamingKebabCase
),
50 pub fn from_str(rename_all_str
: &str) -> Result
<Self, ParseError
> {
51 for (name
, rule
) in RENAME_RULES
{
52 if rename_all_str
== *name
{
57 unknown
: rename_all_str
,
61 /// Apply a renaming rule to an enum variant, returning the version expected in the source.
62 pub fn apply_to_variant(&self, variant
: &str) -> String
{
64 None
| PascalCase
=> variant
.to_owned(),
65 LowerCase
=> variant
.to_ascii_lowercase(),
66 UpperCase
=> variant
.to_ascii_uppercase(),
67 CamelCase
=> variant
[..1].to_ascii_lowercase() + &variant
[1..],
69 let mut snake
= String
::new();
70 for (i
, ch
) in variant
.char_indices() {
71 if i
> 0 && ch
.is_uppercase() {
74 snake
.push(ch
.to_ascii_lowercase());
78 ScreamingSnakeCase
=> SnakeCase
.apply_to_variant(variant
).to_ascii_uppercase(),
79 KebabCase
=> SnakeCase
.apply_to_variant(variant
).replace('_'
, "-"),
80 ScreamingKebabCase
=> ScreamingSnakeCase
81 .apply_to_variant(variant
)
86 /// Apply a renaming rule to a struct field, returning the version expected in the source.
87 pub fn apply_to_field(&self, field
: &str) -> String
{
89 None
| LowerCase
| SnakeCase
=> field
.to_owned(),
90 UpperCase
=> field
.to_ascii_uppercase(),
92 let mut pascal
= String
::new();
93 let mut capitalize
= true;
94 for ch
in field
.chars() {
97 } else if capitalize
{
98 pascal
.push(ch
.to_ascii_uppercase());
107 let pascal
= PascalCase
.apply_to_field(field
);
108 pascal
[..1].to_ascii_lowercase() + &pascal
[1..]
110 ScreamingSnakeCase
=> field
.to_ascii_uppercase(),
111 KebabCase
=> field
.replace('_'
, "-"),
112 ScreamingKebabCase
=> ScreamingSnakeCase
.apply_to_field(field
).replace('_'
, "-"),
117 pub struct ParseError
<'a
> {
121 impl<'a
> Display
for ParseError
<'a
> {
122 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
123 f
.write_str("unknown rename rule `rename_all = ")?
;
124 Debug
::fmt(self.unknown
, f
)?
;
125 f
.write_str("`, expected one of ")?
;
126 for (i
, (name
, _rule
)) in RENAME_RULES
.iter().enumerate() {
130 Debug
::fmt(name
, f
)?
;
137 fn rename_variants() {
138 for &(original
, lower
, upper
, camel
, snake
, screaming
, kebab
, screaming_kebab
) in &[
140 "Outcome", "outcome", "OUTCOME", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
152 ("A", "a", "A", "a", "a", "A", "a", "A"),
153 ("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"),
155 assert_eq
!(None
.apply_to_variant(original
), original
);
156 assert_eq
!(LowerCase
.apply_to_variant(original
), lower
);
157 assert_eq
!(UpperCase
.apply_to_variant(original
), upper
);
158 assert_eq
!(PascalCase
.apply_to_variant(original
), original
);
159 assert_eq
!(CamelCase
.apply_to_variant(original
), camel
);
160 assert_eq
!(SnakeCase
.apply_to_variant(original
), snake
);
161 assert_eq
!(ScreamingSnakeCase
.apply_to_variant(original
), screaming
);
162 assert_eq
!(KebabCase
.apply_to_variant(original
), kebab
);
164 ScreamingKebabCase
.apply_to_variant(original
),
172 for &(original
, upper
, pascal
, camel
, screaming
, kebab
, screaming_kebab
) in &[
174 "outcome", "OUTCOME", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
185 ("a", "A", "A", "a", "A", "a", "A"),
186 ("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"),
188 assert_eq
!(None
.apply_to_field(original
), original
);
189 assert_eq
!(UpperCase
.apply_to_field(original
), upper
);
190 assert_eq
!(PascalCase
.apply_to_field(original
), pascal
);
191 assert_eq
!(CamelCase
.apply_to_field(original
), camel
);
192 assert_eq
!(SnakeCase
.apply_to_field(original
), original
);
193 assert_eq
!(ScreamingSnakeCase
.apply_to_field(original
), screaming
);
194 assert_eq
!(KebabCase
.apply_to_field(original
), kebab
);
195 assert_eq
!(ScreamingKebabCase
.apply_to_field(original
), screaming_kebab
);