xsd_parser/generator/
context.rs1use std::{
2 any::{Any, TypeId},
3 collections::HashMap,
4 ops::Deref,
5};
6
7use parking_lot::Mutex;
8use proc_macro2::{Ident as Ident2, TokenStream};
9use quote::format_ident;
10
11use crate::{
12 code::{IdentPath, Module, ModulePath},
13 schema::NamespaceId,
14 types::Ident,
15};
16
17use super::{Config, GeneratorFlags};
18
19#[derive(Debug)]
25pub struct Context<'a, 'types> {
26 ident: &'a Ident,
27 config: &'a Config<'types>,
28 module: Mutex<&'a mut Module>,
29
30 module_path: ModulePath,
31 serialize_module_path: ModulePath,
32 deserialize_module_path: ModulePath,
33
34 values: HashMap<TypeId, Box<dyn Any>>,
35}
36
37pub trait ValueKey: Any {
38 type Type: Any + Clone;
39}
40
41impl<'a, 'types> Context<'a, 'types> {
42 pub fn current_ns(&self) -> Option<NamespaceId> {
44 self.check_flags(GeneratorFlags::USE_MODULES)
45 .then_some(self.ident.ns)
46 .flatten()
47 }
48
49 pub fn resolve_type_for_module(&self, ident: &IdentPath) -> TokenStream {
51 ident.relative_to(&self.module_path)
52 }
53
54 pub fn add_usings<I>(&self, usings: I)
56 where
57 I: IntoIterator,
58 I::Item: ToString,
59 {
60 let mut root = self.module.lock();
61 Self::main_module(self.module_path.last(), &mut root).usings(usings);
62 }
63
64 pub fn module(&mut self) -> &mut Module {
66 let root = self.module.get_mut();
67
68 Self::main_module(self.module_path.last(), root)
69 }
70
71 pub fn set<K>(&mut self, value: K::Type)
73 where
74 K: ValueKey,
75 {
76 self.values.insert(TypeId::of::<K>(), Box::new(value));
77 }
78
79 pub fn get<K>(&self) -> K::Type
83 where
84 K: ValueKey,
85 {
86 self.values
87 .get(&TypeId::of::<K>())
88 .unwrap()
89 .downcast_ref::<K::Type>()
90 .unwrap()
91 .clone()
92 }
93
94 pub fn unset<K>(&mut self)
96 where
97 K: ValueKey,
98 {
99 self.values.remove(&TypeId::of::<K>());
100 }
101
102 pub(crate) fn resolve_type_for_serialize_module(&self, ident: &IdentPath) -> TokenStream {
103 ident.relative_to(&self.serialize_module_path)
104 }
105
106 pub(crate) fn resolve_type_for_deserialize_module(&self, ident: &IdentPath) -> TokenStream {
107 ident.relative_to(&self.deserialize_module_path)
108 }
109
110 pub(crate) fn quick_xml_serialize(&mut self) -> &mut Module {
111 self.module().module_mut("quick_xml_serialize")
112 }
113
114 pub(crate) fn quick_xml_deserialize(&mut self) -> &mut Module {
115 self.module().module_mut("quick_xml_deserialize")
116 }
117
118 pub(crate) fn add_quick_xml_serialize_usings<I>(&self, usings: I)
119 where
120 I: IntoIterator,
121 I::Item: ToString,
122 {
123 let mut root = self.module.lock();
124 Self::main_module(self.module_path.last(), &mut root)
125 .module_mut("quick_xml_serialize")
126 .usings(usings);
127 }
128
129 pub(crate) fn add_quick_xml_deserialize_usings<I>(&self, usings: I)
130 where
131 I: IntoIterator,
132 I::Item: ToString,
133 {
134 let mut root = self.module.lock();
135 Self::main_module(self.module_path.last(), &mut root)
136 .module_mut("quick_xml_deserialize")
137 .usings(usings);
138 }
139
140 pub(super) fn new(
141 ident: &'a Ident,
142 config: &'a Config<'types>,
143 module: &'a mut Module,
144 ) -> Self {
145 let ns = config
146 .check_flags(GeneratorFlags::USE_MODULES)
147 .then_some(ident.ns)
148 .flatten();
149 let module_path = ModulePath::from_namespace(ns, config.types);
150 let serialize_module_path = module_path
151 .clone()
152 .join(format_ident!("quick_xml_serialize"));
153 let deserialize_module_path = module_path
154 .clone()
155 .join(format_ident!("quick_xml_deserialize"));
156
157 Self {
158 ident,
159 config,
160 module: Mutex::new(module),
161
162 module_path,
163 serialize_module_path,
164 deserialize_module_path,
165
166 values: HashMap::new(),
167 }
168 }
169
170 fn main_module<'x>(ident: Option<&Ident2>, root: &'x mut Module) -> &'x mut Module {
171 if let Some(ident) = ident {
172 root.module_mut(ident.to_string())
173 } else {
174 root
175 }
176 }
177}
178
179impl<'types> Deref for Context<'_, 'types> {
180 type Target = Config<'types>;
181
182 fn deref(&self) -> &Self::Target {
183 self.config
184 }
185}