1use serde::{Deserialize, Serialize};
12use std::{collections::HashMap, rc::Rc};
13
14#[derive(Debug, PartialEq, Eq)]
15pub struct Scope {
16 pub(crate) symbols: HashMap<String, Symbol>,
17 pub(crate) parent: Option<Rc<Scope>>,
18}
19
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub enum Symbol {
22 EnvVar(String, Box<Type>),
23 ParamVar(String, Box<Type>),
24 LocalExpr(Box<DataExpr>),
25 Input(Box<InputBlock>),
26 PartyDef(Box<PartyDef>),
27 PolicyDef(Box<PolicyDef>),
28 AssetDef(Box<AssetDef>),
29 TypeDef(Box<TypeDef>),
30 RecordField(Box<RecordField>),
31 VariantCase(Box<VariantCase>),
32 Fees,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct Span {
37 dummy: bool,
38 pub start: usize,
39 pub end: usize,
40}
41
42impl Default for Span {
43 fn default() -> Self {
44 Self::DUMMY
45 }
46}
47
48impl Eq for Span {}
49
50impl PartialEq for Span {
51 fn eq(&self, other: &Self) -> bool {
52 if self.dummy || other.dummy {
53 return true;
54 }
55
56 self.start == other.start && self.end == other.end
57 }
58}
59
60impl std::hash::Hash for Span {
61 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
62 self.start.hash(state);
63 self.end.hash(state);
64 }
65}
66
67impl Span {
68 pub const DUMMY: Self = Self {
69 dummy: true,
70 start: 0,
71 end: 0,
72 };
73
74 pub fn new(start: usize, end: usize) -> Self {
75 Self {
76 dummy: false,
77 start,
78 end,
79 }
80 }
81}
82
83impl Symbol {
84 pub fn as_type_def(&self) -> Option<&TypeDef> {
85 match self {
86 Symbol::TypeDef(x) => Some(x.as_ref()),
87 _ => None,
88 }
89 }
90
91 pub fn as_variant_case(&self) -> Option<&VariantCase> {
92 match self {
93 Symbol::VariantCase(x) => Some(x.as_ref()),
94 _ => None,
95 }
96 }
97
98 pub fn as_field_def(&self) -> Option<&RecordField> {
99 match self {
100 Symbol::RecordField(x) => Some(x.as_ref()),
101 _ => None,
102 }
103 }
104
105 pub fn as_policy_def(&self) -> Option<&PolicyDef> {
106 match self {
107 Symbol::PolicyDef(x) => Some(x.as_ref()),
108 _ => None,
109 }
110 }
111
112 pub fn target_type(&self) -> Option<Type> {
113 match self {
114 Symbol::ParamVar(_, ty) => Some(ty.as_ref().clone()),
115 Symbol::RecordField(x) => Some(x.r#type.clone()),
116 Symbol::Input(x) => x.datum_is().cloned(),
117 x => {
118 dbg!(x);
119 None
120 }
121 }
122 }
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
126pub struct Identifier {
127 pub value: String,
128 pub span: Span,
129
130 #[serde(skip)]
132 pub(crate) symbol: Option<Symbol>,
133}
134
135impl Identifier {
136 pub fn new(value: impl Into<String>) -> Self {
137 Self {
138 value: value.into(),
139 symbol: None,
140 span: Span::DUMMY,
141 }
142 }
143
144 pub fn try_symbol(&self) -> Result<&Symbol, crate::lowering::Error> {
145 match &self.symbol {
146 Some(symbol) => Ok(symbol),
147 None => Err(crate::lowering::Error::MissingAnalyzePhase(
148 self.value.clone(),
149 )),
150 }
151 }
152
153 pub fn target_type(&self) -> Option<Type> {
154 self.symbol.as_ref().and_then(|x| x.target_type())
155 }
156}
157
158impl AsRef<str> for Identifier {
159 fn as_ref(&self) -> &str {
160 &self.value
161 }
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
165pub struct Program {
166 pub env: Option<EnvDef>,
167 pub txs: Vec<TxDef>,
168 pub types: Vec<TypeDef>,
169 pub assets: Vec<AssetDef>,
170 pub parties: Vec<PartyDef>,
171 pub policies: Vec<PolicyDef>,
172 pub span: Span,
173
174 #[serde(skip)]
176 pub(crate) scope: Option<Rc<Scope>>,
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
180pub struct EnvField {
181 pub name: String,
182 pub r#type: Type,
183 pub span: Span,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
187pub struct EnvDef {
188 pub fields: Vec<EnvField>,
189 pub span: Span,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
193pub struct ParameterList {
194 pub parameters: Vec<ParamDef>,
195 pub span: Span,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
199pub struct TxDef {
200 pub name: Identifier,
201 pub parameters: ParameterList,
202 pub locals: Option<LocalsBlock>,
203 pub references: Vec<ReferenceBlock>,
204 pub inputs: Vec<InputBlock>,
205 pub outputs: Vec<OutputBlock>,
206 pub validity: Option<ValidityBlock>,
207 pub burn: Option<BurnBlock>,
208 pub mints: Vec<MintBlock>,
209 pub signers: Option<SignersBlock>,
210 pub adhoc: Vec<ChainSpecificBlock>,
211 pub span: Span,
212 pub collateral: Vec<CollateralBlock>,
213 pub metadata: Option<MetadataBlock>,
214
215 #[serde(skip)]
217 pub(crate) scope: Option<Rc<Scope>>,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
221pub struct LocalsAssign {
222 pub name: Identifier,
223 pub value: DataExpr,
224 pub span: Span,
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
228pub struct LocalsBlock {
229 pub assigns: Vec<LocalsAssign>,
230 pub span: Span,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
234pub struct StringLiteral {
235 pub value: String,
236 pub span: Span,
237}
238
239impl StringLiteral {
240 pub fn new(value: impl Into<String>) -> Self {
241 Self {
242 value: value.into(),
243 span: Span::DUMMY,
244 }
245 }
246}
247
248#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
249pub struct HexStringLiteral {
250 pub value: String,
251 pub span: Span,
252}
253
254impl HexStringLiteral {
255 pub fn new(value: impl Into<String>) -> Self {
256 Self {
257 value: value.into(),
258 span: Span::DUMMY,
259 }
260 }
261}
262
263#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
264pub enum CollateralBlockField {
265 From(DataExpr),
266 MinAmount(DataExpr),
267 Ref(DataExpr),
268}
269
270impl CollateralBlockField {
271 fn key(&self) -> &str {
272 match self {
273 CollateralBlockField::From(_) => "from",
274 CollateralBlockField::MinAmount(_) => "min_amount",
275 CollateralBlockField::Ref(_) => "ref",
276 }
277 }
278
279 pub fn as_data_expr(&self) -> Option<&DataExpr> {
280 match self {
281 CollateralBlockField::Ref(x) => Some(x),
282 _ => None,
283 }
284 }
285}
286
287#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
288pub struct CollateralBlock {
289 pub fields: Vec<CollateralBlockField>,
290 pub span: Span,
291}
292
293impl CollateralBlock {
294 pub(crate) fn find(&self, key: &str) -> Option<&CollateralBlockField> {
295 self.fields.iter().find(|x| x.key() == key)
296 }
297}
298
299#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
300pub enum InputBlockField {
301 From(DataExpr),
302 DatumIs(Type),
303 MinAmount(DataExpr),
304 Redeemer(DataExpr),
305 Ref(DataExpr),
306}
307
308impl InputBlockField {
309 fn key(&self) -> &str {
310 match self {
311 InputBlockField::From(_) => "from",
312 InputBlockField::DatumIs(_) => "datum_is",
313 InputBlockField::MinAmount(_) => "min_amount",
314 InputBlockField::Redeemer(_) => "redeemer",
315 InputBlockField::Ref(_) => "ref",
316 }
317 }
318
319 pub fn as_data_expr(&self) -> Option<&DataExpr> {
320 match self {
321 InputBlockField::Redeemer(x) => Some(x),
322 InputBlockField::Ref(x) => Some(x),
323 _ => None,
324 }
325 }
326
327 pub fn as_datum_type(&self) -> Option<&Type> {
328 match self {
329 InputBlockField::DatumIs(x) => Some(x),
330 _ => None,
331 }
332 }
333}
334
335#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
336pub struct ReferenceBlock {
337 pub name: String,
338 pub r#ref: DataExpr,
339 pub span: Span,
340}
341
342#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
343pub struct MetadataBlockField {
344 pub key: DataExpr,
345 pub value: DataExpr,
346 pub span: Span,
347}
348
349#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
350pub struct MetadataBlock {
351 pub fields: Vec<MetadataBlockField>,
352 pub span: Span,
353}
354
355#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
356pub struct InputBlock {
357 pub name: String,
358 pub is_many: bool,
359 pub fields: Vec<InputBlockField>,
360 pub span: Span,
361}
362
363impl InputBlock {
364 pub(crate) fn find(&self, key: &str) -> Option<&InputBlockField> {
365 self.fields.iter().find(|x| x.key() == key)
366 }
367
368 pub(crate) fn datum_is(&self) -> Option<&Type> {
369 self.find("datum_is").and_then(|x| x.as_datum_type())
370 }
371}
372
373#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
374pub enum OutputBlockField {
375 To(Box<DataExpr>),
376 Amount(Box<DataExpr>),
377 Datum(Box<DataExpr>),
378}
379
380impl OutputBlockField {
381 fn key(&self) -> &str {
382 match self {
383 OutputBlockField::To(_) => "to",
384 OutputBlockField::Amount(_) => "amount",
385 OutputBlockField::Datum(_) => "datum",
386 }
387 }
388}
389
390#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
391pub struct OutputBlock {
392 pub name: Option<String>,
393 pub fields: Vec<OutputBlockField>,
394 pub span: Span,
395}
396
397impl OutputBlock {
398 pub(crate) fn find(&self, key: &str) -> Option<&OutputBlockField> {
399 self.fields.iter().find(|x| x.key() == key)
400 }
401}
402
403#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
404pub enum ValidityBlockField {
405 UntilSlot(Box<DataExpr>),
406 SinceSlot(Box<DataExpr>),
407}
408
409impl ValidityBlockField {
410 fn key(&self) -> &str {
411 match self {
412 ValidityBlockField::UntilSlot(_) => "until_slot",
413 ValidityBlockField::SinceSlot(_) => "since_slot",
414 }
415 }
416}
417
418#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
419pub struct ValidityBlock {
420 pub fields: Vec<ValidityBlockField>,
421 pub span: Span,
422}
423
424impl ValidityBlock {
425 pub(crate) fn find(&self, key: &str) -> Option<&ValidityBlockField> {
426 self.fields.iter().find(|x| x.key() == key)
427 }
428}
429
430#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
431pub enum MintBlockField {
432 Amount(Box<DataExpr>),
433 Redeemer(Box<DataExpr>),
434}
435
436impl MintBlockField {
437 fn key(&self) -> &str {
438 match self {
439 MintBlockField::Amount(_) => "amount",
440 MintBlockField::Redeemer(_) => "redeemer",
441 }
442 }
443}
444
445#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
446pub struct MintBlock {
447 pub fields: Vec<MintBlockField>,
448 pub span: Span,
449}
450
451#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
452pub struct SignersBlock {
453 pub signers: Vec<DataExpr>,
454 pub span: Span,
455}
456
457impl MintBlock {
458 pub(crate) fn find(&self, key: &str) -> Option<&MintBlockField> {
459 self.fields.iter().find(|x| x.key() == key)
460 }
461}
462
463#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
464pub struct BurnBlock {
465 pub fields: Vec<MintBlockField>,
466 pub span: Span,
467}
468
469#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
470pub struct RecordField {
471 pub name: Identifier,
472 pub r#type: Type,
473 pub span: Span,
474}
475
476impl RecordField {
477 pub fn new(name: &str, r#type: Type) -> Self {
478 Self {
479 name: Identifier::new(name),
480 r#type,
481 span: Span::DUMMY,
482 }
483 }
484}
485
486#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
487pub struct PartyDef {
488 pub name: Identifier,
489 pub span: Span,
490}
491
492#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
493pub struct PartyField {
494 pub name: String,
495 pub party_type: String,
496}
497
498#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
499pub struct PolicyDef {
500 pub name: Identifier,
501 pub value: PolicyValue,
502 pub span: Span,
503}
504
505#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
506pub enum PolicyField {
507 Hash(DataExpr),
508 Script(DataExpr),
509 Ref(DataExpr),
510}
511
512#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
513pub struct PolicyConstructor {
514 pub fields: Vec<PolicyField>,
515 pub span: Span,
516}
517
518impl PolicyConstructor {
519 pub(crate) fn find_field(&self, field: &str) -> Option<&PolicyField> {
520 self.fields.iter().find(|x| match x {
521 PolicyField::Hash(_) => field == "hash",
522 PolicyField::Script(_) => field == "script",
523 PolicyField::Ref(_) => field == "ref",
524 })
525 }
526}
527
528#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
529pub enum PolicyValue {
530 Constructor(PolicyConstructor),
531 Assign(HexStringLiteral),
532}
533
534#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
535pub struct StaticAssetConstructor {
536 pub r#type: Identifier,
537 pub amount: Box<DataExpr>,
538 pub span: Span,
539}
540
541impl StaticAssetConstructor {
542 pub fn target_type(&self) -> Option<Type> {
543 Some(Type::AnyAsset)
544 }
545}
546
547#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
548pub struct AnyAssetConstructor {
549 pub policy: Box<DataExpr>,
550 pub asset_name: Box<DataExpr>,
551 pub amount: Box<DataExpr>,
552 pub span: Span,
553}
554
555impl AnyAssetConstructor {
556 pub fn target_type(&self) -> Option<Type> {
557 Some(Type::AnyAsset)
558 }
559}
560
561#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
562pub struct RecordConstructorField {
563 pub name: Identifier,
564 pub value: Box<DataExpr>,
565 pub span: Span,
566}
567
568#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
569pub struct StructConstructor {
570 pub r#type: Identifier,
571 pub case: VariantCaseConstructor,
572 pub span: Span,
573
574 #[serde(skip)]
576 pub scope: Option<Rc<Scope>>,
577}
578
579impl StructConstructor {
580 pub fn target_type(&self) -> Option<Type> {
581 self.r#type.symbol.as_ref().and_then(|x| x.target_type())
582 }
583}
584
585#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
586pub struct VariantCaseConstructor {
587 pub name: Identifier,
588 pub fields: Vec<RecordConstructorField>,
589 pub spread: Option<Box<DataExpr>>,
590 pub span: Span,
591
592 #[serde(skip)]
594 pub scope: Option<Rc<Scope>>,
595}
596
597impl VariantCaseConstructor {
598 pub fn find_field_value(&self, field: &str) -> Option<&DataExpr> {
599 self.fields
600 .iter()
601 .find(|x| x.name.value == field)
602 .map(|x| x.value.as_ref())
603 }
604}
605
606#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
607pub struct ListConstructor {
608 pub elements: Vec<DataExpr>,
609 pub span: Span,
610}
611
612impl ListConstructor {
613 pub fn target_type(&self) -> Option<Type> {
614 self.elements.first().and_then(|x| x.target_type())
615 }
616}
617
618#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
619pub struct UtxoRef {
620 pub txid: Vec<u8>,
621 pub index: u64,
622 pub span: Span,
623}
624
625#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
626pub struct NegateOp {
627 pub operand: Box<DataExpr>,
628 pub span: Span,
629}
630
631impl NegateOp {
632 pub fn target_type(&self) -> Option<Type> {
633 self.operand.target_type()
634 }
635}
636
637#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
638pub struct PropertyOp {
639 pub operand: Box<DataExpr>,
640 pub property: Box<Identifier>,
641 pub span: Span,
642
643 #[serde(skip)]
645 pub(crate) scope: Option<Rc<Scope>>,
646}
647
648impl PropertyOp {
649 pub fn target_type(&self) -> Option<Type> {
650 self.property.target_type()
651 }
652}
653
654#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
655pub struct AddOp {
656 pub lhs: Box<DataExpr>,
657 pub rhs: Box<DataExpr>,
658 pub span: Span,
659}
660
661impl AddOp {
662 pub fn target_type(&self) -> Option<Type> {
663 self.lhs.target_type()
664 }
665}
666
667#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
668pub struct SubOp {
669 pub lhs: Box<DataExpr>,
670 pub rhs: Box<DataExpr>,
671 pub span: Span,
672}
673
674impl SubOp {
675 pub fn target_type(&self) -> Option<Type> {
676 self.lhs.target_type()
677 }
678}
679
680#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
681pub enum DataExpr {
682 None,
683 Unit,
684 Number(i64),
685 Bool(bool),
686 String(StringLiteral),
687 HexString(HexStringLiteral),
688 StructConstructor(StructConstructor),
689 ListConstructor(ListConstructor),
690 StaticAssetConstructor(StaticAssetConstructor),
691 AnyAssetConstructor(AnyAssetConstructor),
692 Identifier(Identifier),
693 AddOp(AddOp),
694 SubOp(SubOp),
695 NegateOp(NegateOp),
696 PropertyOp(PropertyOp),
697 UtxoRef(UtxoRef),
698}
699
700impl DataExpr {
701 pub fn as_identifier(&self) -> Option<&Identifier> {
702 match self {
703 DataExpr::Identifier(x) => Some(x),
704 _ => None,
705 }
706 }
707
708 pub fn target_type(&self) -> Option<Type> {
709 match self {
710 DataExpr::Identifier(x) => x.target_type(),
711 DataExpr::None => Some(Type::Undefined),
712 DataExpr::Unit => Some(Type::Unit),
713 DataExpr::Number(_) => Some(Type::Int),
714 DataExpr::Bool(_) => Some(Type::Bool),
715 DataExpr::String(_) => Some(Type::Bytes),
716 DataExpr::HexString(_) => Some(Type::Bytes),
717 DataExpr::StructConstructor(x) => x.target_type(),
718 DataExpr::ListConstructor(x) => x.target_type(),
719 DataExpr::AddOp(x) => x.target_type(),
720 DataExpr::SubOp(x) => x.target_type(),
721 DataExpr::NegateOp(x) => x.target_type(),
722 DataExpr::PropertyOp(x) => x.target_type(),
723 DataExpr::StaticAssetConstructor(x) => x.target_type(),
724 DataExpr::AnyAssetConstructor(x) => x.target_type(),
725 DataExpr::UtxoRef(_) => Some(Type::UtxoRef),
726 }
727 }
728}
729
730#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
731pub enum AddressExpr {
732 String(StringLiteral),
733 HexString(HexStringLiteral),
734 Identifier(Identifier),
735}
736
737impl AddressExpr {
738 pub fn as_identifier(&self) -> Option<&Identifier> {
739 match self {
740 AddressExpr::Identifier(x) => Some(x),
741 _ => None,
742 }
743 }
744}
745
746#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
747pub enum Type {
748 Undefined,
749 Unit,
750 Int,
751 Bool,
752 Bytes,
753 Address,
754 Utxo,
755 UtxoRef,
756 AnyAsset,
757 List(Box<Type>),
758 Custom(Identifier),
759}
760
761impl std::fmt::Display for Type {
762 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
763 match self {
764 Type::Undefined => write!(f, "Undefined"),
765 Type::Unit => write!(f, "Unit"),
766 Type::Int => write!(f, "Int"),
767 Type::Bool => write!(f, "Bool"),
768 Type::Bytes => write!(f, "Bytes"),
769 Type::Address => write!(f, "Address"),
770 Type::UtxoRef => write!(f, "UtxoRef"),
771 Type::AnyAsset => write!(f, "AnyAsset"),
772 Type::Utxo => write!(f, "Utxo"),
773 Type::List(inner) => write!(f, "List<{}>", inner),
774 Type::Custom(id) => write!(f, "{}", id.value),
775 }
776 }
777}
778
779impl Type {
780 pub fn properties(&self) -> Vec<(String, Type)> {
781 match self {
782 Type::AnyAsset => {
783 vec![
784 ("amount".to_string(), Type::Int),
785 ("policy".to_string(), Type::Bytes),
786 ("asset_name".to_string(), Type::Bytes),
787 ]
788 }
789 Type::UtxoRef => {
790 vec![
791 ("tx_hash".to_string(), Type::Bytes),
792 ("output_index".to_string(), Type::Int),
793 ]
794 }
795 Type::Custom(identifier) => {
796 let def = identifier.symbol.as_ref().and_then(|s| s.as_type_def());
797
798 match def {
799 Some(ty) if ty.cases.len() == 1 => ty.cases[0]
800 .fields
801 .iter()
802 .map(|f| (f.name.value.clone(), f.r#type.clone()))
803 .collect(),
804 _ => vec![],
805 }
806 }
807 _ => vec![],
808 }
809 }
810
811 pub fn property_index(&self, property: &str) -> Option<usize> {
812 let properties = Self::properties(self);
813 properties.iter().position(|(name, _)| name == property)
814 }
815}
816
817#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
818pub struct ParamDef {
819 pub name: Identifier,
820 pub r#type: Type,
821}
822
823#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
824pub struct TypeDef {
825 pub name: Identifier,
826 pub cases: Vec<VariantCase>,
827 pub span: Span,
828}
829
830impl TypeDef {
831 pub(crate) fn find_case_index(&self, case: &str) -> Option<usize> {
832 self.cases.iter().position(|x| x.name.value == case)
833 }
834
835 #[allow(dead_code)]
836 pub(crate) fn find_case(&self, case: &str) -> Option<&VariantCase> {
837 self.cases.iter().find(|x| x.name.value == case)
838 }
839}
840
841#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
842pub struct VariantCase {
843 pub name: Identifier,
844 pub fields: Vec<RecordField>,
845 pub span: Span,
846}
847
848impl VariantCase {
849 #[allow(dead_code)]
850 pub(crate) fn find_field_index(&self, field: &str) -> Option<usize> {
851 self.fields.iter().position(|x| x.name.value == field)
852 }
853
854 #[allow(dead_code)]
855 pub(crate) fn find_field(&self, field: &str) -> Option<&RecordField> {
856 self.fields.iter().find(|x| x.name.value == field)
857 }
858}
859
860#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
861pub struct AssetDef {
862 pub name: Identifier,
863 pub policy: DataExpr,
864 pub asset_name: DataExpr,
865 pub span: Span,
866}
867
868#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
869pub enum ChainSpecificBlock {
870 Cardano(crate::cardano::CardanoBlock),
871}