cbindgen/bindgen/
rename.rs1use std::borrow::Cow;
6use std::str::FromStr;
7
8#[derive(Debug, Clone, Copy)]
10pub enum IdentifierType<'a> {
11 StructMember,
12 EnumVariant { prefix: &'a str },
13 FunctionArg,
14 Type,
15 Enum,
16}
17
18impl IdentifierType<'_> {
19 fn to_str(self) -> &'static str {
20 match self {
21 IdentifierType::StructMember => "m",
22 IdentifierType::EnumVariant { .. } => "",
23 IdentifierType::FunctionArg => "a",
24 IdentifierType::Type => "",
25 IdentifierType::Enum => "",
26 }
27 }
28}
29
30#[derive(Debug, Clone, Default)]
32pub enum RenameRule {
33 #[default]
35 None,
36 GeckoCase,
38 LowerCase,
40 UpperCase,
42 PascalCase,
44 CamelCase,
46 SnakeCase,
48 ScreamingSnakeCase,
50 QualifiedScreamingSnakeCase,
53 Prefix(String),
55}
56
57impl RenameRule {
58 pub(crate) fn not_none(&self) -> Option<&Self> {
59 match self {
60 RenameRule::None => None,
61 other => Some(other),
62 }
63 }
64
65 pub fn apply<'a>(&self, text: &'a str, context: IdentifierType) -> Cow<'a, str> {
67 use heck::*;
68
69 if text.is_empty() {
70 return Cow::Borrowed(text);
71 }
72
73 Cow::Owned(match self {
74 RenameRule::None => return Cow::Borrowed(text),
75 RenameRule::GeckoCase => context.to_str().to_owned() + &text.to_upper_camel_case(),
76 RenameRule::LowerCase => text.to_lowercase(),
77 RenameRule::UpperCase => text.to_uppercase(),
78 RenameRule::PascalCase => text.to_pascal_case(),
79 RenameRule::CamelCase => text.to_lower_camel_case(),
80 RenameRule::SnakeCase => text.to_snake_case(),
81 RenameRule::ScreamingSnakeCase => text.to_shouty_snake_case(),
82 RenameRule::QualifiedScreamingSnakeCase => {
83 let mut result = String::new();
84
85 if let IdentifierType::EnumVariant { prefix } = context {
86 result.push_str(
87 &RenameRule::ScreamingSnakeCase.apply(prefix, IdentifierType::Enum),
88 );
89 result.push('_');
90 }
91
92 result.push_str(&RenameRule::ScreamingSnakeCase.apply(text, context));
93 result
94 }
95 RenameRule::Prefix(prefix) => prefix.to_owned() + text,
96 })
97 }
98}
99
100impl FromStr for RenameRule {
101 type Err = String;
102
103 fn from_str(s: &str) -> Result<RenameRule, Self::Err> {
104 const PREFIX: &str = "prefix:";
105 const PREFIX_LEN: usize = PREFIX.len();
106
107 match s {
108 "none" => Ok(RenameRule::None),
109 "None" => Ok(RenameRule::None),
110
111 "mGeckoCase" => Ok(RenameRule::GeckoCase),
112 "GeckoCase" => Ok(RenameRule::GeckoCase),
113 "gecko_case" => Ok(RenameRule::GeckoCase),
114
115 "lowercase" => Ok(RenameRule::LowerCase),
116 "LowerCase" => Ok(RenameRule::LowerCase),
117 "lower_case" => Ok(RenameRule::LowerCase),
118
119 "UPPERCASE" => Ok(RenameRule::UpperCase),
120 "UpperCase" => Ok(RenameRule::UpperCase),
121 "upper_case" => Ok(RenameRule::UpperCase),
122
123 "PascalCase" => Ok(RenameRule::PascalCase),
124 "pascal_case" => Ok(RenameRule::PascalCase),
125
126 "camelCase" => Ok(RenameRule::CamelCase),
127 "CamelCase" => Ok(RenameRule::CamelCase),
128 "camel_case" => Ok(RenameRule::CamelCase),
129
130 "snake_case" => Ok(RenameRule::SnakeCase),
131 "SnakeCase" => Ok(RenameRule::SnakeCase),
132
133 "SCREAMING_SNAKE_CASE" => Ok(RenameRule::ScreamingSnakeCase),
134 "ScreamingSnakeCase" => Ok(RenameRule::ScreamingSnakeCase),
135 "screaming_snake_case" => Ok(RenameRule::ScreamingSnakeCase),
136
137 "QUALIFIED_SCREAMING_SNAKE_CASE" => Ok(RenameRule::QualifiedScreamingSnakeCase),
138 "QualifiedScreamingSnakeCase" => Ok(RenameRule::QualifiedScreamingSnakeCase),
139 "qualified_screaming_snake_case" => Ok(RenameRule::QualifiedScreamingSnakeCase),
140
141 s if s.starts_with(PREFIX) => Ok(RenameRule::Prefix(s[PREFIX_LEN..].to_string())),
142
143 _ => Err(format!("Unrecognized RenameRule: '{}'.", s)),
144 }
145 }
146}
147
148deserialize_enum_str!(RenameRule);