postgres_derive/
case.rs

1#[allow(deprecated, unused_imports)]
2use std::ascii::AsciiExt;
3
4use heck::{
5    ToKebabCase, ToLowerCamelCase, ToShoutyKebabCase, ToShoutySnakeCase, ToSnakeCase, ToTrainCase,
6    ToUpperCamelCase,
7};
8
9use self::RenameRule::*;
10
11/// The different possible ways to change case of fields in a struct, or variants in an enum.
12#[allow(clippy::enum_variant_names)]
13#[derive(Copy, Clone, PartialEq)]
14pub enum RenameRule {
15    /// Rename direct children to "lowercase" style.
16    LowerCase,
17    /// Rename direct children to "UPPERCASE" style.
18    UpperCase,
19    /// Rename direct children to "PascalCase" style, as typically used for
20    /// enum variants.
21    PascalCase,
22    /// Rename direct children to "camelCase" style.
23    CamelCase,
24    /// Rename direct children to "snake_case" style, as commonly used for
25    /// fields.
26    SnakeCase,
27    /// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly
28    /// used for constants.
29    ScreamingSnakeCase,
30    /// Rename direct children to "kebab-case" style.
31    KebabCase,
32    /// Rename direct children to "SCREAMING-KEBAB-CASE" style.
33    ScreamingKebabCase,
34
35    /// Rename direct children to "Train-Case" style.
36    TrainCase,
37}
38
39pub const RENAME_RULES: &[&str] = &[
40    "lowercase",
41    "UPPERCASE",
42    "PascalCase",
43    "camelCase",
44    "snake_case",
45    "SCREAMING_SNAKE_CASE",
46    "kebab-case",
47    "SCREAMING-KEBAB-CASE",
48    "Train-Case",
49];
50
51impl RenameRule {
52    pub fn from_str(rule: &str) -> Option<RenameRule> {
53        match rule {
54            "lowercase" => Some(LowerCase),
55            "UPPERCASE" => Some(UpperCase),
56            "PascalCase" => Some(PascalCase),
57            "camelCase" => Some(CamelCase),
58            "snake_case" => Some(SnakeCase),
59            "SCREAMING_SNAKE_CASE" => Some(ScreamingSnakeCase),
60            "kebab-case" => Some(KebabCase),
61            "SCREAMING-KEBAB-CASE" => Some(ScreamingKebabCase),
62            "Train-Case" => Some(TrainCase),
63            _ => None,
64        }
65    }
66    /// Apply a renaming rule to an enum or struct field, returning the version expected in the source.
67    pub fn apply_to_field(&self, variant: &str) -> String {
68        match *self {
69            LowerCase => variant.to_lowercase(),
70            UpperCase => variant.to_uppercase(),
71            PascalCase => variant.to_upper_camel_case(),
72            CamelCase => variant.to_lower_camel_case(),
73            SnakeCase => variant.to_snake_case(),
74            ScreamingSnakeCase => variant.to_shouty_snake_case(),
75            KebabCase => variant.to_kebab_case(),
76            ScreamingKebabCase => variant.to_shouty_kebab_case(),
77            TrainCase => variant.to_train_case(),
78        }
79    }
80}
81
82#[test]
83fn rename_field() {
84    for &(original, lower, upper, camel, snake, screaming, kebab, screaming_kebab) in &[
85        (
86            "Outcome", "outcome", "OUTCOME", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
87        ),
88        (
89            "VeryTasty",
90            "verytasty",
91            "VERYTASTY",
92            "veryTasty",
93            "very_tasty",
94            "VERY_TASTY",
95            "very-tasty",
96            "VERY-TASTY",
97        ),
98        ("A", "a", "A", "a", "a", "A", "a", "A"),
99        ("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"),
100    ] {
101        assert_eq!(LowerCase.apply_to_field(original), lower);
102        assert_eq!(UpperCase.apply_to_field(original), upper);
103        assert_eq!(PascalCase.apply_to_field(original), original);
104        assert_eq!(CamelCase.apply_to_field(original), camel);
105        assert_eq!(SnakeCase.apply_to_field(original), snake);
106        assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming);
107        assert_eq!(KebabCase.apply_to_field(original), kebab);
108        assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab);
109    }
110}