xsd_parser/types/
custom.rs1use std::fmt::{Debug, Formatter, Result as FmtResult};
4use std::hash::{Hash, Hasher};
5
6use proc_macro2::TokenStream;
7
8pub struct CustomType {
10 name: &'static str,
11 default: Option<Box<dyn CustomDefaultImpl>>,
12}
13
14impl CustomType {
15 #[must_use]
17 pub fn new(name: &'static str) -> Self {
18 Self {
19 name,
20 default: None,
21 }
22 }
23
24 #[must_use]
26 pub fn name(&self) -> &'static str {
27 self.name
28 }
29
30 #[must_use]
35 pub fn default(&self, s: &str) -> Option<TokenStream> {
36 self.default.as_ref()?.exec(s)
37 }
38
39 #[must_use]
41 pub fn with_default<X: CustomDefaultImpl>(mut self, x: X) -> Self {
42 self.default = Some(Box::new(x));
43
44 self
45 }
46}
47
48impl Clone for CustomType {
49 fn clone(&self) -> Self {
50 Self {
51 name: self.name,
52 default: self
53 .default
54 .as_ref()
55 .map(|x| CustomDefaultImpl::clone(&**x)),
56 }
57 }
58}
59
60impl Debug for CustomType {
61 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
62 f.debug_struct("CustomType")
63 .field("name", &self.name)
64 .field("default", &self.default.is_some())
65 .finish()
66 }
67}
68
69impl Eq for CustomType {}
70
71impl PartialEq for CustomType {
72 fn eq(&self, other: &Self) -> bool {
73 self.name.eq(other.name)
74 }
75}
76
77impl Hash for CustomType {
78 fn hash<H: Hasher>(&self, state: &mut H) {
79 self.name.hash(state);
80 }
81}
82
83pub trait CustomDefaultImpl: 'static {
89 fn exec(&self, s: &str) -> Option<TokenStream>;
93
94 fn clone(&self) -> Box<dyn CustomDefaultImpl>;
96}
97
98impl<X> CustomDefaultImpl for X
99where
100 X: Fn(&str) -> Option<TokenStream> + Clone + 'static,
101{
102 fn exec(&self, s: &str) -> Option<TokenStream> {
103 (*self)(s)
104 }
105
106 fn clone(&self) -> Box<dyn CustomDefaultImpl> {
107 Box::new(self.clone())
108 }
109}