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#[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 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 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 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 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 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 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 #[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
119impl 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
128impl 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
137impl 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
146impl 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
155impl 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#[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
326impl 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#[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#[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#[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
592impl 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#[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
673impl 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#[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
753impl 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}