1use std::any::Any;
2use std::fmt::{Debug, Display};
3use std::mem::take;
4
5use proc_macro2::Ident as Ident2;
6use quote::format_ident;
7
8use crate::models::{
9 meta::{MetaType, MetaTypes},
10 schema::NamespaceId,
11 Name, TypeIdent,
12};
13
14pub trait Naming: Debug {
19 fn clone_boxed(&self) -> Box<dyn Naming>;
21
22 fn builder(&self) -> Box<dyn NameBuilder>;
24
25 fn unify(&self, s: &str) -> String;
34
35 fn make_type_name(&self, postfixes: &[String], ty: &MetaType, ident: &TypeIdent) -> Name;
38
39 fn make_unknown_variant(&self, id: usize) -> Ident2;
43
44 fn format_module_name(&self, s: &str) -> String;
46
47 fn format_type_name(&self, s: &str) -> String;
49
50 fn format_field_name(&self, s: &str) -> String;
52
53 fn format_variant_name(&self, s: &str) -> String;
55
56 fn format_constant_name(&self, s: &str) -> String;
58
59 fn format_attribute_field_name(&self, s: &str) -> String {
63 self.format_field_name(s)
64 }
65
66 fn format_element_field_name(&self, s: &str) -> String {
70 self.format_field_name(s)
71 }
72
73 fn format_module_ident(&self, name: &Name) -> Ident2 {
78 let ident = self.format_module_name(name.as_str());
79
80 format_ident!("{ident}")
81 }
82
83 fn format_type_ident(&self, name: &Name, display_name: Option<&str>) -> Ident2 {
89 let ident = self.format_type_name(display_name.unwrap_or(name.as_str()));
90
91 format_ident!("{ident}")
92 }
93
94 fn format_field_ident(&self, name: &Name, display_name: Option<&str>) -> Ident2 {
100 let ident = self.format_field_name(display_name.unwrap_or(name.as_str()));
101
102 format_ident!("{ident}")
103 }
104
105 fn format_variant_ident(&self, name: &Name, display_name: Option<&str>) -> Ident2 {
110 let ident = self.format_variant_name(display_name.unwrap_or(name.as_str()));
111
112 format_ident!("{ident}")
113 }
114
115 fn format_constant_ident(&self, name: &Name, display_name: Option<&str>) -> Ident2 {
120 let ident = self.format_constant_name(display_name.unwrap_or(name.as_str()));
121
122 format_ident!("{ident}")
123 }
124
125 fn format_attribute_field_ident(&self, name: &Name, display_name: Option<&str>) -> Ident2 {
130 let ident = self.format_attribute_field_name(display_name.unwrap_or(name.as_str()));
131
132 format_ident!("{ident}")
133 }
134
135 fn format_element_field_ident(&self, name: &Name, display_name: Option<&str>) -> Ident2 {
140 let ident = self.format_element_field_name(display_name.unwrap_or(name.as_str()));
141
142 format_ident!("{ident}")
143 }
144
145 fn format_module(&self, types: &MetaTypes, ns: Option<NamespaceId>) -> Option<Ident2> {
147 let ns = ns?;
148 let module = types.modules.get(&ns)?;
149 let name = module.name.as_ref()?;
150
151 Some(self.format_module_ident(name))
152 }
153}
154
155pub trait NameBuilder: Debug + Any {
170 fn finish(&self) -> Name;
173
174 fn merge(&mut self, other: &dyn NameBuilder);
177
178 fn clone_boxed(&self) -> Box<dyn NameBuilder>;
180
181 fn has_name(&self) -> bool;
183
184 fn has_extension(&self) -> bool;
186
187 fn set_name(&mut self, name: String);
189
190 fn set_with_id(&mut self, value: bool);
192
193 fn set_generated(&mut self, value: bool);
196
197 fn add_extension(&mut self, replace: bool, extension: String);
200
201 fn strip_suffix(&mut self, suffix: &str);
203
204 fn generate_unique_id(&mut self);
212
213 fn prepare_type_name(&mut self);
215
216 fn prepare_field_name(&mut self);
218
219 fn prepare_content_type_name(&mut self);
221}
222
223impl NameBuilder for Box<dyn NameBuilder> {
224 #[inline]
225 fn finish(&self) -> Name {
226 (**self).finish()
227 }
228
229 #[inline]
230 fn merge(&mut self, other: &dyn NameBuilder) {
231 (**self).merge(other);
232 }
233
234 #[inline]
235 fn clone_boxed(&self) -> Box<dyn NameBuilder> {
236 (**self).clone_boxed()
237 }
238
239 #[inline]
240 fn has_name(&self) -> bool {
241 (**self).has_name()
242 }
243
244 #[inline]
245 fn has_extension(&self) -> bool {
246 (**self).has_extension()
247 }
248
249 #[inline]
250 fn set_name(&mut self, name: String) {
251 (**self).set_name(name);
252 }
253
254 #[inline]
255 fn set_with_id(&mut self, value: bool) {
256 (**self).set_with_id(value);
257 }
258
259 #[inline]
260 fn set_generated(&mut self, value: bool) {
261 (**self).set_generated(value);
262 }
263
264 #[inline]
265 fn add_extension(&mut self, replace: bool, extension: String) {
266 (**self).add_extension(replace, extension);
267 }
268
269 #[inline]
270 fn strip_suffix(&mut self, suffix: &str) {
271 (**self).strip_suffix(suffix);
272 }
273
274 #[inline]
275 fn generate_unique_id(&mut self) {
276 (**self).generate_unique_id();
277 }
278
279 #[inline]
280 fn prepare_type_name(&mut self) {
281 (**self).prepare_type_name();
282 }
283
284 #[inline]
285 fn prepare_field_name(&mut self) {
286 (**self).prepare_field_name();
287 }
288
289 #[inline]
290 fn prepare_content_type_name(&mut self) {
291 (**self).prepare_content_type_name();
292 }
293}
294
295pub trait NameBuilderExt: Sized {
297 #[must_use]
299 fn generate_id(self) -> Self;
300
301 #[must_use]
304 fn with_id(self, value: bool) -> Self;
305
306 #[must_use]
310 fn extend<I>(self, replace: bool, iter: I) -> Self
311 where
312 I: IntoIterator,
313 I::Item: Display;
314
315 #[must_use]
317 fn remove_suffix(self, suffix: &str) -> Self;
318
319 #[must_use]
324 fn unique_name<T>(self, value: T) -> Self
325 where
326 T: Display;
327
328 #[must_use]
334 fn shared_name<T>(self, value: T) -> Self
335 where
336 T: Display;
337
338 #[must_use]
340 fn or<T>(self, fallback: T) -> Self
341 where
342 T: NameFallback;
343
344 #[must_use]
346 fn or_else<F, T>(self, fallback: F) -> Self
347 where
348 F: FnOnce() -> T,
349 T: NameFallback;
350
351 #[must_use]
353 fn type_name(self) -> Self;
354
355 #[must_use]
357 fn field_name(self) -> Self;
358
359 #[must_use]
361 fn content_type_name(self) -> Self;
362}
363
364impl<X> NameBuilderExt for X
365where
366 X: NameBuilder + Sized,
367{
368 fn generate_id(mut self) -> Self {
369 self.generate_unique_id();
370
371 self
372 }
373
374 fn with_id(mut self, value: bool) -> Self {
375 self.set_with_id(value);
376
377 self
378 }
379
380 fn extend<I>(mut self, mut replace: bool, iter: I) -> Self
381 where
382 I: IntoIterator,
383 I::Item: Display,
384 {
385 for ext in iter {
386 let ext = ext.to_string();
387
388 self.add_extension(take(&mut replace), ext);
389 }
390
391 self
392 }
393
394 fn remove_suffix(mut self, suffix: &str) -> Self {
395 self.strip_suffix(suffix);
396
397 self
398 }
399
400 fn unique_name<T>(mut self, value: T) -> Self
401 where
402 T: Display,
403 {
404 self.set_name(value.to_string());
405 self.set_with_id(false);
406
407 self
408 }
409
410 fn shared_name<T>(mut self, value: T) -> Self
411 where
412 T: Display,
413 {
414 self.set_name(value.to_string());
415 self.set_with_id(true);
416
417 self
418 }
419
420 fn or<T>(self, fallback: T) -> Self
421 where
422 T: NameFallback,
423 {
424 self.or_else(|| fallback)
425 }
426
427 fn or_else<F, T>(mut self, fallback: F) -> Self
428 where
429 F: FnOnce() -> T,
430 T: NameFallback,
431 {
432 if !self.has_name() {
433 fallback().apply(&mut self);
434 }
435
436 self
437 }
438
439 fn type_name(mut self) -> Self {
440 self.prepare_type_name();
441
442 self
443 }
444
445 fn field_name(mut self) -> Self {
446 self.prepare_field_name();
447
448 self
449 }
450
451 fn content_type_name(mut self) -> Self {
452 self.prepare_content_type_name();
453
454 self
455 }
456}
457
458pub trait NameFallback {
461 fn apply(self, builder: &mut dyn NameBuilder);
463}
464
465impl NameFallback for &dyn NameBuilder {
466 fn apply(self, builder: &mut dyn NameBuilder) {
467 builder.merge(self);
468 }
469}
470
471impl NameFallback for Box<dyn NameBuilder> {
472 fn apply(self, builder: &mut dyn NameBuilder) {
473 builder.merge(&*self);
474 }
475}
476
477impl NameFallback for Name {
478 #[inline]
479 fn apply(self, builder: &mut dyn NameBuilder) {
480 (&self).apply(builder);
481 }
482}
483
484impl NameFallback for &Name {
485 #[inline]
486 fn apply(self, builder: &mut dyn NameBuilder) {
487 builder.set_name(self.as_str().to_owned());
488 builder.set_generated(self.is_generated());
489 builder.set_with_id(false);
490 }
491}
492
493impl NameFallback for Option<&Name> {
494 #[inline]
495 fn apply(self, builder: &mut dyn NameBuilder) {
496 if let Some(x) = self {
497 x.apply(builder);
498 }
499 }
500}
501
502impl NameFallback for Option<Name> {
503 #[inline]
504 fn apply(self, builder: &mut dyn NameBuilder) {
505 self.as_ref().apply(builder);
506 }
507}
508
509impl NameFallback for &Option<Name> {
510 fn apply(self, builder: &mut dyn NameBuilder) {
511 self.as_ref().apply(builder);
512 }
513}
514
515impl NameFallback for &String {
516 fn apply(self, builder: &mut dyn NameBuilder) {
517 builder.set_name(self.to_owned());
518 builder.set_with_id(false);
519 }
520}
521
522impl NameFallback for Option<&String> {
523 fn apply(self, builder: &mut dyn NameBuilder) {
524 if let Some(x) = self {
525 x.apply(builder);
526 }
527 }
528}
529
530impl NameFallback for Option<String> {
531 fn apply(self, builder: &mut dyn NameBuilder) {
532 self.as_ref().apply(builder);
533 }
534}
535
536impl NameFallback for &Option<String> {
537 fn apply(self, builder: &mut dyn NameBuilder) {
538 self.as_ref().apply(builder);
539 }
540}
541
542impl NameFallback for &str {
543 fn apply(self, builder: &mut dyn NameBuilder) {
544 builder.set_name(self.to_owned());
545 builder.set_with_id(false);
546 }
547}
548
549impl NameFallback for Option<&str> {
550 fn apply(self, builder: &mut dyn NameBuilder) {
551 if let Some(x) = self {
552 x.apply(builder);
553 }
554 }
555}