sdml_json/write/
mod.rs

1/*!
2This module provides SDML to JSON Value functions for the entire model.
3
4# Model Representation in JSON
5
6# Template Context
7
8Note that the created context values *are not* intended as a direct 1:1 representation of either the
9published surface syntax grammar or the Rust model. The form is simplified for use in the template
10language using the following guidelines.
11
121. Reduce layers in the model that do not add value; i.e. [Identifier` in the Rust model has an
13   inner `value` field.
142. Where an `Option<T>` field is `None` do not add a key in the generated object.
153. Where a `Vec<T>` field `is_empty` do not add a key in the generated object.
164. Use the key `"__type"` as a discriminator where the content of an object is ambiguous, especially
17   in arrays.
185. Only add `source_span` values for major objects such as definitions, not for individual names
19   etc.
20
21The upshot of this is that an `if` statement in a template is used to check for presence of a value
22before you use it. The following demonstrates this pattern for optional fields and  possibly empty
23collections.
24
25```md
26{% if module.base_uri -%}
27 *Base URI*: {{ module.base_uri }}
28{%- endif %}
29
30{% if module.annotations -%}
31  {% for ann in module.annotations -%}
32    {{ ann.name }}
33  {%- endfor %}
34{%- endif %}
35```
36
37 */
38
39use sdml_core::{
40    config::is_library_module,
41    model::{
42        annotations::{Annotation, AnnotationOnlyBody, AnnotationProperty, HasAnnotations},
43        constraints::{
44            AtomicSentence, BinaryBooleanSentence, BooleanSentence, ConnectiveOperator, Constraint,
45            ConstraintBody, ConstraintSentence, ControlledLanguageString, Equation,
46            FormalConstraint, FunctionBody, FunctionCardinality, FunctionComposition, FunctionDef,
47            FunctionParameter, FunctionSignature, FunctionType, FunctionTypeReference,
48            FunctionalTerm, InequalityRelation, Inequation, PredicateSequenceMember,
49            PredicateValue, QuantifiedSentence, QuantifiedVariable, QuantifiedVariableBinding,
50            SequenceBuilder, SequenceOfPredicateValues, SimpleSentence, Subject, Term,
51            UnaryBooleanSentence, Variable,
52        },
53        definitions::{
54            DatatypeDef, Definition, DimensionBody, DimensionDef, DimensionIdentity,
55            DimensionParent, EntityBody, EntityDef, EnumBody, EnumDef, EventBody, EventDef,
56            MethodDef, PropertyDef, RdfDef, RestrictionFacet, SourceEntity, StructureBody,
57            StructureDef, TypeClassArgument, TypeClassBody, TypeClassDef, TypeClassReference,
58            TypeVariable, TypeVariant, UnionBody, UnionDef, ValueVariant,
59        },
60        identifiers::{Identifier, IdentifierReference, QualifiedIdentifier},
61        members::{Cardinality, MappingType, Member, MemberDef, MemberKind, TypeReference},
62        modules::{Import, ImportStatement, MemberImport, Module, ModuleImport, ModulePath},
63        values::{
64            MappingValue, SequenceMember, SequenceOfValues, SimpleValue, Value as SdmlValue,
65            ValueConstructor,
66        },
67        HasBody, HasName, HasNameReference, HasOptionalBody, HasSourceSpan, Span,
68    },
69    store::ModuleStore,
70    syntax::*,
71};
72use sdml_errors::Error;
73use serde_json::{Map, Number, Value};
74use std::io::{Cursor, Write};
75
76// ------------------------------------------------------------------------------------------------
77// Macros -- only here for the ToJson definition
78// ------------------------------------------------------------------------------------------------
79
80macro_rules! new_map {
81    () => {{
82        let map: Map<String, Value> = Map::default();
83        map
84    }};
85    ($capacity:expr) => {{
86        let map: Map<String, Value> = Map::with_capacity($capacity);
87        map
88    }};
89}
90
91// ------------------------------------------------------------------------------------------------
92// Public Types
93// ------------------------------------------------------------------------------------------------
94
95#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
96pub struct ValueOptions {
97    context_only: bool,
98    include_spans: bool,
99}
100
101#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
102pub struct WriteOptions {
103    values: ValueOptions,
104    pretty_print: bool,
105}
106
107pub trait ToJson {
108    fn to_json_with(&self, opts: ValueOptions) -> Value {
109        let mut value_map = new_map!();
110        self.add_to_json_with(&mut value_map, opts);
111        value_map.into()
112    }
113    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions);
114}
115
116// ------------------------------------------------------------------------------------------------
117// Macros
118// ------------------------------------------------------------------------------------------------
119
120macro_rules! set {
121    ($obj:expr, $opts:expr, name => $named:expr) => {
122        set!($obj, FIELD_NAME_NAME => $named.name().to_json_with($opts));
123    };
124    ($obj:expr, $opts:expr, nameref => $named:expr) => {
125        set!($obj, FIELD_NAME_NAME => $named.name_reference().to_json_with($opts));
126    };
127    ($obj:expr, $key:expr => $value:expr) => {
128        $obj.insert($key.into(), Value::from($value));
129    };
130    (unless $test:expr ; $obj:expr => $meta_type:expr) => {
131        if !$test {
132            set!($obj, KEY_META_TYPE => $meta_type);
133        }
134    };
135    ($obj:expr => $meta_type:expr) => {
136        set!($obj, KEY_META_TYPE => $meta_type);
137    };
138}
139
140macro_rules! set_source_span {
141    ($spanned:expr, $obj:expr, $opts:expr, $if:expr) => {
142        if $if {
143            set_source_span!($spanned, $obj, $opts);
144        }
145    };
146    ($spanned:expr, $obj:expr, $opts:expr) => {
147        if $opts.include_spans {
148            if let Some(source_span) = $spanned.source_span() {
149                set!($obj, FIELD_NAME_SPAN => source_span.to_json_with($opts));
150            }
151        }
152    };
153}
154
155macro_rules! set_variant {
156    ($obj:expr, $opts:expr => $enum_type:expr) => {
157        if !$opts.context_only {
158            set!($obj => $enum_type);
159        }
160    };
161    ($obj:expr, $opts:expr => $variant:expr, $var_type:expr) => {
162        if $opts.context_only {
163            $variant.add_to_json_with($obj, $opts);
164        } else {
165            let mut inner_map = new_map!();
166            $variant.add_to_json_with(&mut inner_map, $opts);
167            set!($obj, $var_type => inner_map);
168        }
169    };
170}
171
172macro_rules! add_enum {
173    ($me:expr, $obj:expr, $opts:expr => $enum_type:expr $( ; $var_name:ident => $var_type:expr )+) => {
174        set_variant!($obj, $opts => $enum_type);
175        match $me {
176            $(
177            Self::$var_name(v) => set_variant!($obj, $opts => v, $var_type),
178            )+
179        }
180    };
181    ($me:expr, $obj:expr, $opts:expr => $enum_type:expr
182     $( ; $var_name:ident => $var_type:expr )+ ; ! $bool_var_name:ident => $bool_var_type:expr) => {
183        set_variant!($obj, $opts => $enum_type);
184        match $me {
185            $(
186            Self::$var_name(v) => set_variant!($obj, $opts => v, $var_type),
187            )+
188            Self::$bool_var_name => {
189                set!($obj, $bool_var_type => true);
190            }
191        }
192    };
193}
194
195macro_rules! add_body {
196    ($obj:expr, $opts:expr, $thing:expr) => {
197        if let Some(body) = $thing.body() {
198            if $opts.context_only {
199                body.add_to_json_with($obj, $opts);
200            } else {
201                set!($obj, FIELD_NAME_BODY => body.to_json_with($opts));
202            }
203        }
204    };
205}
206
207macro_rules! add_collection {
208    ($obj:expr, $opts:expr, $thing:expr, $has_things:ident, $things:ident, $name:expr) => {
209        if $thing.$has_things() {
210            let $things = $thing
211                .$things()
212                .map(|thing| thing.to_json_with($opts))
213                .collect::<Vec<Value>>();
214            set!($obj, $name => $things);
215        }
216    };
217}
218
219macro_rules! add_annotations {
220    ($obj:expr, $opts:expr, $annotated:expr) => {
221        add_collection!(
222            $obj,
223            $opts,
224            $annotated,
225            has_annotations,
226            annotations,
227            FIELD_NAME_ANNOTATIONS
228        );
229    };
230}
231
232// ------------------------------------------------------------------------------------------------
233// Public Names
234// ------------------------------------------------------------------------------------------------
235
236const KEY_META_TYPE: &str = "__type";
237
238const JSON_FIELD_NAME_DEFINITIONS: &str = "definitions";
239
240// ------------------------------------------------------------------------------------------------
241// Public Functions
242// ------------------------------------------------------------------------------------------------
243
244#[inline]
245pub fn write_module<W>(w: &mut W, module: &Module, cache: &impl ModuleStore) -> Result<(), Error>
246where
247    W: Write,
248{
249    write_module_with_options(w, module, cache, Default::default())
250}
251
252pub fn write_module_with_options<W>(
253    w: &mut W,
254    module: &Module,
255    _: &impl ModuleStore,
256    options: WriteOptions,
257) -> Result<(), Error>
258where
259    W: Write,
260{
261    let value = module_to_value(module, options.values);
262    if options.pretty_print {
263        Ok(serde_json::to_writer_pretty(w, &value).map_err(into_generator_error)?)
264    } else {
265        Ok(serde_json::to_writer(w, &value).map_err(into_generator_error)?)
266    }
267}
268
269#[inline]
270pub fn write_module_to_string(module: &Module, cache: &impl ModuleStore) -> Result<String, Error> {
271    write_module_with_options_to_string(module, cache, Default::default())
272}
273
274pub fn write_module_with_options_to_string(
275    module: &Module,
276    cache: &impl ModuleStore,
277    options: WriteOptions,
278) -> Result<String, Error> {
279    let mut buffer = Cursor::new(Vec::new());
280    write_module_with_options(&mut buffer, module, cache, options)?;
281    Ok(String::from_utf8(buffer.into_inner())?)
282}
283
284///
285/// ```json
286/// {
287///   "identifier-1": {
288///     "__type": "module",
289///     ...
290///   },
291///   "identifier-2": {
292///     "__type": "module",
293///     ...
294///   }
295/// }
296/// ```
297pub fn module_list_to_value(modules: &[&Module], opts: ValueOptions) -> Value {
298    println!("context::module_list_to_value(modules: [...], opts: {opts:?})",);
299    let values: Map<String, Value> = modules
300        .iter()
301        .map(|module| module_to_value_and_name(module, opts))
302        .collect();
303    values.into()
304}
305
306///
307/// Convert a SDML `Module` into a JSON Value
308///
309/// ```json
310/// {
311///   "__type": "module",
312///   "name": "Identifier",
313///   "is_library_module": true,
314///   "source_file": "Path",            // optional
315///   "source_span": {
316///     "start": 0,
317///     "end": 10,
318///   }, // optional
319///   "base_uri": "absolute-uri",       // optional
320///   "version_info": "string",         // optional
321///   "version_uri": "absolute-uri",    // optional
322///   "imports": [],                    // optional
323///   "definitions": [],                // optional
324///   "annotations": []                 // optional
325/// }
326/// ```
327///
328/// # Import Object
329///
330/// Module import:
331///
332/// ```json
333/// {
334///   "module": "Identifier",
335///   "version_uri": "absolute-uri"     // optional
336/// }
337/// ```
338///
339/// Member import:
340///
341/// ```json
342/// {
343///   "module": "Identifier",
344///   "member": "Identifier"
345/// }
346/// ```
347///
348pub fn module_to_value(module: &Module, opts: ValueOptions) -> Value {
349    module.to_json_with(opts)
350}
351
352fn module_to_value_and_name(module: &Module, opts: ValueOptions) -> (String, Value) {
353    (module.name().to_string(), module.to_json_with(opts))
354}
355
356// ------------------------------------------------------------------------------------------------
357// Implementations
358// ------------------------------------------------------------------------------------------------
359
360impl ValueOptions {
361    pub fn for_context() -> Self {
362        Self {
363            context_only: true,
364            include_spans: false,
365        }
366    }
367
368    pub fn for_model() -> Self {
369        Self {
370            context_only: false,
371            include_spans: true,
372        }
373    }
374
375    pub fn emit_context_only(self, context_only: bool) -> Self {
376        let mut self_mut = self;
377        self_mut.context_only = context_only;
378        self_mut
379    }
380
381    pub fn with_spans_included(self, include_spans: bool) -> Self {
382        let mut self_mut = self;
383        self_mut.include_spans = include_spans;
384        self_mut
385    }
386}
387
388// ------------------------------------------------------------------------------------------------
389
390impl WriteOptions {
391    pub fn for_context() -> Self {
392        Self {
393            values: ValueOptions::for_context(),
394            pretty_print: Default::default(),
395        }
396    }
397
398    pub fn for_model() -> Self {
399        Self {
400            values: ValueOptions::for_model(),
401            pretty_print: Default::default(),
402        }
403    }
404
405    pub fn emit_context_only(self, context_only: bool) -> Self {
406        let mut self_mut = self;
407        self_mut.values.context_only = context_only;
408        self_mut
409    }
410
411    pub fn with_pretty_printing(self, pretty_print: bool) -> Self {
412        let mut self_mut = self;
413        self_mut.pretty_print = pretty_print;
414        self_mut
415    }
416
417    pub fn with_spans_included(self, include_spans: bool) -> Self {
418        let mut self_mut = self;
419        self_mut.values.include_spans = include_spans;
420        self_mut
421    }
422}
423
424// ------------------------------------------------------------------------------------------------
425
426impl ToJson for Module {
427    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
428        set!(value_map => NODE_KIND_MODULE);
429        set_source_span!(self, value_map, opts);
430        set!(value_map, opts, name => self);
431        set!(value_map, FIELD_NAME_IS_LIBRARY_MODULE => is_library_module(self.name()));
432        if let Some(source_file) = self.source_file() {
433            set!(
434                value_map,
435                FIELD_NAME_SOURCE_FILE =>
436                    source_file.to_string_lossy().into_owned()
437            );
438        }
439        if let Some(base_uri) = self.base_uri() {
440            set!(value_map, FIELD_NAME_BASE => base_uri.to_string());
441        }
442        if let Some(version_info) = self.version_info() {
443            set!(value_map, FIELD_NAME_VERSION_INFO => version_info.to_string());
444        }
445        if let Some(version_uri) = self.version_uri() {
446            set!(value_map, FIELD_NAME_VERSION_URI => version_uri.to_string());
447        }
448        if opts.context_only && self.has_imports() {
449            let import_array: Vec<Value> = self
450                .imports()
451                .map(|stmt| {
452                    let from_path = stmt.from_module_path();
453                    stmt.imports()
454                        .map(|im| ContextImport(from_path, im).to_json_with(opts))
455                        .collect::<Vec<_>>()
456                })
457                .flatten()
458                .collect();
459
460            set!(value_map, FIELD_NAME_IMPORTS => import_array);
461        } else {
462            add_collection!(
463                value_map,
464                opts,
465                self,
466                has_imports,
467                imports,
468                FIELD_NAME_IMPORTS
469            );
470        }
471        add_annotations!(value_map, opts, self);
472        add_collection!(
473            value_map,
474            opts,
475            self,
476            has_definitions,
477            definitions,
478            JSON_FIELD_NAME_DEFINITIONS
479        );
480    }
481}
482
483impl ToJson for Span {
484    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
485        set!(unless opts.context_only; value_map => NODE_KIND_SPAN);
486        set!(value_map, FIELD_NAME_START => Value::Number(self.start().into()));
487        set!(value_map, FIELD_NAME_END => Value::Number(self.end().into()));
488    }
489}
490
491impl ToJson for ImportStatement {
492    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
493        set!(value_map => NODE_KIND_IMPORT_STATEMENT);
494        if let Some(from_path) = self.from_module_path() {
495            set!(value_map, KW_IMPORT_FROM => Value::String(from_path.to_string()));
496        }
497        add_collection!(
498            value_map,
499            opts,
500            self,
501            has_imports,
502            imports,
503            FIELD_NAME_IMPORTS
504        );
505    }
506}
507
508#[derive(Debug)]
509struct ContextImport<'a>(Option<&'a ModulePath>, &'a Import);
510
511impl ToJson for ContextImport<'_> {
512    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
513        set_variant!(value_map, opts => NODE_KIND_IMPORT);
514
515        if let Some(from_path) = self.0 {
516            set!(value_map, KW_IMPORT_FROM => Value::String(from_path.to_string()));
517        }
518
519        match self.1 {
520            Import::Module(v) => set_variant!(value_map, opts => v, NODE_VARIANT_MODULE),
521            Import::Member(v) => {
522                set_variant!(value_map, opts => v, NODE_VARIANT_MEMBER)
523            }
524        }
525    }
526}
527
528impl ToJson for Import {
529    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
530        set_variant!(value_map, opts => NODE_KIND_IMPORT);
531
532        match self {
533            Import::Module(v) => set_variant!(value_map, opts => v, NODE_VARIANT_MODULE),
534            Import::Member(v) => {
535                set_variant!(value_map, opts => v, NODE_VARIANT_MEMBER)
536            }
537        }
538    }
539}
540
541impl ToJson for MemberImport {
542    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
543        set!(unless opts.context_only; value_map => NODE_KIND_MEMBER_IMPORT);
544        set!(value_map, FIELD_NAME_MODULE => self.name().module().to_json_with(opts));
545        set!(value_map, FIELD_NAME_MEMBER => self.name().member().to_json_with(opts));
546        if let Some(renamed_as) = self.renamed_as() {
547            set!(value_map, FIELD_NAME_RENAME => renamed_as.to_string());
548        }
549    }
550}
551
552impl ToJson for ModuleImport {
553    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
554        set!(unless opts.context_only; value_map => NODE_KIND_MODULE_IMPORT);
555        set!(value_map, FIELD_NAME_MODULE => self.name().to_json_with(opts));
556        if let Some(version) = self.version_uri() {
557            set!(value_map, FIELD_NAME_VERSION_URI => version.to_string());
558        }
559        if let Some(renamed_as) = self.renamed_as() {
560            set!(value_map, FIELD_NAME_RENAME => renamed_as.to_json_with(opts));
561        }
562    }
563}
564
565impl ToJson for Definition {
566    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
567        add_enum!(self,
568            value_map, opts => NODE_KIND_DEFINITION
569                ; Datatype => NODE_VARIANT_DATATYPE
570                ; Dimension => NODE_VARIANT_DIMENSION
571                ; Entity => NODE_VARIANT_ENTITY
572                ; Enum => NODE_VARIANT_ENUM
573                ; Event => NODE_VARIANT_EVENT
574                ; Property => NODE_VARIANT_PROPERTY
575                ; Rdf => NODE_VARIANT_RDF
576                ; Structure => NODE_VARIANT_STRUCTURE
577                ; TypeClass => NODE_VARIANT_TYPE_CLASS
578                ; Union => NODE_VARIANT_UNION
579        );
580    }
581}
582
583impl ToJson for Annotation {
584    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
585        add_enum!(self,
586            value_map, opts => NODE_KIND_ANNOTATION
587                ; Property => NODE_VARIANT_PROPERTY
588                ; Constraint => NODE_VARIANT_CONSTRAINT
589        );
590    }
591}
592
593impl ToJson for TypeReference {
594    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
595        set_variant!(value_map, opts => NODE_KIND_TYPE_REFERENCE);
596
597        match self {
598            TypeReference::Unknown => {
599                set!(value_map, NODE_VARIANT_UNKNOWN => true);
600            }
601            TypeReference::Type(v) => {
602                set!(value_map, NODE_VARIANT_REFERENCE => v.to_json_with(opts));
603            }
604            TypeReference::MappingType(v) => {
605                set_variant!(value_map, opts => v, NODE_VARIANT_MAPPING)
606            }
607        }
608    }
609}
610
611impl ToJson for MappingType {
612    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
613        set!(value_map => NODE_KIND_MAPPING_TYPE);
614        set_source_span!(self, value_map, opts);
615        set!(value_map, FIELD_NAME_DOMAIN => self.domain().to_json_with(opts));
616        set!(value_map, FIELD_NAME_RANGE => self.range().to_json_with(opts));
617    }
618}
619
620///
621/// Convert a SDML `AnnotationProperty` into a context object, in the form shown as JSON below.
622///
623/// ```json
624/// {
625///     "__type": "property",
626///     "source_span": {},              // optional
627///     "name": "IdentifierReference",  // optional
628///     "value": {}
629/// }
630/// ```
631///
632impl ToJson for AnnotationProperty {
633    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
634        set!(value_map => NODE_KIND_ANNOTATION_PROPERTY);
635        set_source_span!(self, value_map, opts);
636        set!(value_map, opts, nameref => self);
637        set!(value_map, FIELD_NAME_VALUE => self.value().to_json_with(opts));
638    }
639}
640
641///
642/// Convert a SDML `Value` into a context object, in the form shown as JSON below.
643///
644/// # Simple Value
645///
646/// ```json
647/// {
648///     "__type": "boolean|double|decimal|integer|unsigned|string|uri|binary",
649///     "value": ...
650/// }
651/// ```
652///
653/// # Value Constructor
654///
655/// ```json
656/// {
657///     "__type": "constructor",
658///     "type_ref": "IdentifierReference",
659///     "value": {}
660/// }
661/// ```
662///
663/// # Mapping
664///
665/// ```json
666/// {
667///     "__type": "mapping",
668///     "domain": {},
669///     "range": {}
670/// }
671/// ```
672///
673/// # Reference
674///
675/// ```json
676/// {
677///     "__type": "type_ref",
678///     "value": "IdentifierReference",
679/// }
680/// ```
681///
682/// # Sequence
683///
684/// ```json
685/// {
686///     "__type": "sequence",
687///     "members": []
688/// }
689/// ```
690///
691impl ToJson for SdmlValue {
692    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
693        add_enum!(self,
694            value_map, opts => NODE_KIND_VALUE
695                ; Simple => NODE_VARIANT_SIMPLE
696                ; ValueConstructor => NODE_VARIANT_VALUE_CONSTRUCTOR
697                ; Mapping => NODE_VARIANT_MAPPING
698                ; Reference => NODE_VARIANT_REFERENCE
699                ; Sequence => NODE_VARIANT_SEQUENCE
700        );
701    }
702}
703
704///
705/// Convert a SDML `Constraint` into a context object, in the form shown as JSON below.
706///
707/// ## Informal Constraint
708///
709/// ```json
710/// {
711///     "__type": "informal",
712///     "source_span": {},              // optional
713///     "name": "Identifier",
714///     "value": "string",
715///     "language": ""                  // optional
716/// }
717/// ```
718///
719/// ## Formal Constraint
720///
721/// ```json
722/// {
723///     "__type": "formal",
724///     "source_span": {},             // optional
725///     "name": "Identifier",
726///     "definitions": [],             // optional
727///     "sentence": {}
728/// }
729/// ```
730///
731impl ToJson for Constraint {
732    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
733        set_variant!(value_map, opts => NODE_KIND_CONSTRAINT);
734        set_source_span!(self, value_map, opts);
735        set!(value_map, opts, name => self);
736        if opts.context_only {
737            self.body().add_to_json_with(value_map, opts);
738        } else {
739            set!(value_map, FIELD_NAME_BODY => self.body().to_json_with(opts));
740        }
741    }
742}
743
744impl ToJson for ConstraintBody {
745    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
746        add_enum!(self,
747            value_map, opts => NODE_KIND_CONSTRAINT_BODY
748                ; Formal => NODE_VARIANT_FORMAL
749                ; Informal => NODE_VARIANT_INFORMAL
750        );
751    }
752}
753
754impl ToJson for ControlledLanguageString {
755    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, _: ValueOptions) {
756        set!(value_map => NODE_KIND_INFORMAL_CONSTRAINT);
757        set!(value_map, FIELD_NAME_VALUE => self.value().to_string());
758        if let Some(language) = self.language() {
759            set!(value_map, FIELD_NAME_LANGUAGE => language.value().to_string());
760        }
761    }
762}
763
764impl ToJson for FormalConstraint {
765    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
766        set!(value_map => NODE_KIND_FORMAL_CONSTRAINT);
767        add_collection!(
768            value_map,
769            opts,
770            self,
771            has_definitions,
772            definitions,
773            FIELD_NAME_ENVIRONMENT
774        );
775        set!(value_map, FIELD_NAME_BODY => self.body().to_json_with(opts));
776    }
777}
778
779///
780/// Convert a SDML `DatatypeDef` into a context object, in the form shown as JSON below.
781///
782/// ```json
783/// {
784///     "__type": "datatype",
785///     "source_span": {},              // optional
786///     "name": "Identifier",
787///     "is_opaque": false,
788///     "base_type": "IdentifierReference",
789///     "annotations": []               // optional
790/// }
791/// ```
792///
793impl ToJson for DatatypeDef {
794    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
795        set!(value_map => NODE_KIND_DATA_TYPE_DEF);
796        set_source_span!(self, value_map, opts);
797        set!(value_map, opts, name => self);
798        set!(value_map, FIELD_NAME_IS_OPAQUE => self.is_opaque());
799        set!(value_map, FIELD_NAME_BASE => self.base_type().to_string());
800        if self.has_restrictions() {
801            let mut inner_map: Map<String, Value> = new_map!(self.restriction_count() + 1);
802            set!(&mut inner_map => NODE_KIND_DATATYPE_DEF_RESTRICTION);
803            for restriction in self.restrictions() {
804                match restriction {
805                    RestrictionFacet::FractionDigits(v, f) => {
806                        let mut restriction_map = new_map!(2);
807                        set!(restriction_map, FIELD_NAME_VALUE => *v);
808                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
809                        set!(inner_map, KW_FACET_FRACTION_DIGITS => restriction_map);
810                    }
811                    RestrictionFacet::TotalDigits(v, f) => {
812                        let mut restriction_map = new_map!(2);
813                        set!(restriction_map, FIELD_NAME_VALUE => *v);
814                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
815                        set!(inner_map, KW_FACET_TOTAL_DIGITS => restriction_map);
816                    }
817                    RestrictionFacet::Length(v, f) => {
818                        let mut restriction_map = new_map!(2);
819                        set!(restriction_map, FIELD_NAME_VALUE => *v);
820                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
821                        set!(inner_map, KW_FACET_LENGTH => restriction_map);
822                    }
823                    RestrictionFacet::MaxLength(v, f) => {
824                        let mut restriction_map = new_map!(2);
825                        set!(restriction_map, FIELD_NAME_VALUE => *v);
826                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
827                        set!(inner_map, KW_FACET_MAX_LENGTH => restriction_map);
828                    }
829                    RestrictionFacet::MinLength(v, f) => {
830                        let mut restriction_map = new_map!(2);
831                        set!(restriction_map, FIELD_NAME_VALUE => *v);
832                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
833                        set!(inner_map, KW_FACET_MIN_LENGTH => restriction_map);
834                    }
835                    RestrictionFacet::MaxExclusive(v, f) => {
836                        let mut restriction_map = new_map!(2);
837                        set!(restriction_map, FIELD_NAME_VALUE => *v);
838                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
839                        set!(inner_map, KW_FACET_MAX_EXCLUSIVE => restriction_map);
840                    }
841                    RestrictionFacet::MinExclusive(v, f) => {
842                        let mut restriction_map = new_map!(2);
843                        set!(restriction_map, FIELD_NAME_VALUE => *v);
844                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
845                        set!(inner_map, KW_FACET_MIN_EXCLUSIVE => restriction_map);
846                    }
847                    RestrictionFacet::MaxInclusive(v, f) => {
848                        let mut restriction_map = new_map!(2);
849                        set!(restriction_map, FIELD_NAME_VALUE => *v);
850                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
851                        set!(inner_map, KW_FACET_MAX_INCLUSIVE => restriction_map);
852                    }
853                    RestrictionFacet::MinInclusive(v, f) => {
854                        let mut restriction_map = new_map!(2);
855                        set!(restriction_map, FIELD_NAME_VALUE => *v);
856                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
857                        set!(inner_map, KW_FACET_MIN_INCLUSIVE => restriction_map);
858                    }
859                    RestrictionFacet::ExplicitTimezone(v, f) => {
860                        let mut restriction_map = new_map!(2);
861                        set!(restriction_map, FIELD_NAME_VALUE => v.to_string());
862                        set!(restriction_map, FIELD_NAME_IS_FIXED => *f);
863                        set!(inner_map, KW_FACET_EXPLICIT_TIMEZONE => restriction_map);
864                    }
865                    RestrictionFacet::Pattern(vs) => {
866                        let mut restriction_map = new_map!(1);
867                        let value_array: Vec<serde_json::Value> =
868                            vs.iter().map(|s| s.to_string().into()).collect();
869                        set!(restriction_map, FIELD_NAME_VALUE => value_array);
870                        set!(inner_map, KW_FACET_PATTERN => restriction_map);
871                    }
872                }
873            }
874            set!(value_map, FIELD_NAME_RESTRICTION => inner_map);
875        }
876        add_body!(value_map, opts, self);
877    }
878}
879
880impl ToJson for AnnotationOnlyBody {
881    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
882        if self.has_annotations() {
883            let annotations = self
884                .annotations()
885                .map(|ann| ann.to_json_with(opts))
886                .collect::<Vec<Value>>();
887            if opts.context_only {
888                set!(value_map, FIELD_NAME_ANNOTATIONS => annotations);
889            } else {
890                let mut inner_map: Map<String, Value> = new_map!(2);
891                set!(&mut inner_map => NODE_KIND_ANNOTATION_ONLY_BODY);
892                set!(&mut inner_map, FIELD_NAME_ANNOTATIONS => annotations);
893                set!(value_map, FIELD_NAME_BODY => inner_map);
894            }
895        }
896    }
897}
898
899impl ToJson for Identifier {
900    fn to_json_with(&self, opts: ValueOptions) -> Value {
901        if opts.context_only {
902            self.to_string().into()
903        } else {
904            let mut map = new_map!(2);
905            self.add_to_json_with(&mut map, opts);
906            map.into()
907        }
908    }
909    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, _: ValueOptions) {
910        set!(value_map => NODE_KIND_IDENTIFIER);
911        set!(value_map, FIELD_NAME_VALUE => self.to_string());
912    }
913}
914
915impl ToJson for QualifiedIdentifier {
916    fn to_json_with(&self, opts: ValueOptions) -> Value {
917        if opts.context_only {
918            self.to_string().into()
919        } else {
920            let mut map = new_map!(3);
921            self.add_to_json_with(&mut map, opts);
922            map.into()
923        }
924    }
925    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
926        set!(value_map => NODE_KIND_QUALIFIED_IDENTIFIER);
927        set!(value_map, FIELD_NAME_MODULE => self.module().to_json_with(opts));
928        set!(value_map, FIELD_NAME_MEMBER => self.member().to_json_with(opts));
929    }
930}
931
932impl ToJson for IdentifierReference {
933    fn to_json_with(&self, opts: ValueOptions) -> Value {
934        if opts.context_only {
935            self.to_string().into()
936        } else {
937            let mut map = new_map!();
938            self.add_to_json_with(&mut map, opts);
939            map.into()
940        }
941    }
942    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
943        add_enum!(self,
944            value_map, opts => NODE_KIND_IDENTIFIER_REFERENCE
945                ; Identifier => NODE_VARIANT_IDENTIFIER
946                ; QualifiedIdentifier => NODE_VARIANT_QUALIFIED_IDENTIFIER
947        );
948    }
949}
950
951///
952/// Convert a SDML `EntityDef` into a context object, in the form shown as JSON below.
953///
954/// ```json
955/// {
956///     "__type": "entity",
957///     "source_span": {},              // optional
958///     "name": "Identifier",
959///     "identity": {},
960///     "members": [],                  // optional
961///     "annotations": []               // optional
962/// }
963/// ```
964///
965/// For `identity`, see MemberDef and for `members` see Member, in [`member_to_value`].
966///
967impl ToJson for EntityDef {
968    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
969        set!(value_map => NODE_KIND_ENTITY_DEF);
970        set_source_span!(self, value_map, opts);
971        set!(value_map, opts, name => self);
972        add_body!(value_map, opts, self)
973    }
974}
975
976impl ToJson for EntityBody {
977    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
978        set!(unless opts.context_only; value_map => NODE_KIND_ENTITY_BODY);
979        set!(value_map, FIELD_NAME_IDENTITY => self.identity().to_json_with(opts));
980        add_annotations!(value_map, opts, self);
981        add_collection!(
982            value_map,
983            opts,
984            self,
985            has_members,
986            members,
987            FIELD_NAME_MEMBERS
988        );
989    }
990}
991
992///
993/// Convert a SDML `Member` into a context object, in the form shown as JSON below.
994///
995///
996/// A member is either a reference to a property or a definition of a new member.
997///
998/// # Property Reference
999///
1000/// ```json
1001/// {
1002///     "__type": "reference",
1003///     "type_ref": "IdentifierReference",
1004/// }
1005/// ```
1006///
1007/// # Member Definition
1008///
1009/// ```json
1010/// {
1011///     "__type": "definition",
1012///     "source_span": {},              // optional
1013///     "name": "Identifier",
1014///     "cardinality": {
1015///         "ordering": "",
1016///         "uniqueness": "",
1017///         "min_occurs": 1,
1018///         "max_occurs": 0             // optional
1019///     },
1020///     "type_ref": "IdentifierReference"
1021/// }
1022/// ```
1023///
1024impl ToJson for Member {
1025    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1026        if opts.context_only {
1027            self.kind().add_to_json_with(value_map, opts)
1028        } else {
1029            set!(value_map => NODE_KIND_MEMBER);
1030            set_source_span!(self, value_map, opts);
1031            set!(value_map, FIELD_NAME_KIND => self.kind().to_json_with(opts));
1032        }
1033    }
1034}
1035
1036impl ToJson for MemberKind {
1037    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1038        add_enum!(self,
1039            value_map, opts => NODE_KIND_MEMBER
1040                ; Reference => NODE_VARIANT_REFERENCE
1041                ; Definition => NODE_VARIANT_DEFINITION
1042        );
1043    }
1044}
1045
1046impl ToJson for MemberDef {
1047    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1048        set!(value_map => NODE_KIND_MEMBER_DEF);
1049        set_source_span!(self, value_map, opts);
1050        set!(value_map, opts, name => self);
1051        if !self.target_cardinality().is_default() {
1052            set!(value_map, FIELD_NAME_CARDINALITY => self.target_cardinality().to_json_with(opts));
1053        }
1054        set!(value_map, FIELD_NAME_TYPE => self.target_type().to_json_with(opts));
1055        add_body!(value_map, opts, self);
1056    }
1057}
1058
1059impl ToJson for Cardinality {
1060    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1061        set!(unless opts.context_only; value_map => NODE_KIND_CARDINALITY_EXPRESSION);
1062        if let Some(ordering) = self.ordering() {
1063            set!(value_map, FIELD_NAME_ORDERING => ordering.to_string());
1064        }
1065        if let Some(uniqueness) = self.uniqueness() {
1066            set!(value_map, FIELD_NAME_UNIQUENESS => uniqueness.to_string());
1067        }
1068        let range = self.range();
1069        set!(value_map, FIELD_NAME_MIN => range.min_occurs());
1070        if let Some(max_occurs) = range.max_occurs() {
1071            set!(value_map, FIELD_NAME_MAX => max_occurs);
1072        }
1073    }
1074}
1075
1076///
1077/// Convert a SDML `EnumDef` into a context object, in the form shown as JSON below.
1078///
1079/// ```json
1080/// {
1081///     "__type": "enum",
1082///     "source_span": {},              // optional
1083///     "name": "Identifier",
1084///     "variants": [                   // optional
1085///         {
1086///             "name": "Identifier",
1087///             "annotations": []       // optional
1088///         }
1089///     ],
1090///     "annotations": []               // optional
1091/// }
1092/// ```
1093///
1094impl ToJson for EnumDef {
1095    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1096        set!(value_map => NODE_KIND_ENUM_DEF);
1097        set_source_span!(self, value_map, opts);
1098        set!(value_map, opts, name => self);
1099        add_body!(value_map, opts, self);
1100    }
1101}
1102
1103impl ToJson for EnumBody {
1104    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1105        set!(unless opts.context_only; value_map => NODE_KIND_ENUM_BODY);
1106        add_annotations!(value_map, opts, self);
1107        add_collection!(
1108            value_map,
1109            opts,
1110            self,
1111            has_variants,
1112            variants,
1113            FIELD_NAME_VARIANTS
1114        );
1115    }
1116}
1117
1118impl ToJson for ValueVariant {
1119    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1120        set!(unless opts.context_only; value_map => NODE_KIND_VALUE_VARIANT);
1121        set_source_span!(self, value_map, opts);
1122        set!(value_map, opts, name => self);
1123        add_body!(value_map, opts, self);
1124    }
1125}
1126
1127///
1128/// Convert a SDML `EventDef` into a context object, in the form shown as JSON below.
1129///
1130/// ```json
1131/// {
1132///     "__type": "event_def",
1133///     "source_span": {},              // optional
1134///     "name": "Identifier",
1135///     "source_entity": {},             // SourceEntity
1136///     "members": [],                  // optional
1137///     "annotations": []               // optional
1138/// }
1139/// ```
1140///
1141/// For `members`, see [`member_to_value`], and for `event_source` see [`dimension_to_value`].
1142///
1143impl ToJson for EventDef {
1144    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1145        set!(value_map => NODE_KIND_EVENT_DEF);
1146        set_source_span!(self, value_map, opts);
1147        set!(value_map, opts, name => self);
1148        add_body!(value_map, opts, self);
1149    }
1150}
1151
1152impl ToJson for EventBody {
1153    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1154        set!(unless opts.context_only; value_map => NODE_KIND_EVENT_BODY);
1155        add_annotations!(value_map, opts, self);
1156        set!(value_map, FIELD_NAME_SOURCE => self.source_entity().to_json_with(opts));
1157        add_collection!(
1158            value_map,
1159            opts,
1160            self,
1161            has_members,
1162            members,
1163            FIELD_NAME_MEMBERS
1164        );
1165    }
1166}
1167
1168impl ToJson for SourceEntity {
1169    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1170        set!(value_map => NODE_KIND_SOURCE_ENTITY);
1171        set_source_span!(self, value_map, opts);
1172        set!(value_map, FIELD_NAME_ENTITY => self.target_entity().to_json_with(opts));
1173        add_collection!(
1174            value_map,
1175            opts,
1176            self,
1177            has_members,
1178            members,
1179            FIELD_NAME_MEMBERS
1180        );
1181    }
1182}
1183
1184///
1185/// Convert a SDML `DimensionDef` into a context object, in the form shown as JSON below.
1186///
1187/// ```json
1188/// {
1189///     "__type": "event",
1190///     "source_span": {},              // optional
1191///     "name": "Identifier",
1192///     "entity": {...},                // SourceEntity or Member
1193///     "parents": [],                  // optional
1194///     "members": [],                  // optional
1195///     "annotations": []               // optional
1196/// }
1197/// ```
1198///
1199/// # DimensionParent
1200///
1201/// ```json
1202/// {
1203///     "source_span": {},              // optional
1204///     "name": "Identifier",
1205///     "entity": "IdentifierReference",
1206///     "annotations": []               // optional
1207/// }
1208/// ```
1209///
1210/// # SourceEntity
1211///
1212/// ```json
1213/// {
1214///     "__type": "source_entity",
1215///     "source_span": {},              // optional
1216///     "entity": "IdentifierReference",
1217///     "members": []                   // optional
1218/// }
1219/// ```
1220///
1221/// For `members`, see [`member_to_value`].
1222///
1223impl ToJson for DimensionDef {
1224    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1225        set!(value_map => NODE_KIND_DIMENSION_DEF);
1226        set_source_span!(self, value_map, opts);
1227        set!(value_map, opts, name => self);
1228        add_body!(value_map, opts, self);
1229    }
1230}
1231
1232impl ToJson for DimensionBody {
1233    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1234        set!(unless opts.context_only; value_map => NODE_KIND_DIMENSION_BODY);
1235        add_annotations!(value_map, opts, self);
1236        set!(value_map, FIELD_NAME_IDENTITY => self.identity().to_json_with(opts));
1237        add_collection!(
1238            value_map,
1239            opts,
1240            self,
1241            has_parents,
1242            parents,
1243            FIELD_NAME_PARENTS
1244        );
1245        add_collection!(
1246            value_map,
1247            opts,
1248            self,
1249            has_members,
1250            members,
1251            FIELD_NAME_MEMBERS
1252        );
1253    }
1254}
1255
1256impl ToJson for DimensionIdentity {
1257    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1258        add_enum!(self,
1259            value_map, opts => NODE_KIND_DIMENSION_IDENTITY
1260                ; Source => FIELD_NAME_SOURCE
1261                ; Identity => FIELD_NAME_IDENTITY
1262        );
1263    }
1264}
1265
1266impl ToJson for DimensionParent {
1267    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1268        set!(unless opts.context_only; value_map => NODE_KIND_DIMENSION_PARENT);
1269        set_source_span!(self, value_map, opts);
1270        set!(value_map, opts, name => self);
1271        set!(value_map, FIELD_NAME_ENTITY => self.target_entity().to_json_with(opts));
1272        add_body!(value_map, opts, self);
1273    }
1274}
1275
1276///
1277/// Convert a SDML `PropertyDef` into a context object, in the form shown as JSON below.
1278///
1279/// ```json
1280/// {
1281///     "__type": "property",
1282///     "source_span": {},              // optional
1283///     "name": "Identifier",
1284///     "cardinality": {
1285///         "ordering": "",
1286///         "uniqueness": "",
1287///         "min_occurs": 1,
1288///         "max_occurs": 0             // optional
1289///     },
1290///     "type_ref": "IdentifierReference"
1291/// }
1292/// ```
1293///
1294/// For `member` see member definition in [`member_to_value`].
1295///
1296impl ToJson for PropertyDef {
1297    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1298        set!(value_map => NODE_KIND_PROPERTY_DEF);
1299        set_source_span!(self, value_map, opts);
1300        set!(value_map, FIELD_NAME_MEMBER => self.member_def().to_json_with(opts));
1301    }
1302}
1303
1304///
1305/// Convert a SDML `RdfDef` into a context object, in the form shown as JSON below.
1306///
1307/// ```json
1308/// {
1309///     "__type": "rdf",
1310///     "source_span": {},              // optional
1311///     "name": "Identifier",
1312///     "annotations": []               // optional
1313/// }
1314/// ```
1315///
1316impl ToJson for RdfDef {
1317    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1318        set!(value_map => NODE_KIND_RDF_DEF);
1319        set_source_span!(self, value_map, opts);
1320        set!(value_map, opts, name => self);
1321        self.body().add_to_json_with(value_map, opts);
1322    }
1323}
1324
1325///
1326/// Convert a SDML `StructureDef` into a context object, in the form shown as JSON below.
1327///
1328/// ```json
1329/// {
1330///     "__type": "structure",
1331///     "source_span": {},              // optional
1332///     "name": "Identifier",
1333///     "members": [],                  // optional
1334///     "annotations": []               // optional
1335/// }
1336/// ```
1337///
1338/// For `members`, see [`member_to_value`].
1339///
1340impl ToJson for StructureDef {
1341    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1342        set!(value_map => NODE_KIND_STRUCTURE_DEF);
1343        set_source_span!(self, value_map, opts);
1344        set!(value_map, opts, name => self);
1345        add_body!(value_map, opts, self);
1346    }
1347}
1348
1349impl ToJson for StructureBody {
1350    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1351        set!(unless opts.context_only; value_map => NODE_KIND_STRUCTURE_BODY);
1352        add_annotations!(value_map, opts, self);
1353        add_collection!(
1354            value_map,
1355            opts,
1356            self,
1357            has_members,
1358            members,
1359            FIELD_NAME_MEMBERS
1360        );
1361    }
1362}
1363
1364///
1365/// Convert a SDML `TypeClassDef` into a context object, in the form shown as JSON below.
1366///
1367/// ```json
1368/// {
1369///     "__type": "type_class",
1370///     "source_span": {},              // optional
1371///     "name": "Identifier",
1372///     "variables": [],                // optional
1373///     "methods": [],                  // optional
1374///     "annotations": []               // optional
1375/// }
1376/// ```
1377///
1378/// ## Variable
1379///
1380/// TBD
1381///
1382/// ## Method
1383///
1384/// TBD
1385///
1386impl ToJson for TypeClassDef {
1387    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1388        set!(value_map => NODE_KIND_TYPE_CLASS_DEF);
1389        set_source_span!(self, value_map, opts);
1390        set!(value_map, opts, name => self);
1391        add_collection!(
1392            value_map,
1393            opts,
1394            self,
1395            has_variables,
1396            variables,
1397            FIELD_NAME_VARIABLES
1398        );
1399        add_body!(value_map, opts, self);
1400    }
1401}
1402
1403impl ToJson for TypeClassBody {
1404    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1405        set!(unless opts.context_only; value_map => NODE_KIND_TYPE_CLASS_BODY);
1406        set_source_span!(self, value_map, opts, !opts.context_only);
1407        add_annotations!(value_map, opts, self);
1408        add_collection!(
1409            value_map,
1410            opts,
1411            self,
1412            has_methods,
1413            methods,
1414            FIELD_NAME_METHODS
1415        );
1416    }
1417}
1418
1419///
1420/// Convert a SDML `UnionDef` into a context object, in the form shown as JSON below.
1421///
1422/// ```json
1423/// {
1424///     "__type": "union",
1425///     "source_span": {},              // optional
1426///     "name": "Identifier",
1427///     "variants": [                   // optional
1428///         {
1429///             "name": "IdentifierReference",
1430///             "rename": "Identifier",
1431///             "annotations": []
1432///         }
1433///     ],
1434///     "annotations": []               // optional
1435/// }
1436/// ```
1437///
1438impl ToJson for UnionDef {
1439    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1440        set!(value_map => NODE_KIND_UNION_DEF);
1441        set_source_span!(self, value_map, opts);
1442        set!(value_map, opts, name => self);
1443        add_body!(value_map, opts, self);
1444    }
1445}
1446
1447impl ToJson for UnionBody {
1448    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1449        set!(unless opts.context_only; value_map => NODE_KIND_UNION_BODY);
1450        set_source_span!(self, value_map, opts, !opts.context_only);
1451        add_annotations!(value_map, opts, self);
1452        add_collection!(
1453            value_map,
1454            opts,
1455            self,
1456            has_variants,
1457            variants,
1458            FIELD_NAME_VARIANTS
1459        );
1460    }
1461}
1462
1463impl ToJson for TypeVariant {
1464    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1465        set!(unless opts.context_only; value_map => NODE_KIND_TYPE_VARIANT);
1466        set_source_span!(self, value_map, opts);
1467        set!(value_map, opts, nameref => self);
1468        if let Some(rename) = self.rename() {
1469            set!(value_map, FIELD_NAME_RENAME => rename.to_json_with(opts));
1470        }
1471        add_body!(value_map, opts, self);
1472    }
1473}
1474
1475impl ToJson for SimpleValue {
1476    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1477        set_variant!(value_map, opts => NODE_KIND_SIMPLE_VALUE);
1478
1479        match self {
1480            SimpleValue::Boolean(v) => {
1481                set!(value_map => NODE_KIND_BOOLEAN);
1482                set!(value_map, FIELD_NAME_VALUE => *v);
1483            }
1484            SimpleValue::Double(v) => {
1485                set!(value_map => NODE_KIND_DOUBLE);
1486                set!(value_map, FIELD_NAME_VALUE => *v.as_ref());
1487            }
1488            SimpleValue::Decimal(v) => {
1489                set!(value_map => NODE_KIND_DECIMAL);
1490                set!(value_map, FIELD_NAME_VALUE => v.to_string());
1491            }
1492            SimpleValue::Integer(v) => {
1493                set!(value_map => NODE_KIND_INTEGER);
1494                set!(value_map, FIELD_NAME_VALUE => *v);
1495            }
1496            SimpleValue::Unsigned(v) => {
1497                set!(value_map => NODE_KIND_UNSIGNED);
1498                set!(value_map, FIELD_NAME_VALUE => *v);
1499            }
1500            SimpleValue::String(v) => {
1501                set!(value_map => NODE_KIND_STRING);
1502                set!(value_map, FIELD_NAME_VALUE => v.value().to_string());
1503                if let Some(language) = v.language() {
1504                    set!(value_map, FIELD_NAME_LANGUAGE => language.inner().to_string());
1505                }
1506            }
1507            SimpleValue::IriReference(v) => {
1508                set!(value_map => NODE_KIND_IRI);
1509                set!(value_map, FIELD_NAME_VALUE => v.to_string());
1510            }
1511            SimpleValue::Binary(v) => {
1512                let value: Vec<Value> = v
1513                    .as_bytes()
1514                    .iter()
1515                    .map(|b| Number::from(*b).into())
1516                    .collect();
1517
1518                set!(value_map => NODE_KIND_BINARY);
1519                set!(value_map, FIELD_NAME_VALUE => value);
1520            }
1521        }
1522    }
1523}
1524
1525impl ToJson for ValueConstructor {
1526    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1527        set!(value_map => NODE_KIND_VALUE_CONSTRUCTOR);
1528        set_source_span!(self, value_map, opts);
1529        set!(value_map, FIELD_NAME_TYPE => self.type_name().to_json_with(opts));
1530        set!(value_map, FIELD_NAME_VALUE => self.value().to_json_with(opts));
1531    }
1532}
1533
1534impl ToJson for MappingValue {
1535    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1536        set!(value_map => NODE_KIND_MAPPING_VALUE);
1537        set_source_span!(self, value_map, opts);
1538        set!(value_map, FIELD_NAME_DOMAIN => self.domain().to_json_with(opts));
1539        set!(value_map, FIELD_NAME_RANGE => self.range().to_json_with(opts));
1540    }
1541}
1542
1543impl ToJson for SequenceOfValues {
1544    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1545        set!(value_map => NODE_KIND_SEQUENCE_OF_VALUES);
1546        set_source_span!(self, value_map, opts);
1547        if let Some(ordering) = self.ordering() {
1548            set!(value_map, FIELD_NAME_ORDERING => ordering.to_string());
1549        }
1550        if let Some(uniqueness) = self.uniqueness() {
1551            set!(value_map, FIELD_NAME_UNIQUENESS => uniqueness.to_string());
1552        }
1553        if !self.is_empty() {
1554            let values = self
1555                .iter()
1556                .map(|thing| thing.to_json_with(opts))
1557                .collect::<Vec<Value>>();
1558            set!(value_map, FIELD_NAME_MEMBERS => values);
1559        }
1560    }
1561}
1562
1563impl ToJson for SequenceMember {
1564    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1565        add_enum!(self,
1566            value_map, opts => NODE_KIND_SEQUENCE_MEMBER
1567                ; Simple => NODE_VARIANT_SIMPLE
1568                ; ValueConstructor => NODE_VARIANT_VALUE_CONSTRUCTOR
1569                ; Mapping => NODE_VARIANT_MAPPING
1570                ; Reference => NODE_VARIANT_REFERENCE
1571        );
1572    }
1573}
1574
1575impl ToJson for SequenceOfPredicateValues {
1576    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1577        set!(value_map => NODE_KIND_SEQUENCE_OF_PREDICATE_VALUES);
1578        set_source_span!(self, value_map, opts);
1579        if !self.is_empty() {
1580            let values = self
1581                .iter()
1582                .map(|thing| thing.to_json_with(opts))
1583                .collect::<Vec<Value>>();
1584            set!(value_map, FIELD_NAME_MEMBERS => values);
1585        }
1586    }
1587}
1588
1589impl ToJson for PredicateSequenceMember {
1590    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1591        add_enum!(self,
1592            value_map, opts => NODE_KIND_PREDICATE_SEQUENCE_MEMBER
1593                ; Simple => NODE_VARIANT_SIMPLE
1594                ; ValueConstructor => NODE_VARIANT_VALUE_CONSTRUCTOR
1595                ; Mapping => NODE_VARIANT_MAPPING
1596                ; Reference => NODE_VARIANT_REFERENCE
1597        );
1598    }
1599}
1600
1601impl ToJson for PredicateValue {
1602    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1603        add_enum!(self,
1604            value_map, opts => NODE_KIND_PREDICATE_VALUE
1605                ; Simple => NODE_VARIANT_SIMPLE
1606                ; Sequence => NODE_VARIANT_SEQUENCE
1607        );
1608    }
1609}
1610
1611impl ToJson for FunctionDef {
1612    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1613        set!(value_map => NODE_KIND_FUNCTION_DEF);
1614        set_source_span!(self, value_map, opts);
1615        set!(value_map, FIELD_NAME_SIGNATURE => self.signature().to_json_with(opts));
1616        set!(value_map, FIELD_NAME_BODY => self.body().to_json_with(opts));
1617    }
1618}
1619
1620impl ToJson for FunctionSignature {
1621    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1622        set!(value_map => NODE_KIND_FUNCTION_SIGNATURE);
1623        set_source_span!(self, value_map, opts);
1624        add_collection!(
1625            value_map,
1626            opts,
1627            self,
1628            has_parameters,
1629            parameters,
1630            FIELD_NAME_PARAMETERS
1631        );
1632        set!(value_map, FIELD_NAME_TYPE => self.target_type().to_json_with(opts));
1633    }
1634}
1635
1636impl ToJson for FunctionParameter {
1637    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1638        set!(value_map => NODE_KIND_FUNCTION_PARAMETER);
1639        set_source_span!(self, value_map, opts);
1640        set!(value_map, opts, name => self);
1641        set!(value_map, FIELD_NAME_TYPE => self.target_type().to_json_with(opts));
1642    }
1643}
1644
1645impl ToJson for FunctionType {
1646    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1647        set!(value_map => NODE_KIND_FUNCTION_TYPE);
1648        set_source_span!(self, value_map, opts);
1649        if !self.target_cardinality().is_default() {
1650            set!(
1651                value_map,
1652                FIELD_NAME_CARDINALITY =>
1653                self.target_cardinality().to_json_with(opts)
1654            );
1655        }
1656        set!(value_map, FIELD_NAME_TYPE => self.target_type().to_json_with(opts));
1657    }
1658}
1659
1660impl ToJson for FunctionCardinality {
1661    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1662        set!(unless opts.context_only; value_map => NODE_KIND_FUNCTION_CARDINALITY_EXPRESSION);
1663        set_source_span!(self, value_map, opts);
1664        if let Some(ordering) = self.ordering() {
1665            set!(value_map, FIELD_NAME_ORDERING => ordering.to_string());
1666        }
1667        if let Some(uniqueness) = self.uniqueness() {
1668            set!(value_map, FIELD_NAME_UNIQUENESS => uniqueness.to_string());
1669        }
1670        if let Some(range) = self.range() {
1671            set!(value_map, FIELD_NAME_MIN => range.min_occurs());
1672            if let Some(max_occurs) = range.max_occurs() {
1673                set!(value_map, FIELD_NAME_MAX => max_occurs);
1674            }
1675        }
1676    }
1677}
1678
1679impl ToJson for FunctionTypeReference {
1680    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1681        add_enum!(self,
1682            value_map, opts => NODE_KIND_FUNCTION_TYPE_REFERENCE
1683            ; Reference => NODE_VARIANT_REFERENCE
1684            ; MappingType => NODE_VARIANT_MAPPING
1685            ; ! Wildcard => NODE_VARIANT_WILDCARD
1686        );
1687    }
1688}
1689
1690impl ToJson for FunctionBody {
1691    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1692        add_enum!(self,
1693            value_map, opts => NODE_KIND_FUNCTION_BODY
1694            ; Sentence => NODE_VARIANT_SENTENCE
1695            ; Term => NODE_VARIANT_TERM
1696        );
1697    }
1698}
1699
1700impl ToJson for ConstraintSentence {
1701    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1702        add_enum!(self,
1703            value_map, opts => NODE_KIND_CONSTRAINT_SENTENCE
1704                ; Simple => NODE_VARIANT_SIMPLE
1705                ; Boolean => NODE_VARIANT_BOOLEAN
1706                ; Quantified => NODE_VARIANT_QUANTIFIED
1707        );
1708    }
1709}
1710
1711impl ToJson for SimpleSentence {
1712    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1713        add_enum!(self,
1714            value_map, opts => NODE_KIND_SIMPLE_SENTENCE
1715                ; Atomic => NODE_VARIANT_ATOMIC
1716                ; Equation => NODE_VARIANT_EQUATION
1717                ; Inequation => NODE_VARIANT_INEQUATION
1718        );
1719    }
1720}
1721
1722impl ToJson for AtomicSentence {
1723    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1724        set!(value_map => NODE_KIND_ATOMIC_SENTENCE);
1725        set_source_span!(self, value_map, opts);
1726        set!(value_map, FIELD_NAME_PREDICATE => self.predicate().to_json_with(opts));
1727        add_collection!(
1728            value_map,
1729            opts,
1730            self,
1731            has_arguments,
1732            arguments,
1733            FIELD_NAME_ARGUMENTS
1734        );
1735    }
1736}
1737
1738impl ToJson for Equation {
1739    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1740        set!(value_map => NODE_KIND_EQUATION);
1741        set_source_span!(self, value_map, opts);
1742        set!(value_map, FIELD_NAME_LHS => self.left_operand().to_json_with(opts));
1743        set!(value_map, FIELD_NAME_RHS => self.right_operand().to_json_with(opts));
1744    }
1745}
1746
1747impl ToJson for Inequation {
1748    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1749        set!(value_map => NODE_KIND_INEQUATION);
1750        set_source_span!(self, value_map, opts);
1751        set!(value_map, FIELD_NAME_LHS => self.left_operand().to_json_with(opts));
1752        set!(value_map, FIELD_NAME_RELATION => match self.relation() {
1753            InequalityRelation::NotEqual => NODE_KIND_OP_INEQUALITY,
1754            InequalityRelation::LessThan => NODE_KIND_OP_LESS_THAN,
1755            InequalityRelation::LessThanOrEqual => NODE_KIND_OP_LESS_THAN_OR_EQUAL,
1756            InequalityRelation::GreaterThan => NODE_KIND_OP_GREATER_THAN,
1757            InequalityRelation::GreaterThanOrEqual => NODE_KIND_OP_GREATER_THAN_OR_EQUAL,
1758        });
1759        set!(value_map, FIELD_NAME_RHS => self.right_operand().to_json_with(opts));
1760    }
1761}
1762
1763impl ToJson for BooleanSentence {
1764    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1765        add_enum!(self,
1766            value_map, opts => NODE_KIND_BOOLEAN_SENTENCE
1767                ; Unary => NODE_VARIANT_UNARY
1768                ; Binary => NODE_VARIANT_BINARY
1769        );
1770    }
1771}
1772
1773impl ToJson for UnaryBooleanSentence {
1774    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1775        set!(value_map => NODE_KIND_UNARY_BOOLEAN_SENTENCE);
1776        set_source_span!(self, value_map, opts);
1777        set!(value_map, FIELD_NAME_OPERATOR => self.operator().to_string());
1778        set!(value_map, FIELD_NAME_OPERAND => self.operand().to_json_with(opts));
1779    }
1780}
1781
1782impl ToJson for BinaryBooleanSentence {
1783    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1784        set!(value_map => NODE_KIND_BINARY_BOOLEAN_SENTENCE);
1785        set_source_span!(self, value_map, opts);
1786        set!(value_map, FIELD_NAME_LHS => self.left_operand().to_json_with(opts));
1787        set!(value_map, FIELD_NAME_OPERATOR => match self.operator() {
1788            ConnectiveOperator::Negation => NODE_KIND_LOGICAL_OP_NEGATION,
1789            ConnectiveOperator::Conjunction => NODE_KIND_LOGICAL_OP_CONJUNCTION,
1790            ConnectiveOperator::Disjunction => NODE_KIND_LOGICAL_OP_DISJUNCTION,
1791            ConnectiveOperator::ExclusiveDisjunction => NODE_KIND_LOGICAL_OP_EXCLUSIVE_DISJUNCTION,
1792            ConnectiveOperator::Implication => NODE_KIND_LOGICAL_OP_IMPLICATION,
1793            ConnectiveOperator::Biconditional => NODE_KIND_LOGICAL_OP_BICONDITIONAL,
1794        });
1795        set!(value_map, FIELD_NAME_RHS => self.right_operand().to_json_with(opts));
1796    }
1797}
1798
1799impl ToJson for QuantifiedSentence {
1800    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1801        set!(value_map => NODE_KIND_QUANTIFIED_SENTENCE);
1802        set_source_span!(self, value_map, opts);
1803        set!(value_map, FIELD_NAME_BINDING => self.binding().to_json_with(opts));
1804        set!(value_map, FIELD_NAME_SENTENCE => self.body().to_json_with(opts));
1805    }
1806}
1807
1808impl ToJson for QuantifiedVariableBinding {
1809    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1810        set!(value_map => NODE_KIND_QUANTIFIED_VARIABLE_BINDING);
1811        set_source_span!(self, value_map, opts);
1812        set!(
1813            value_map,
1814            FIELD_NAME_QUANTIFIER =>
1815            self.quantifier().to_string()
1816        );
1817        set!(value_map, FIELD_NAME_BINDING => self.binding().to_json_with(opts));
1818    }
1819}
1820
1821impl ToJson for QuantifiedVariable {
1822    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1823        set!(value_map => NODE_KIND_QUANTIFIED_VARIABLE);
1824        set_source_span!(self, value_map, opts);
1825        set!(value_map, FIELD_NAME_VARIABLE => self.variable().to_json_with(opts));
1826        set!(value_map, FIELD_NAME_SOURCE => self.source().to_json_with(opts));
1827    }
1828}
1829
1830impl ToJson for Term {
1831    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1832        set_variant!(value_map, opts => NODE_KIND_TERM);
1833
1834        match self {
1835            Self::Sequence(v) => set_variant!(value_map, opts => v, NODE_VARIANT_SEQUENCE),
1836            Self::Function(v) => set_variant!(value_map, opts => v, NODE_VARIANT_FUNCTION),
1837            Self::Composition(v) => set_variant!(value_map, opts => v, NODE_VARIANT_COMPOSITION),
1838            Self::Identifier(v) => set_variant!(value_map, opts => v, NODE_VARIANT_IDENTIFIER),
1839            Self::ReservedSelf => {
1840                set!(value_map, NODE_VARIANT_SELF => true);
1841            }
1842            Self::Value(v) => set_variant!(value_map, opts => v, NODE_VARIANT_VALUE),
1843        }
1844    }
1845}
1846
1847impl ToJson for SequenceBuilder {
1848    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1849        set!(value_map => NODE_KIND_SEQUENCE_BUILDER);
1850        set_source_span!(self, value_map, opts);
1851        let mut variable_array: Vec<Value> = Vec::default();
1852        for variable in self.variables() {
1853            variable_array.push(variable.to_json_with(opts));
1854        }
1855        set!(value_map, FIELD_NAME_VARIABLES => Value::Array(variable_array));
1856        set!(value_map, FIELD_NAME_BODY => self.body().to_json_with(opts));
1857    }
1858}
1859
1860impl ToJson for Variable {
1861    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, _opts: ValueOptions) {
1862        set!(value_map => NODE_KIND_VARIABLE);
1863        set!(value_map, FIELD_NAME_NAME => self.name().as_ref());
1864        if let Some(range) = self.range() {
1865            set!(value_map, FIELD_NAME_RANGE => range.to_string().as_str());
1866        }
1867    }
1868}
1869
1870impl ToJson for FunctionalTerm {
1871    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1872        set!(value_map => NODE_KIND_FUNCTIONAL_TERM);
1873        set_source_span!(self, value_map, opts);
1874        set!(value_map, FIELD_NAME_FUNCTION => self.function().to_json_with(opts));
1875        add_collection!(
1876            value_map,
1877            opts,
1878            self,
1879            has_arguments,
1880            arguments,
1881            FIELD_NAME_ARGUMENTS
1882        );
1883    }
1884}
1885
1886impl ToJson for FunctionComposition {
1887    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1888        set!(value_map => NODE_KIND_FUNCTION_COMPOSITION);
1889        set_source_span!(self, value_map, opts);
1890        set!(value_map, FIELD_NAME_SUBJECT => self.subject().to_json_with(opts));
1891        add_collection!(
1892            value_map,
1893            opts,
1894            self,
1895            has_function_names,
1896            function_names,
1897            FIELD_NAME_FUNCTIONS
1898        );
1899    }
1900}
1901
1902impl ToJson for Subject {
1903    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1904        set_variant!(value_map, opts => NODE_KIND_SUBJECT);
1905
1906        match self {
1907            Self::ReservedSelf => {
1908                set!(value_map, NODE_VARIANT_SELF => true);
1909            }
1910            Self::Identifier(v) => set_variant!(value_map, opts => v, NODE_VARIANT_IDENTIFIER),
1911        }
1912    }
1913}
1914
1915impl ToJson for TypeVariable {
1916    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1917        set!(value_map => NODE_KIND_TYPE_VARIABLE);
1918        set_source_span!(self, value_map, opts);
1919        set!(value_map, opts, name => self);
1920        if let Some(cardinality) = self.cardinality() {
1921            set!(value_map, FIELD_NAME_CARDINALITY => cardinality.to_json_with(opts));
1922        }
1923        add_collection!(
1924            value_map,
1925            opts,
1926            self,
1927            has_restrictions,
1928            restrictions,
1929            FIELD_NAME_RESTRICTION
1930        );
1931    }
1932}
1933
1934impl ToJson for TypeClassReference {
1935    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1936        set!(value_map => NODE_KIND_TYPE_CLASS_REFERENCE);
1937        set_source_span!(self, value_map, opts);
1938        set!(value_map, opts, name => self);
1939        add_collection!(
1940            value_map,
1941            opts,
1942            self,
1943            has_arguments,
1944            arguments,
1945            FIELD_NAME_ARGUMENTS
1946        );
1947    }
1948}
1949
1950impl ToJson for TypeClassArgument {
1951    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1952        add_enum!(self,
1953            value_map, opts => NODE_KIND_TYPE_CLASS_ARGUMENT
1954            ; Reference => NODE_VARIANT_REFERENCE
1955            ; ! Wildcard => NODE_VARIANT_WILDCARD
1956        );
1957    }
1958}
1959
1960impl ToJson for MethodDef {
1961    fn add_to_json_with(&self, value_map: &mut Map<String, Value>, opts: ValueOptions) {
1962        set!(value_map => NODE_KIND_METHOD_DEF);
1963        set_source_span!(self, value_map, opts);
1964        set!(value_map, opts, name => self);
1965        set!(value_map, FIELD_NAME_SIGNATURE => self.signature().to_json_with(opts));
1966        if let Some(body) = self.body() {
1967            set!(value_map, FIELD_NAME_BODY => body.to_json_with(opts));
1968        }
1969        add_annotations!(value_map, opts, self);
1970    }
1971}
1972
1973// ------------------------------------------------------------------------------------------------
1974// Private Functions
1975// ------------------------------------------------------------------------------------------------
1976
1977#[inline(always)]
1978fn into_generator_error(e: serde_json::Error) -> Error {
1979    println!("{e:#?}");
1980    Error::GeneratorError {
1981        name: "JSON".into(),
1982        message: e.to_string(),
1983    }
1984}