1#![warn(missing_docs)]
18
19use proc_macro::TokenStream;
20use quote::quote;
21use syn::{parse_macro_input, Data, DeriveInput};
22
23#[proc_macro_derive(HasId)]
26pub fn hasid_derive(input: TokenStream) -> TokenStream {
27 let input = parse_macro_input!(input as DeriveInput);
28
29 let fields = match input.data {
30 Data::Struct(s) => s
31 .fields
32 .into_iter()
33 .map(|f| f.ident.unwrap().to_string())
34 .collect::<Vec<_>>(),
35 _ => panic!("HasId only supports Struct"),
36 };
37 let name = input.ident;
38 let _id = fields
40 .iter()
41 .find(|s| *s == "id")
42 .expect("No id field present");
43 let _href = fields
44 .iter()
45 .find(|s| *s == "href")
46 .expect("No href field present");
47 let out = quote! {
50
51 impl HasId for #name {
52 fn generate_id(&mut self) {
53 let id = #name::get_uuid();
54 self.id = id.into();
55 self.generate_href();
56 }
57 fn generate_href(&mut self) {
58 let href = format!("{}/{}",#name::get_class_href(),self.get_id());
59 self.href = href.into();
60 }
61 fn get_id(&self) -> String {
62 match self.id.as_ref() {
63 Some(i) => i.clone(),
64 None => String::default(),
65 }
66 }
67 fn get_href(&self) -> String {
68 match self.href.as_ref() {
69 Some(h) => h.clone(),
70 None => String::default(),
71 }
72 }
73 fn get_class() -> String {
74 CLASS_PATH.to_string()
75 }
76 fn get_class_href() -> String {
77 format!("/{}/{}/{}",crate::get_lib_path(),MOD_PATH,#name::get_class())
78 }
79 fn get_mod_path() -> String {
80 format!("/{}/{}",crate::get_lib_path(),MOD_PATH)
81 }
82 fn set_id(&mut self, id : impl Into<String>) {
83 self.id = Some(id.into());
84 self.generate_href();
86 }
87
88 fn id(mut self, id : impl Into<String>) -> Self {
89 self.set_id(id);
90 self
91 }
92 }
93 };
94 out.into()
95}
96
97#[proc_macro_derive(HasAttachment)]
99pub fn hasattachment_derive(input: TokenStream) -> TokenStream {
100 let input = parse_macro_input!(input as DeriveInput);
101 let fields = match input.data {
102 Data::Struct(s) => s
103 .fields
104 .into_iter()
105 .map(|f| f.ident.unwrap().to_string())
106 .collect::<Vec<_>>(),
107 _ => panic!("HasAttachments only supports Struct"),
108 };
109 let _last_update = fields
110 .iter()
111 .find(|s| *s == "attachment")
112 .expect("No attachment field present");
113 let name = input.ident;
114 let out = quote! {
115 impl HasAttachment for #name {
116 fn add(&mut self, attachment : &AttachmentRefOrValue) {
117 match self.attachment.as_mut() {
118 Some(v) => {
119 v.push(attachment.clone());
120 }
121 None => {
122 self.attachment = Some(vec![attachment.clone()]);
123 }
124 }
125 }
126 fn position(&self, name : impl Into<String>) -> Option<usize> {
127 match self.attachment.as_ref() {
128 Some(v) => {
129 let pattern : String = name.into();
130 v.iter().position(|a| a.name == Some(pattern.clone()))
131 }
132 None => None,
133 }
134 }
135 fn find(&self, name : impl Into<String>) -> Option<&AttachmentRefOrValue> {
136 match self.attachment.as_ref() {
137 Some(v) => {
138 let pattern : String = name.into();
139 v.iter().find(|a| a.name == Some(pattern.clone()))
140 },
141 None => None,
142 }
143 }
144 fn get(&self, position: usize) -> Option<AttachmentRefOrValue> {
145 match self.attachment.as_ref() {
146 Some(v) => {
147 v.get(position).cloned()
148 },
149 None => None,
150 }
151 }
152 fn remove(&mut self, position : usize) -> Option<AttachmentRefOrValue> {
153 match self.attachment.as_mut() {
154 Some(v) => {
155 Some(v.remove(position))
156 },
157 None => None,
158 }
159 }
160
161 fn attachment(mut self, attachment : AttachmentRefOrValue) -> Self {
162 self.add(&attachment);
163 self
164 }
165 }
166 };
167 out.into()
168}
169
170#[proc_macro_derive(HasLastUpdate)]
172pub fn haslastupdate_derive(input: TokenStream) -> TokenStream {
173 let input = parse_macro_input!(input as DeriveInput);
174 let fields = match input.data {
175 Data::Struct(s) => s
176 .fields
177 .into_iter()
178 .map(|f| f.ident.unwrap().to_string())
179 .collect::<Vec<_>>(),
180 _ => panic!("HasId only supports Struct"),
181 };
182 let _last_update = fields
183 .iter()
184 .find(|s| *s == "last_update")
185 .expect("No last_update field present");
186 let name = input.ident;
187 let out = quote! {
188 impl HasLastUpdate for #name {
189 fn set_last_update(&mut self, time : impl Into<String>) {
190 self.last_update = Some(time.into());
191 }
192
193 fn get_last_update(&self) -> Option<String> {
194 self.last_update.clone()
195 }
196
197 fn last_update(mut self, time : Option<String>) -> Self {
198 match time {
199 Some(t) => self.set_last_update(t),
200 None => self.set_last_update(Self::get_timestamp()),
201 };
202 self
203 }
204 }
205 };
206 out.into()
207}
208
209#[proc_macro_derive(HasName)]
211pub fn hasname_derive(input: TokenStream) -> TokenStream {
212 let input = parse_macro_input!(input as DeriveInput);
213 let fields = match input.data {
214 Data::Struct(s) => s
215 .fields
216 .into_iter()
217 .map(|f| f.ident.unwrap().to_string())
218 .collect::<Vec<_>>(),
219 _ => panic!("HasId only supports Struct"),
220 };
221 let name = input.ident;
222 let _name = fields
224 .iter()
225 .find(|s| *s == "name")
226 .expect("No name field present");
227 let out = quote! {
228 impl HasName for #name {
229 fn get_name(&self) -> String {
230 self.name.clone().unwrap_or("NoName".to_string())
231 }
232 fn set_name(&mut self, name : impl Into<String>) {
233 self.name = Some(name.into().trim().to_string());
234 }
235 fn name(mut self, name :impl Into<String>) -> Self {
236 self.set_name(name);
237 self
238 }
239 }
240 };
241 out.into()
242}
243
244#[proc_macro_derive(HasNote)]
246pub fn hasnote_derive(input: TokenStream) -> TokenStream {
247 let input = parse_macro_input!(input as DeriveInput);
248 let fields = match input.data {
249 Data::Struct(s) => s
250 .fields
251 .into_iter()
252 .map(|f| f.ident.unwrap().to_string())
253 .collect::<Vec<_>>(),
254 _ => panic!("HasId only supports Struct"),
255 };
256 let name = input.ident;
257 let _note = fields
259 .iter()
260 .find(|s| *s == "note")
261 .expect("No note field present");
262 let out = quote! {
263 impl HasNote for #name {
264 fn add_note(&mut self, note : Note) {
265 match self.note.as_mut() {
266 Some(v) => v.push(note),
267 None => self.note = Some(vec![note]),
268 }
269 }
270 fn get_note(&self, idx : usize) -> Option<&Note> {
271 match self.note.as_ref() {
272 Some(n) => n.get(idx),
273 None => None,
274 }
275 }
276 fn remove_note(&mut self, idx: usize) -> Result<Note,TMFError> {
277 match self.note.as_mut() {
278 Some(n) => Ok(n.remove(idx)),
279 None => Err(TMFError::NoDataError("No notes present".to_string())),
280 }
281 }
282 fn note(mut self, note : Note) -> Self {
283 self.add_note(note);
284 self
285 }
286 }
287 };
288 out.into()
289}
290
291#[proc_macro_derive(HasRelatedParty)]
293pub fn hasrelatedparty_derive(input: TokenStream) -> TokenStream {
294 let input = parse_macro_input!(input as DeriveInput);
295 let fields = match input.data {
296 Data::Struct(s) => s
297 .fields
298 .into_iter()
299 .map(|f| f.ident.unwrap().to_string())
300 .collect::<Vec<_>>(),
301 _ => panic!("HasRelatedParty only supports Struct"),
302 };
303 let name = input.ident;
304 let _related_party: &String = fields
306 .iter()
307 .find(|s| *s == "related_party")
308 .expect("No related_party field present");
309 let out = quote! {
310 impl HasRelatedParty for #name {
311 fn add_party(&mut self, party : RelatedParty) {
312 match self.related_party.as_mut() {
313 Some(v) => v.push(party),
314 None => self.related_party = Some(vec![party]),
315 }
316 }
317 fn get_party(&self, idx : usize ) -> Option<&RelatedParty> {
318 match self.related_party.as_ref() {
319 Some(rp) => {
320 rp.get(idx)
322 },
323 None => None,
324 }
325
326 }
327 fn remove_party(&mut self, idx : usize) -> Result<RelatedParty,TMFError> {
328 match self.related_party.as_mut() {
329 None => Err(TMFError::NoDataError("No related parties present".to_string())),
330 Some(rp) => {
331 Ok(rp.remove(idx))
332 }
333 }
334 }
335 fn get_by_role(&self, role : String) -> Option<Vec<&RelatedParty>> {
336 match &self.related_party {
337 Some(rp) => {
338 let out = rp.iter()
339 .filter(|p| p.role.is_some())
340 .filter(|p| p.role.clone().unwrap() == role)
341 .collect();
342 Some(out)
343 },
344 None => None,
345 }
346 }
347
348 fn party(mut self, party : RelatedParty) -> Self {
349 self.add_party(party);
350 self
351 }
352 }
353 };
354 out.into()
355}
356
357#[proc_macro_derive(HasDescription)]
359pub fn hasdescription_derive(input: TokenStream) -> TokenStream {
360 let input = parse_macro_input!(input as DeriveInput);
361 let fields = match input.data {
362 Data::Struct(s) => s
363 .fields
364 .into_iter()
365 .map(|f| f.ident.unwrap().to_string())
366 .collect::<Vec<_>>(),
367 _ => panic!("HasValidity only supports Struct"),
368 };
369 let name = input.ident;
370 let _name = fields
372 .iter()
373 .find(|s| *s == "description")
374 .expect("No description field found");
375
376 let out = quote! {
377 impl HasDescription for #name {
378 fn description(mut self, description : impl Into<String>) -> Self {
379 self.description = Some(description.into());
380 self
381 }
382 fn get_description(&self) -> String {
383 match self.description.as_ref() {
384 Some(d) => d.clone(),
385 None => String::default(),
386 }
387 }
388 fn set_description(&mut self, description : impl Into<String>) -> Option<String> {
389 self.description.replace(description.into())
390 }
391 }
392 };
393 out.into()
394}
395
396#[proc_macro_derive(HasValidity)]
398pub fn hasvalidity_derive(input: TokenStream) -> TokenStream {
399 let input = parse_macro_input!(input as DeriveInput);
400 let fields = match input.data {
401 Data::Struct(s) => s
402 .fields
403 .into_iter()
404 .map(|f| f.ident.unwrap().to_string())
405 .collect::<Vec<_>>(),
406 _ => panic!("HasValidity only supports Struct"),
407 };
408 let name = input.ident;
409 let _name = fields
411 .iter()
412 .find(|s| *s == "valid_for")
413 .expect("No valid_for object present");
414 let out = quote! {
415 impl HasValidity for #name {
416 fn get_validity(&self) -> Option<TimePeriod> {
417 self.valid_for.clone()
418 }
419 fn get_validity_end(&self) -> Option<crate::TimeStamp> {
420 match self.valid_for.as_ref() {
421 Some(v) => v.end_date_time.clone(),
422 None => None,
423 }
424 }
425 fn get_validity_start(&self) -> Option<crate::TimeStamp> {
426 match self.valid_for.as_ref() {
427 Some(v) => Some(v.start_date_time.clone()),
428 None => None,
429 }
430 }
431 fn set_validity(&mut self, validity : TimePeriod) {
432 self.valid_for = Some(validity);
433 }
434 fn set_validity_end(&mut self, end : crate::TimeStamp) -> TimePeriod {
435 let mut validity = match self.get_validity() {
436 Some(v) => v,
437 None => TimePeriod::default(),
438 };
439 validity.end_date_time = Some(end);
440 self.set_validity(validity.clone());
441 validity
442 }
443 fn set_validity_start(&mut self, start : crate::TimeStamp) -> TimePeriod {
444 let mut validity = match self.get_validity() {
445 Some(v) => v,
446 None => TimePeriod::default(),
447 };
448 validity.start_date_time = start;
449 self.set_validity(validity.clone());
450 validity
451 }
452 fn is_valid(&self) -> bool {
453 let validity = self.get_validity();
454 match validity {
455 Some(v) => {
456 if v.started() && !v.finished() {
457 return true
458 }
459 false
460 },
461 None => false
462 }
463 }
464
465 fn validity(mut self, validity : TimePeriod) -> Self {
466 self.set_validity(validity);
467 self
468 }
469 }
470 };
471 out.into()
472}