ssd_data/
lib.rs

1use serde::{Deserialize, Serialize};
2
3#[cfg(feature = "_python")]
4use pyo3::prelude::*;
5
6#[cfg(feature = "_access_functions")]
7use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
8
9use std::collections::HashMap;
10#[cfg(feature = "_access_functions")]
11use std::io::Write;
12
13pub type OrderedMap<T> = Vec<(String, T)>;
14
15#[derive(Serialize, Deserialize, Debug)]
16pub struct RawModel {
17    pub raw: serde_value::Value,
18    pub defines: HashMap<String, String>,
19}
20
21#[derive(Serialize, Deserialize, Debug)]
22pub struct SsdModel {
23    pub module: SsdModule,
24    pub defines: HashMap<String, String>,
25}
26
27#[cfg(feature = "_python")]
28macro_rules! Struct {
29    ($name: ident, $($prop_name: ident : $typ: ty),+) => {
30        #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
31        #[pyclass]
32        pub struct $name {
33            $(#[pyo3(get)] pub $prop_name: $typ),+
34        }
35    };
36}
37
38#[cfg(not(feature = "_python"))]
39macro_rules! Struct {
40    ($name: ident, $($prop_name: ident : $typ: ty),+) => {
41        #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
42        pub struct $name {
43            $(pub $prop_name: $typ),+
44        }
45    };
46}
47
48Struct!(SsdModule,
49    namespace: Namespace,
50    imports: Vec<Import>,
51    data_types: OrderedMap<DataType>,
52    enums: OrderedMap<Enum>,
53    services: OrderedMap<Service>
54);
55
56#[cfg(feature = "_python")]
57#[pymethods]
58impl SsdModule {
59    fn __repr__(&self) -> String {
60        format!("{self:?}")
61    }
62}
63
64impl SsdModule {
65    #[must_use]
66    pub fn new(
67        namespace: Namespace,
68        imports: Vec<Import>,
69        data_types: OrderedMap<DataType>,
70        enums: OrderedMap<Enum>,
71        services: OrderedMap<Service>,
72    ) -> Self {
73        Self {
74            namespace,
75            imports,
76            data_types,
77            enums,
78            services,
79        }
80    }
81}
82
83#[cfg(feature = "_access_functions")]
84impl SsdModule {
85    pub fn namespace(&mut self) -> Namespace {
86        self.namespace.clone()
87    }
88
89    pub fn imports(&mut self) -> Vec<Import> {
90        self.imports.clone()
91    }
92
93    pub fn data_types(&mut self) -> OrderedMap<DataType> {
94        self.data_types.clone()
95    }
96
97    pub fn enums(&mut self) -> OrderedMap<Enum> {
98        self.enums.clone()
99    }
100
101    pub fn services(&mut self) -> OrderedMap<Service> {
102        self.services.clone()
103    }
104}
105
106Struct!(Import,
107    path: Namespace,
108    attributes: Vec<Attribute>
109);
110
111#[cfg(feature = "_python")]
112#[pymethods]
113impl Import {
114    fn __repr__(&self) -> String {
115        format!("{self:?}")
116    }
117}
118
119impl Import {
120    #[must_use]
121    pub fn new(path: Namespace, attributes: Vec<Attribute>) -> Self {
122        Import { path, attributes }
123    }
124}
125
126#[cfg(feature = "_access_functions")]
127impl Import {
128    pub fn path(&mut self) -> Namespace {
129        self.path.clone()
130    }
131
132    pub fn attributes(&mut self) -> Vec<Attribute> {
133        self.attributes.clone()
134    }
135}
136
137Struct!(Dependency,
138    name: Namespace,
139    attributes: Vec<Attribute>,
140    comments: Vec<String>
141);
142
143#[cfg(feature = "_python")]
144#[pymethods]
145impl Dependency {
146    fn __repr__(&self) -> String {
147        format!("{self:?}")
148    }
149}
150
151impl Dependency {
152    #[must_use]
153    pub fn new(name: Namespace, attributes: Vec<Attribute>) -> Self {
154        Dependency {
155            name,
156            attributes,
157            comments: Vec::new(),
158        }
159    }
160
161    pub fn with_comments(mut self, comments: &mut Vec<String>) -> Self {
162        self.comments.append(comments);
163        self
164    }
165}
166
167#[cfg(feature = "_access_functions")]
168impl Dependency {
169    pub fn name(&mut self) -> Namespace {
170        self.name.clone()
171    }
172
173    pub fn attributes(&mut self) -> Vec<Attribute> {
174        self.attributes.clone()
175    }
176}
177
178Struct!(Parameter,
179    name: String,
180    value: Option<String>
181);
182
183#[cfg(feature = "_python")]
184#[pymethods]
185impl Parameter {
186    fn __repr__(&self) -> String {
187        format!("{self:?}")
188    }
189}
190
191#[cfg(feature = "_access_functions")]
192impl Parameter {
193    pub fn name(&mut self) -> String {
194        self.name.clone()
195    }
196
197    pub fn value(&mut self) -> Option<String> {
198        self.value.clone()
199    }
200}
201
202Struct!(Attribute,
203    name: Namespace,
204    parameters: Vec<Parameter>
205);
206
207#[cfg(feature = "_python")]
208#[pymethods]
209impl Attribute {
210    fn __repr__(&self) -> String {
211        format!("{self:?}")
212    }
213}
214
215impl Attribute {
216    #[must_use]
217    pub fn new(name: Namespace, parameters: Vec<(String, Option<String>)>) -> Self {
218        Self {
219            name,
220            parameters: parameters
221                .into_iter()
222                .map(|(name, value)| Parameter { name, value })
223                .collect(),
224        }
225    }
226}
227
228#[cfg(feature = "_access_functions")]
229impl Attribute {
230    pub fn name(&mut self) -> Namespace {
231        self.name.clone()
232    }
233
234    pub fn parameters(&mut self) -> Vec<Parameter> {
235        self.parameters.clone()
236    }
237}
238
239Struct!(DataType,
240    properties: OrderedMap<TypeName>,
241    attributes: Vec<Attribute>
242);
243
244#[cfg(feature = "_python")]
245#[pymethods]
246impl DataType {
247    fn __repr__(&self) -> String {
248        format!("{self:?}")
249    }
250}
251
252impl DataType {
253    #[must_use]
254    pub fn new(properties: OrderedMap<TypeName>, attributes: Vec<Attribute>) -> Self {
255        Self {
256            properties,
257            attributes,
258        }
259    }
260}
261
262#[cfg(feature = "_access_functions")]
263impl DataType {
264    pub fn properties(&mut self) -> OrderedMap<TypeName> {
265        self.properties.clone()
266    }
267
268    pub fn attributes(&mut self) -> Vec<Attribute> {
269        self.attributes.clone()
270    }
271}
272
273Struct!(Enum,
274    values: OrderedMap<EnumValue>,
275    attributes: Vec<Attribute>
276);
277
278#[cfg(feature = "_python")]
279#[pymethods]
280impl Enum {
281    fn __repr__(&self) -> String {
282        format!("{self:?}")
283    }
284}
285
286impl Enum {
287    #[must_use]
288    pub fn new(values: OrderedMap<EnumValue>, attributes: Vec<Attribute>) -> Self {
289        Self { values, attributes }
290    }
291}
292
293#[cfg(feature = "_access_functions")]
294impl Enum {
295    pub fn values(&mut self) -> OrderedMap<EnumValue> {
296        self.values.clone()
297    }
298
299    pub fn attributes(&mut self) -> Vec<Attribute> {
300        self.attributes.clone()
301    }
302}
303
304Struct!(Service,
305    dependencies: Vec<Dependency>,
306    functions: OrderedMap<Function>,
307    events: OrderedMap<Event>,
308    attributes: Vec<Attribute>
309);
310
311#[cfg(feature = "_python")]
312#[pymethods]
313impl Service {
314    fn __repr__(&self) -> String {
315        format!("{self:?}")
316    }
317}
318
319impl Service {
320    #[must_use]
321    pub fn new(
322        dependencies: Vec<Dependency>,
323        functions: OrderedMap<Function>,
324        events: OrderedMap<Event>,
325        attributes: Vec<Attribute>,
326    ) -> Self {
327        Self {
328            dependencies,
329            functions,
330            events,
331            attributes,
332        }
333    }
334}
335
336#[cfg(feature = "_access_functions")]
337impl Service {
338    pub fn dependencies(&mut self) -> Vec<Dependency> {
339        self.dependencies.clone()
340    }
341
342    pub fn functions(&mut self) -> OrderedMap<Function> {
343        self.functions.clone()
344    }
345
346    pub fn handlers(&mut self) -> OrderedMap<Function> {
347        const DEPRECATED: &str =  "Using the property 'handlers' is deprecated and will be removed in future versions. Use 'functions' instead.";
348        let mut stderr = StandardStream::stderr(ColorChoice::Always);
349        if stderr
350            .set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))
351            .is_ok()
352        {
353            writeln!(&mut stderr, "{}", DEPRECATED).unwrap();
354
355            let _ = stderr.set_color(&ColorSpec::default());
356        } else {
357            eprintln!("{}", DEPRECATED);
358        }
359        self.functions()
360    }
361
362    pub fn events(&mut self) -> OrderedMap<Event> {
363        self.events.clone()
364    }
365
366    pub fn attributes(&mut self) -> Vec<Attribute> {
367        self.attributes.clone()
368    }
369}
370
371Struct!(Function,
372    arguments: OrderedMap<TypeName>,
373    return_type: Option<TypeName>,
374    attributes: Vec<Attribute>,
375    comments: Vec<String>
376);
377
378#[cfg(feature = "_python")]
379#[pymethods]
380impl Function {
381    fn __repr__(&self) -> String {
382        format!("{self:?}")
383    }
384}
385
386impl Function {
387    #[must_use]
388    pub fn new(
389        arguments: OrderedMap<TypeName>,
390        return_type: Option<TypeName>,
391        attributes: Vec<Attribute>,
392    ) -> Self {
393        Self {
394            arguments,
395            return_type,
396            attributes,
397            comments: Vec::new(),
398        }
399    }
400
401    pub fn with_comments(mut self, comments: &mut Vec<String>) -> Self {
402        self.comments.append(comments);
403        self
404    }
405}
406
407#[cfg(feature = "_access_functions")]
408impl Function {
409    pub fn arguments(&mut self) -> OrderedMap<TypeName> {
410        self.arguments.clone()
411    }
412
413    pub fn return_type(&mut self) -> Option<TypeName> {
414        self.return_type.clone()
415    }
416
417    pub fn attributes(&mut self) -> Vec<Attribute> {
418        self.attributes.clone()
419    }
420}
421
422Struct!(Event,
423    arguments: OrderedMap<TypeName>,
424    attributes: Vec<Attribute>,
425    comments: Vec<String>
426);
427
428#[cfg(feature = "_python")]
429#[pymethods]
430impl Event {
431    fn __repr__(&self) -> String {
432        format!("{self:?}")
433    }
434}
435
436impl Event {
437    #[must_use]
438    pub fn new(arguments: OrderedMap<TypeName>, attributes: Vec<Attribute>) -> Self {
439        Self {
440            arguments,
441            attributes,
442            comments: Vec::new(),
443        }
444    }
445
446    pub fn with_comments(mut self, comments: &mut Vec<String>) -> Self {
447        self.comments.append(comments);
448        self
449    }
450}
451
452#[cfg(feature = "_access_functions")]
453impl Event {
454    pub fn arguments(&mut self) -> OrderedMap<TypeName> {
455        self.arguments.clone()
456    }
457
458    pub fn attributes(&mut self) -> Vec<Attribute> {
459        self.attributes.clone()
460    }
461}
462
463Struct!(TypeName,
464    typ: Namespace,
465    is_list: bool,
466    count: Option<usize>,
467    attributes: Vec<Attribute>,
468    comments: Vec<String>
469);
470
471#[cfg(feature = "_python")]
472#[pymethods]
473impl TypeName {
474    fn __repr__(&self) -> String {
475        format!("{self:?}")
476    }
477}
478
479impl TypeName {
480    #[must_use]
481    pub fn new(
482        typ: Namespace,
483        is_list: bool,
484        count: Option<usize>,
485        attributes: Vec<Attribute>,
486    ) -> Self {
487        Self {
488            typ,
489            is_list,
490            count,
491            attributes,
492            comments: Vec::new(),
493        }
494    }
495
496    pub fn with_comments(mut self, comments: &mut Vec<String>) -> Self {
497        self.comments.append(comments);
498        self
499    }
500}
501
502#[cfg(feature = "_access_functions")]
503impl TypeName {
504    pub fn typ(&mut self) -> Namespace {
505        self.typ.clone()
506    }
507
508    pub fn is_list(&mut self) -> bool {
509        self.is_list
510    }
511
512    pub fn count(&mut self) -> Option<usize> {
513        self.count
514    }
515
516    pub fn attributes(&mut self) -> Vec<Attribute> {
517        self.attributes.clone()
518    }
519}
520
521Struct!(EnumValue,
522    value: Option<i64>,
523    attributes: Vec<Attribute>,
524    comments: Vec<String>
525);
526
527#[cfg(feature = "_python")]
528#[pymethods]
529impl EnumValue {
530    fn __repr__(&self) -> String {
531        format!("{self:?}")
532    }
533}
534
535impl EnumValue {
536    #[must_use]
537    pub fn new(value: Option<i64>, attributes: Vec<Attribute>) -> Self {
538        Self {
539            value,
540            attributes,
541            comments: Vec::new(),
542        }
543    }
544
545    pub fn with_comments(mut self, comments: &mut Vec<String>) -> Self {
546        self.comments.append(comments);
547        self
548    }
549}
550
551#[cfg(feature = "_access_functions")]
552impl EnumValue {
553    pub fn value(&mut self) -> Option<i64> {
554        self.value
555    }
556
557    pub fn attributes(&mut self) -> Vec<Attribute> {
558        self.attributes.clone()
559    }
560}
561
562Struct!(Namespace,
563    components: Vec<String>
564);
565
566impl IntoIterator for Namespace {
567    type Item = String;
568
569    type IntoIter = std::vec::IntoIter<Self::Item>;
570
571    fn into_iter(self) -> Self::IntoIter {
572        self.components.into_iter()
573    }
574}
575
576#[cfg(feature = "_python")]
577#[pymethods]
578impl Namespace {
579    fn __repr__(&self) -> String {
580        format!("{self:?}")
581    }
582}
583
584impl Namespace {
585    #[must_use]
586    pub fn new(v: &str) -> Self {
587        Namespace {
588            components: v.split("::").map(ToOwned::to_owned).collect(),
589        }
590    }
591
592    #[must_use]
593    pub fn from_vec(components: Vec<String>) -> Self {
594        Namespace { components }
595    }
596}
597
598#[cfg(feature = "_access_functions")]
599impl Namespace {
600    pub fn components(&mut self) -> Vec<String> {
601        self.components.clone()
602    }
603}
604
605impl ToString for Namespace {
606    fn to_string(&self) -> String {
607        self.components.join("::")
608    }
609}