daml_lf/element/
daml_data.rs

1use crate::element::daml_field::DamlField;
2use crate::element::visitor::DamlElementVisitor;
3#[cfg(feature = "full")]
4use crate::element::{DamlExpr, DamlPrimLit};
5use crate::element::{DamlTyConName, DamlType, DamlTypeVarWithKind, DamlVisitableElement};
6use bounded_static::ToStatic;
7use serde::Serialize;
8use std::borrow::Cow;
9
10/// A Daml Data item (template, record, variant or enum).
11#[derive(Debug, Serialize, Clone, ToStatic)]
12pub enum DamlData<'a> {
13    Template(Box<DamlTemplate<'a>>),
14    Record(DamlRecord<'a>),
15    Variant(DamlVariant<'a>),
16    Enum(DamlEnum<'a>),
17}
18
19impl<'a> DamlData<'a> {
20    /// The name of this data type.
21    pub fn name(&self) -> &str {
22        match self {
23            DamlData::Record(record) => &record.name,
24            DamlData::Template(template) => &template.name,
25            DamlData::Variant(variant) => &variant.name,
26            DamlData::Enum(data_enum) => &data_enum.name,
27        }
28    }
29
30    /// The id of the package which contains this `DamlData`.
31    pub fn package_id(&self) -> &str {
32        match self {
33            DamlData::Record(record) => &record.package_id,
34            DamlData::Template(template) => &template.package_id,
35            DamlData::Variant(variant) => &variant.package_id,
36            DamlData::Enum(data_enum) => &data_enum.package_id,
37        }
38    }
39
40    /// The path to the module which contains this `DamlData`.
41    pub fn module_path(&self) -> impl Iterator<Item = &str> {
42        match self {
43            DamlData::Record(record) => record.module_path.iter().map(AsRef::as_ref),
44            DamlData::Template(template) => template.module_path.iter().map(AsRef::as_ref),
45            DamlData::Variant(variant) => variant.module_path.iter().map(AsRef::as_ref),
46            DamlData::Enum(data_enum) => data_enum.module_path.iter().map(AsRef::as_ref),
47        }
48    }
49
50    /// The fields of this data type.
51    pub fn fields(&self) -> &[DamlField<'_>] {
52        match self {
53            DamlData::Record(record) => &record.fields,
54            DamlData::Template(template) => &template.fields,
55            DamlData::Variant(variant) => &variant.fields,
56            DamlData::Enum(_) => &[],
57        }
58    }
59
60    /// The type parameters applied to this data type.
61    pub fn type_params(&self) -> &[DamlTypeVarWithKind<'_>] {
62        match self {
63            DamlData::Record(record) => &record.type_params,
64            DamlData::Template(_) => &[],
65            DamlData::Variant(variant) => &variant.type_params,
66            DamlData::Enum(data_enum) => &data_enum.type_params,
67        }
68    }
69
70    /// Is this data type serializable?
71    pub fn serializable(&self) -> bool {
72        match self {
73            DamlData::Record(record) => record.serializable,
74            DamlData::Template(template) => template.serializable,
75            DamlData::Variant(variant) => variant.serializable,
76            DamlData::Enum(data_enum) => data_enum.serializable,
77        }
78    }
79
80    /// The name of this data type.
81    ///
82    /// This is a clone of a `Cow<str>` which is cheap for the borrowed case used within the library.
83    #[doc(hidden)]
84    pub(crate) fn name_clone(&self) -> Cow<'a, str> {
85        match self {
86            DamlData::Record(record) => record.name.clone(),
87            DamlData::Template(template) => template.name.clone(),
88            DamlData::Variant(variant) => variant.name.clone(),
89            DamlData::Enum(data_enum) => data_enum.name.clone(),
90        }
91    }
92}
93
94impl<'a> DamlVisitableElement<'a> for DamlData<'a> {
95    fn accept(&'a self, visitor: &'a mut impl DamlElementVisitor) {
96        visitor.pre_visit_data(self);
97        match self {
98            DamlData::Record(record) => record.accept(visitor),
99            DamlData::Template(template) => template.accept(visitor),
100            DamlData::Variant(variant) => variant.accept(visitor),
101            DamlData::Enum(data_enum) => data_enum.accept(visitor),
102        }
103        visitor.post_visit_data(self);
104    }
105}
106
107impl PartialEq<DamlData<'_>> for DamlData<'_> {
108    fn eq(&self, other: &DamlData<'_>) -> bool {
109        match (self, other) {
110            (DamlData::Record(a), DamlData::Record(b)) => a.eq(b),
111            (DamlData::Template(a), DamlData::Template(b)) => a.eq(b),
112            (DamlData::Variant(a), DamlData::Variant(b)) => a.eq(b),
113            (DamlData::Enum(a), DamlData::Enum(b)) => a.eq(b),
114            _ => false,
115        }
116    }
117}
118
119/// Convenience impl to compare a `DamlTyConName` with a `DamlData`.
120impl PartialEq<DamlTyConName<'_>> for DamlData<'_> {
121    fn eq(&self, tycon: &DamlTyConName<'_>) -> bool {
122        tycon.package_id() == self.package_id()
123            && cmp_all(tycon.module_path(), self.module_path())
124            && tycon.data_name() == self.name()
125    }
126}
127
128/// Convenience impl to compare a `DamlTemplate` with a `DamlData`.
129impl PartialEq<DamlTemplate<'_>> for DamlData<'_> {
130    fn eq(&self, other: &DamlTemplate<'_>) -> bool {
131        other.package_id() == self.package_id()
132            && cmp_all(other.module_path(), self.module_path())
133            && other.name() == self.name()
134    }
135}
136
137/// Convenience impl to compare a `DamlRecord` with a `DamlData`.
138impl PartialEq<DamlRecord<'_>> for DamlData<'_> {
139    fn eq(&self, other: &DamlRecord<'_>) -> bool {
140        other.package_id() == self.package_id()
141            && cmp_all(other.module_path(), self.module_path())
142            && other.name() == self.name()
143    }
144}
145
146/// Convenience impl to compare a `DamlVariant` with a `DamlData`.
147impl PartialEq<DamlVariant<'_>> for DamlData<'_> {
148    fn eq(&self, other: &DamlVariant<'_>) -> bool {
149        other.package_id() == self.package_id()
150            && cmp_all(other.module_path(), self.module_path())
151            && other.name() == self.name()
152    }
153}
154
155/// Convenience impl to compare a `DamlEnum` with a `DamlData`.
156impl PartialEq<DamlEnum<'_>> for DamlData<'_> {
157    fn eq(&self, other: &DamlEnum<'_>) -> bool {
158        other.package_id() == self.package_id()
159            && cmp_all(other.module_path(), self.module_path())
160            && other.name() == self.name()
161    }
162}
163
164/// A Daml template.
165#[derive(Debug, Serialize, Clone, ToStatic)]
166pub struct DamlTemplate<'a> {
167    name: Cow<'a, str>,
168    package_id: Cow<'a, str>,
169    module_path: Vec<Cow<'a, str>>,
170    fields: Vec<DamlField<'a>>,
171    choices: Vec<DamlChoice<'a>>,
172    param: Cow<'a, str>,
173    #[cfg(feature = "full")]
174    precond: Option<DamlExpr<'a>>,
175    #[cfg(feature = "full")]
176    signatories: DamlExpr<'a>,
177    #[cfg(feature = "full")]
178    agreement: DamlExpr<'a>,
179    #[cfg(feature = "full")]
180    observers: DamlExpr<'a>,
181    key: Option<DamlDefKey<'a>>,
182    serializable: bool,
183}
184
185impl<'a> DamlTemplate<'a> {
186    #[allow(clippy::too_many_arguments)]
187    pub fn new(
188        name: Cow<'a, str>,
189        package_id: Cow<'a, str>,
190        module_path: Vec<Cow<'a, str>>,
191        fields: Vec<DamlField<'a>>,
192        choices: Vec<DamlChoice<'a>>,
193        param: Cow<'a, str>,
194        #[cfg(feature = "full")] precond: Option<DamlExpr<'a>>,
195        #[cfg(feature = "full")] signatories: DamlExpr<'a>,
196        #[cfg(feature = "full")] agreement: DamlExpr<'a>,
197        #[cfg(feature = "full")] observers: DamlExpr<'a>,
198        key: Option<DamlDefKey<'a>>,
199        serializable: bool,
200    ) -> Self {
201        Self {
202            name,
203            package_id,
204            module_path,
205            fields,
206            choices,
207            param,
208            #[cfg(feature = "full")]
209            precond,
210            #[cfg(feature = "full")]
211            signatories,
212            #[cfg(feature = "full")]
213            agreement,
214            #[cfg(feature = "full")]
215            observers,
216            key,
217            serializable,
218        }
219    }
220
221    pub fn new_with_defaults(
222        name: Cow<'a, str>,
223        package_id: Cow<'a, str>,
224        module_path: Vec<Cow<'a, str>>,
225        fields: Vec<DamlField<'a>>,
226    ) -> Self {
227        Self {
228            name,
229            package_id,
230            module_path,
231            fields,
232            choices: vec![],
233            param: Cow::default(),
234            #[cfg(feature = "full")]
235            precond: None,
236            #[cfg(feature = "full")]
237            signatories: DamlExpr::Nil(DamlType::List(vec![DamlType::Party])),
238            #[cfg(feature = "full")]
239            agreement: DamlExpr::PrimLit(DamlPrimLit::Text(Cow::default())),
240            #[cfg(feature = "full")]
241            observers: DamlExpr::Nil(DamlType::List(vec![DamlType::Party])),
242            key: None,
243            serializable: true,
244        }
245    }
246
247    pub fn name(&self) -> &str {
248        &self.name
249    }
250
251    pub fn package_id(&self) -> &str {
252        &self.package_id
253    }
254
255    pub fn module_path(&self) -> impl Iterator<Item = &str> {
256        self.module_path.iter().map(AsRef::as_ref)
257    }
258
259    pub fn fields(&self) -> &[DamlField<'a>] {
260        &self.fields
261    }
262
263    pub fn choices(&self) -> &[DamlChoice<'a>] {
264        &self.choices
265    }
266
267    pub fn param(&self) -> &str {
268        &self.param
269    }
270
271    #[cfg(feature = "full")]
272    pub fn precond(&self) -> Option<&DamlExpr<'a>> {
273        self.precond.as_ref()
274    }
275
276    #[cfg(feature = "full")]
277    pub fn signatories(&self) -> &DamlExpr<'a> {
278        &self.signatories
279    }
280
281    #[cfg(feature = "full")]
282    pub fn agreement(&self) -> &DamlExpr<'a> {
283        &self.agreement
284    }
285
286    #[cfg(feature = "full")]
287    pub fn observers(&self) -> &DamlExpr<'a> {
288        &self.observers
289    }
290
291    pub fn key(&self) -> Option<&DamlDefKey<'a>> {
292        self.key.as_ref()
293    }
294
295    pub const fn serializable(&self) -> bool {
296        self.serializable
297    }
298}
299
300impl<'a> DamlVisitableElement<'a> for DamlTemplate<'a> {
301    fn accept(&'a self, visitor: &'a mut impl DamlElementVisitor) {
302        visitor.pre_visit_template(self);
303        self.fields.iter().for_each(|field| field.accept(visitor));
304        self.choices.iter().for_each(|choice| choice.accept(visitor));
305        #[cfg(feature = "full")]
306        self.precond.iter().for_each(|pre| pre.accept(visitor));
307        #[cfg(feature = "full")]
308        self.signatories.accept(visitor);
309        #[cfg(feature = "full")]
310        self.agreement.accept(visitor);
311        #[cfg(feature = "full")]
312        self.observers.accept(visitor);
313        self.key.iter().for_each(|k| k.accept(visitor));
314        visitor.post_visit_template(self);
315    }
316}
317
318impl PartialEq<DamlTemplate<'_>> for DamlTemplate<'_> {
319    fn eq(&self, other: &DamlTemplate<'_>) -> bool {
320        other.package_id() == self.package_id()
321            && cmp_all(other.module_path(), self.module_path())
322            && other.name() == self.name()
323    }
324}
325
326/// Convenience impl to compare a `DamlData` with a `DamlTemplate`.
327impl PartialEq<DamlData<'_>> for DamlTemplate<'_> {
328    fn eq(&self, data: &DamlData<'_>) -> bool {
329        data.package_id() == self.package_id()
330            && cmp_all(data.module_path(), self.module_path())
331            && data.name() == self.name()
332    }
333}
334
335/// A Daml template choice.
336#[derive(Debug, Serialize, Clone, ToStatic)]
337pub struct DamlChoice<'a> {
338    name: Cow<'a, str>,
339    package_id: Cow<'a, str>,
340    module_path: Vec<Cow<'a, str>>,
341    fields: Vec<DamlField<'a>>,
342    return_type: DamlType<'a>,
343    consuming: bool,
344    self_binder: Cow<'a, str>,
345    #[cfg(feature = "full")]
346    update: DamlExpr<'a>,
347    #[cfg(feature = "full")]
348    controllers: DamlExpr<'a>,
349    #[cfg(feature = "full")]
350    observers: DamlExpr<'a>,
351}
352
353impl<'a> DamlChoice<'a> {
354    #[allow(clippy::too_many_arguments)]
355    pub fn new(
356        name: Cow<'a, str>,
357        package_id: Cow<'a, str>,
358        module_path: Vec<Cow<'a, str>>,
359        fields: Vec<DamlField<'a>>,
360        return_type: DamlType<'a>,
361        consuming: bool,
362        self_binder: Cow<'a, str>,
363        #[cfg(feature = "full")] update: DamlExpr<'a>,
364        #[cfg(feature = "full")] controllers: DamlExpr<'a>,
365        #[cfg(feature = "full")] observers: DamlExpr<'a>,
366    ) -> Self {
367        Self {
368            name,
369            package_id,
370            module_path,
371            fields,
372            return_type,
373            consuming,
374            self_binder,
375            #[cfg(feature = "full")]
376            update,
377            #[cfg(feature = "full")]
378            controllers,
379            #[cfg(feature = "full")]
380            observers,
381        }
382    }
383
384    pub fn new_with_default(
385        name: Cow<'a, str>,
386        package_id: Cow<'a, str>,
387        module_path: Vec<Cow<'a, str>>,
388        fields: Vec<DamlField<'a>>,
389        return_type: DamlType<'a>,
390    ) -> Self {
391        Self {
392            name,
393            package_id,
394            module_path,
395            fields,
396            return_type,
397            consuming: false,
398            self_binder: Cow::default(),
399            #[cfg(feature = "full")]
400            update: DamlExpr::Nil(DamlType::List(vec![DamlType::Party])),
401            #[cfg(feature = "full")]
402            controllers: DamlExpr::Nil(DamlType::List(vec![DamlType::Party])),
403            #[cfg(feature = "full")]
404            observers: DamlExpr::Nil(DamlType::List(vec![DamlType::Party])),
405        }
406    }
407
408    pub fn name(&self) -> &str {
409        &self.name
410    }
411
412    pub fn package_id(&self) -> &str {
413        &self.package_id
414    }
415
416    pub fn module_path(&self) -> impl Iterator<Item = &str> {
417        self.module_path.iter().map(AsRef::as_ref)
418    }
419
420    pub fn fields(&self) -> &[DamlField<'a>] {
421        &self.fields
422    }
423
424    pub const fn return_type(&self) -> &DamlType<'a> {
425        &self.return_type
426    }
427
428    pub const fn consuming(&self) -> bool {
429        self.consuming
430    }
431
432    pub fn self_binder(&self) -> &str {
433        &self.self_binder
434    }
435
436    #[cfg(feature = "full")]
437    pub fn update(&self) -> &DamlExpr<'a> {
438        &self.update
439    }
440
441    #[cfg(feature = "full")]
442    pub fn controllers(&self) -> &DamlExpr<'a> {
443        &self.controllers
444    }
445
446    #[cfg(feature = "full")]
447    pub fn observers(&self) -> &DamlExpr<'a> {
448        &self.observers
449    }
450}
451
452impl<'a> DamlVisitableElement<'a> for DamlChoice<'a> {
453    fn accept(&'a self, visitor: &'a mut impl DamlElementVisitor) {
454        visitor.pre_visit_choice(self);
455        self.fields.iter().for_each(|field| field.accept(visitor));
456        self.return_type.accept(visitor);
457        #[cfg(feature = "full")]
458        self.update.accept(visitor);
459        #[cfg(feature = "full")]
460        self.controllers.accept(visitor);
461        #[cfg(feature = "full")]
462        self.observers.accept(visitor);
463        visitor.post_visit_choice(self);
464    }
465}
466
467/// A Daml template key definition.
468// TODO fields should not be public
469#[derive(Debug, Serialize, Clone, ToStatic)]
470pub struct DamlDefKey<'a> {
471    pub ty: DamlType<'a>,
472    #[cfg(feature = "full")]
473    pub maintainers: DamlExpr<'a>,
474    #[cfg(feature = "full")]
475    pub key_expr: DamlExpr<'a>,
476}
477
478impl<'a> DamlDefKey<'a> {
479    pub fn new(
480        ty: DamlType<'a>,
481        #[cfg(feature = "full")] maintainers: DamlExpr<'a>,
482        #[cfg(feature = "full")] key_expr: DamlExpr<'a>,
483    ) -> Self {
484        Self {
485            ty,
486            #[cfg(feature = "full")]
487            maintainers,
488            #[cfg(feature = "full")]
489            key_expr,
490        }
491    }
492
493    pub fn ty(&self) -> &DamlType<'a> {
494        &self.ty
495    }
496
497    #[cfg(feature = "full")]
498    pub fn maintainers(&self) -> &DamlExpr<'a> {
499        &self.maintainers
500    }
501
502    #[cfg(feature = "full")]
503    pub fn key_expr(&self) -> &DamlExpr<'a> {
504        &self.key_expr
505    }
506}
507
508impl<'a> DamlVisitableElement<'a> for DamlDefKey<'a> {
509    fn accept(&'a self, visitor: &'a mut impl DamlElementVisitor) {
510        visitor.pre_visit_def_key(self);
511        self.ty.accept(visitor);
512        #[cfg(feature = "full")]
513        self.maintainers.accept(visitor);
514        #[cfg(feature = "full")]
515        self.key_expr.accept(visitor);
516        visitor.post_visit_def_key(self);
517    }
518}
519
520/// A Daml record.
521#[derive(Debug, Serialize, Clone, ToStatic)]
522pub struct DamlRecord<'a> {
523    name: Cow<'a, str>,
524    package_id: Cow<'a, str>,
525    module_path: Vec<Cow<'a, str>>,
526    fields: Vec<DamlField<'a>>,
527    type_params: Vec<DamlTypeVarWithKind<'a>>,
528    serializable: bool,
529}
530
531impl<'a> DamlRecord<'a> {
532    pub fn new(
533        name: Cow<'a, str>,
534        package_id: Cow<'a, str>,
535        module_path: Vec<Cow<'a, str>>,
536        fields: Vec<DamlField<'a>>,
537        type_params: Vec<DamlTypeVarWithKind<'a>>,
538        serializable: bool,
539    ) -> Self {
540        Self {
541            name,
542            package_id,
543            module_path,
544            fields,
545            type_params,
546            serializable,
547        }
548    }
549
550    pub fn name(&self) -> &str {
551        &self.name
552    }
553
554    pub fn package_id(&self) -> &str {
555        &self.package_id
556    }
557
558    pub fn module_path(&self) -> impl Iterator<Item = &str> {
559        self.module_path.iter().map(AsRef::as_ref)
560    }
561
562    pub fn fields(&self) -> &[DamlField<'a>] {
563        &self.fields
564    }
565
566    pub fn type_params(&self) -> &[DamlTypeVarWithKind<'a>] {
567        &self.type_params
568    }
569
570    pub const fn serializable(&self) -> bool {
571        self.serializable
572    }
573}
574
575impl<'a> DamlVisitableElement<'a> for DamlRecord<'a> {
576    fn accept(&'a self, visitor: &'a mut impl DamlElementVisitor) {
577        visitor.pre_visit_record(self);
578        self.fields.iter().for_each(|field| field.accept(visitor));
579        self.type_params.iter().for_each(|arg| arg.accept(visitor));
580        visitor.post_visit_record(self);
581    }
582}
583
584impl PartialEq<DamlRecord<'_>> for DamlRecord<'_> {
585    fn eq(&self, other: &DamlRecord<'_>) -> bool {
586        other.package_id() == self.package_id()
587            && cmp_all(other.module_path(), self.module_path())
588            && other.name() == self.name()
589    }
590}
591
592/// Convenience impl to compare a `DamlData` with a `DamlRecord`.
593impl PartialEq<DamlData<'_>> for DamlRecord<'_> {
594    fn eq(&self, data: &DamlData<'_>) -> bool {
595        data.package_id() == self.package_id()
596            && cmp_all(data.module_path(), self.module_path())
597            && data.name() == self.name()
598    }
599}
600
601/// A Daml variant.
602#[derive(Debug, Serialize, Clone, ToStatic)]
603pub struct DamlVariant<'a> {
604    name: Cow<'a, str>,
605    package_id: Cow<'a, str>,
606    module_path: Vec<Cow<'a, str>>,
607    fields: Vec<DamlField<'a>>,
608    type_params: Vec<DamlTypeVarWithKind<'a>>,
609    serializable: bool,
610}
611
612impl<'a> DamlVariant<'a> {
613    pub fn new(
614        name: Cow<'a, str>,
615        package_id: Cow<'a, str>,
616        module_path: Vec<Cow<'a, str>>,
617        fields: Vec<DamlField<'a>>,
618        type_params: Vec<DamlTypeVarWithKind<'a>>,
619        serializable: bool,
620    ) -> Self {
621        Self {
622            name,
623            package_id,
624            module_path,
625            fields,
626            type_params,
627            serializable,
628        }
629    }
630
631    pub fn name(&self) -> &str {
632        &self.name
633    }
634
635    pub fn package_id(&self) -> &str {
636        &self.package_id
637    }
638
639    pub fn module_path(&self) -> impl Iterator<Item = &str> {
640        self.module_path.iter().map(AsRef::as_ref)
641    }
642
643    pub fn fields(&self) -> &[DamlField<'a>] {
644        &self.fields
645    }
646
647    pub fn type_params(&self) -> &[DamlTypeVarWithKind<'a>] {
648        &self.type_params
649    }
650
651    pub const fn serializable(&self) -> bool {
652        self.serializable
653    }
654}
655
656impl<'a> DamlVisitableElement<'a> for DamlVariant<'a> {
657    fn accept(&'a self, visitor: &'a mut impl DamlElementVisitor) {
658        visitor.pre_visit_variant(self);
659        self.fields.iter().for_each(|field| field.accept(visitor));
660        self.type_params.iter().for_each(|arg| arg.accept(visitor));
661        visitor.post_visit_variant(self);
662    }
663}
664
665impl PartialEq<DamlVariant<'_>> for DamlVariant<'_> {
666    fn eq(&self, other: &DamlVariant<'_>) -> bool {
667        other.package_id() == self.package_id()
668            && cmp_all(other.module_path(), self.module_path())
669            && other.name() == self.name()
670    }
671}
672
673/// Convenience impl to compare a `DamlData` with a `DamlVariant`.
674impl PartialEq<DamlData<'_>> for DamlVariant<'_> {
675    fn eq(&self, data: &DamlData<'_>) -> bool {
676        data.package_id() == self.package_id()
677            && cmp_all(data.module_path(), self.module_path())
678            && data.name() == self.name()
679    }
680}
681
682/// A Daml enum.
683#[derive(Debug, Serialize, Clone, ToStatic)]
684pub struct DamlEnum<'a> {
685    name: Cow<'a, str>,
686    package_id: Cow<'a, str>,
687    module_path: Vec<Cow<'a, str>>,
688    constructors: Vec<Cow<'a, str>>,
689    type_params: Vec<DamlTypeVarWithKind<'a>>,
690    serializable: bool,
691}
692
693impl<'a> DamlEnum<'a> {
694    pub fn new(
695        name: Cow<'a, str>,
696        package_id: Cow<'a, str>,
697        module_path: Vec<Cow<'a, str>>,
698        constructors: Vec<Cow<'a, str>>,
699        type_params: Vec<DamlTypeVarWithKind<'a>>,
700        serializable: bool,
701    ) -> Self {
702        Self {
703            name,
704            package_id,
705            module_path,
706            constructors,
707            type_params,
708            serializable,
709        }
710    }
711
712    pub fn name(&self) -> &str {
713        &self.name
714    }
715
716    pub fn package_id(&self) -> &str {
717        &self.package_id
718    }
719
720    pub fn module_path(&self) -> impl Iterator<Item = &str> {
721        self.module_path.iter().map(AsRef::as_ref)
722    }
723
724    pub fn constructors(&self) -> impl Iterator<Item = &str> {
725        self.constructors.iter().map(AsRef::as_ref)
726    }
727
728    pub fn type_params(&self) -> &[DamlTypeVarWithKind<'a>] {
729        &self.type_params
730    }
731
732    pub const fn serializable(&self) -> bool {
733        self.serializable
734    }
735}
736
737impl<'a> DamlVisitableElement<'a> for DamlEnum<'a> {
738    fn accept(&'a self, visitor: &'a mut impl DamlElementVisitor) {
739        visitor.pre_visit_enum(self);
740        self.type_params.iter().for_each(|arg| arg.accept(visitor));
741        visitor.post_visit_enum(self);
742    }
743}
744
745impl PartialEq<DamlEnum<'_>> for DamlEnum<'_> {
746    fn eq(&self, other: &DamlEnum<'_>) -> bool {
747        other.package_id() == self.package_id()
748            && cmp_all(other.module_path(), self.module_path())
749            && other.name() == self.name()
750    }
751}
752
753/// Convenience impl to compare a `DamlData` with a `DamlEnum`.
754impl PartialEq<DamlData<'_>> for DamlEnum<'_> {
755    fn eq(&self, data: &DamlData<'_>) -> bool {
756        data.package_id() == self.package_id()
757            && cmp_all(data.module_path(), self.module_path())
758            && data.name() == self.name()
759    }
760}
761
762fn cmp_all<'a>(left: impl Iterator<Item = &'a str>, right: impl Iterator<Item = &'a str>) -> bool {
763    left.zip(right).all(|(x, y)| x == y)
764}