xsd_parser/models/naming/
default.rs1use std::any::Any;
2use std::sync::{
3 atomic::{AtomicUsize, Ordering},
4 Arc,
5};
6
7use inflector::Inflector;
8use proc_macro2::Ident as Ident2;
9
10use crate::models::{meta::MetaType, TypeIdent};
11use crate::traits::{NameBuilder as NameBuilderTrait, Naming as NamingTrait};
12
13use super::Name;
14
15#[derive(Default, Debug, Clone)]
20pub struct Naming(Arc<AtomicUsize>);
21
22impl NamingTrait for Naming {
23 fn clone_boxed(&self) -> Box<dyn NamingTrait> {
24 Box::new(self.clone())
25 }
26
27 fn builder(&self) -> Box<dyn NameBuilderTrait> {
28 Box::new(NameBuilder::new(self.0.clone(), Box::new(self.clone())))
29 }
30
31 fn unify(&self, s: &str) -> String {
32 super::unify_string(s)
33 }
34
35 fn make_type_name(&self, postfixes: &[String], ty: &MetaType, ident: &TypeIdent) -> Name {
36 super::make_type_name(self, postfixes, ty, ident)
37 }
38
39 fn make_unknown_variant(&self, id: usize) -> Ident2 {
40 super::format_unknown_variant(id)
41 }
42
43 fn format_module_name(&self, s: &str) -> String {
44 let s = self.unify(s).to_snake_case();
45
46 super::format_ident(s)
47 }
48
49 fn format_type_name(&self, s: &str) -> String {
50 let s = self.unify(s);
51
52 super::format_ident(s)
53 }
54
55 fn format_field_name(&self, s: &str) -> String {
56 let s = self.unify(s).to_snake_case();
57
58 super::format_ident(s)
59 }
60
61 fn format_variant_name(&self, s: &str) -> String {
62 let s = self.unify(s);
63
64 super::format_ident(s)
65 }
66
67 fn format_constant_name(&self, s: &str) -> String {
68 let s = self.unify(s).to_screaming_snake_case();
69
70 super::format_ident(s)
71 }
72}
73
74#[must_use]
76#[derive(Debug)]
77pub struct NameBuilder {
78 id: Arc<AtomicUsize>,
79 my_id: Option<usize>,
80 with_id: bool,
81 generated: bool,
82
83 name: Option<String>,
84 extension: Option<String>,
85
86 naming: Box<dyn NamingTrait>,
87}
88
89impl NameBuilder {
90 pub fn new(id: Arc<AtomicUsize>, naming: Box<dyn NamingTrait>) -> Self {
94 Self {
95 id,
96 my_id: None,
97 with_id: true,
98 generated: false,
99 name: None,
100 extension: None,
101 naming,
102 }
103 }
104}
105
106impl Clone for NameBuilder {
107 fn clone(&self) -> Self {
108 Self {
109 id: self.id.clone(),
110 my_id: self.my_id,
111 with_id: self.with_id,
112 generated: self.generated,
113 name: self.name.clone(),
114 extension: self.extension.clone(),
115 naming: self.naming.clone_boxed(),
116 }
117 }
118}
119
120impl NameBuilderTrait for NameBuilder {
121 fn finish(&self) -> Name {
122 let Self {
123 id,
124 my_id,
125 with_id,
126 mut generated,
127 name,
128 extension,
129 naming,
130 } = self;
131
132 let mut ret = String::new();
133 if let Some(s) = extension {
134 generated = true;
135 ret.push_str(&naming.unify(s));
136 }
137
138 if let Some(s) = name {
139 if ret.is_empty() {
140 ret.push_str(s);
141 } else {
142 ret.push_str(&naming.unify(s));
143 }
144 }
145
146 if ret.is_empty() {
147 generated = true;
148 ret.push_str("Unnamed");
149 }
150
151 if *with_id {
152 generated = true;
153 let id = my_id.unwrap_or_else(|| id.fetch_add(1, Ordering::Relaxed));
154 ret = format!("{ret}{id}");
155 }
156
157 if generated {
158 Name::new_generated(ret)
159 } else {
160 Name::new_named(ret)
161 }
162 }
163
164 fn merge(&mut self, other: &dyn NameBuilderTrait) {
165 let other: &Self = (other as &dyn Any).downcast_ref().unwrap();
166
167 if let Some(name) = other.name.clone() {
168 self.name.get_or_insert(name);
169 self.with_id = other.with_id;
170 self.generated = other.generated;
171
172 if let Some(id) = other.my_id {
173 self.with_id = other.with_id;
174 self.my_id.get_or_insert(id);
175 }
176
177 if let Some(ext) = other.extension.clone() {
178 self.extension.get_or_insert(ext);
179 }
180 }
181 }
182
183 fn clone_boxed(&self) -> Box<dyn NameBuilderTrait> {
184 Box::new(self.clone())
185 }
186
187 fn has_name(&self) -> bool {
188 self.name.is_some()
189 }
190
191 fn has_extension(&self) -> bool {
192 self.extension.is_some()
193 }
194
195 fn set_name(&mut self, name: String) {
196 self.name = Some(name);
197 }
198
199 fn set_with_id(&mut self, value: bool) {
200 self.with_id = value;
201 }
202
203 fn set_generated(&mut self, value: bool) {
204 self.generated = value;
205 }
206
207 fn add_extension(&mut self, replace: bool, extension: String) {
208 let s = self.naming.unify(&extension);
209
210 if replace {
211 self.extension = Some(s);
212 } else if let Some(prefix) = &self.extension {
213 self.extension = Some(format!("{s}{prefix}"));
214 } else {
215 self.extension = Some(s);
216 }
217 }
218
219 fn strip_suffix(&mut self, suffix: &str) {
220 if let Some(s) = &mut self.name {
221 if let Some(x) = s.strip_suffix(suffix) {
222 *s = x.into();
223 }
224 }
225
226 if let Some(s) = &mut self.extension {
227 if let Some(x) = s.strip_suffix(suffix) {
228 *s = x.into();
229 }
230 }
231 }
232
233 fn generate_unique_id(&mut self) {
234 if self.my_id.is_none() {
235 self.my_id = Some(self.id.fetch_add(1, Ordering::Release));
236 }
237 }
238
239 fn prepare_type_name(&mut self) {
240 self.strip_suffix("Type");
241 self.strip_suffix("Content");
242 }
243
244 fn prepare_field_name(&mut self) {
245 self.strip_suffix("Type");
246 self.strip_suffix("Content");
247 }
248
249 fn prepare_content_type_name(&mut self) {
250 self.strip_suffix("Type");
251 self.strip_suffix("Content");
252 }
253}
254
255#[cfg(test)]
256mod tests {
257 use crate::traits::Naming as _;
258
259 use super::Naming;
260
261 #[test]
262 fn default_naming() {
263 let naming = Naming::default();
264
265 assert_eq!("_", naming.unify("+"));
266 assert_eq!("FuuBarBaz", naming.unify("Fuu_BAR_BAZ"));
267 assert_eq!("FuuBarBaz", naming.unify("fuu_bar_baz"));
268 assert_eq!("FuuBarBaz", naming.unify("fuu+Bar-BAZ"));
269
270 assert_eq!("QName", naming.unify("QName"));
271 assert_eq!("QName", naming.format_type_name("QName"));
272 assert_eq!("QName", naming.format_variant_name("QName"));
273 assert_eq!("q_name", naming.format_field_name("QName"));
274 }
275}