use serde::{Deserialize, Serialize};
use std::{collections::HashMap, rc::Rc};
#[derive(Debug, PartialEq, Eq)]
pub struct Scope {
pub(crate) symbols: HashMap<String, Symbol>,
pub(crate) parent: Option<Rc<Scope>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Symbol {
EnvVar(String, Box<Type>),
ParamVar(String, Box<Type>),
LocalExpr(Box<DataExpr>),
Output(usize),
Input(Box<InputBlock>),
Reference(Box<ReferenceBlock>),
PartyDef(Box<PartyDef>),
PolicyDef(Box<PolicyDef>),
AssetDef(Box<AssetDef>),
TypeDef(Box<TypeDef>),
AliasDef(Box<AliasDef>),
RecordField(Box<RecordField>),
VariantCase(Box<VariantCase>),
Function(String),
Fees,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Span {
dummy: bool,
pub start: usize,
pub end: usize,
}
impl Default for Span {
fn default() -> Self {
Self::DUMMY
}
}
impl Eq for Span {}
impl PartialEq for Span {
fn eq(&self, other: &Self) -> bool {
if self.dummy || other.dummy {
return true;
}
self.start == other.start && self.end == other.end
}
}
impl std::hash::Hash for Span {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.start.hash(state);
self.end.hash(state);
}
}
impl Span {
pub const DUMMY: Self = Self {
dummy: true,
start: 0,
end: 0,
};
pub fn new(start: usize, end: usize) -> Self {
Self {
dummy: false,
start,
end,
}
}
}
impl Symbol {
pub fn as_type_def(&self) -> Option<&TypeDef> {
match self {
Symbol::TypeDef(x) => Some(x.as_ref()),
_ => None,
}
}
pub fn as_alias_def(&self) -> Option<&AliasDef> {
match self {
Symbol::AliasDef(x) => Some(x.as_ref()),
_ => None,
}
}
pub fn as_variant_case(&self) -> Option<&VariantCase> {
match self {
Symbol::VariantCase(x) => Some(x.as_ref()),
_ => None,
}
}
pub fn as_field_def(&self) -> Option<&RecordField> {
match self {
Symbol::RecordField(x) => Some(x.as_ref()),
_ => None,
}
}
pub fn as_policy_def(&self) -> Option<&PolicyDef> {
match self {
Symbol::PolicyDef(x) => Some(x.as_ref()),
_ => None,
}
}
pub fn target_type(&self) -> Option<Type> {
match self {
Symbol::ParamVar(_, ty) => Some(ty.as_ref().clone()),
Symbol::RecordField(x) => Some(x.r#type.clone()),
Symbol::Input(x) => x.datum_is().cloned(),
Symbol::Reference(x) => x.datum_is.clone(),
x => {
dbg!(x);
None
}
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Identifier {
pub value: String,
pub span: Span,
#[serde(skip)]
pub(crate) symbol: Option<Symbol>,
}
impl Identifier {
pub fn new(value: impl Into<String>) -> Self {
Self {
value: value.into(),
symbol: None,
span: Span::DUMMY,
}
}
pub fn try_symbol(&self) -> Result<&Symbol, crate::lowering::Error> {
match &self.symbol {
Some(symbol) => Ok(symbol),
None => Err(crate::lowering::Error::MissingAnalyzePhase(
self.value.clone(),
)),
}
}
pub fn target_type(&self) -> Option<Type> {
self.symbol.as_ref().and_then(|x| x.target_type())
}
}
impl AsRef<str> for Identifier {
fn as_ref(&self) -> &str {
&self.value
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct Program {
pub env: Option<EnvDef>,
pub txs: Vec<TxDef>,
pub types: Vec<TypeDef>,
pub aliases: Vec<AliasDef>,
pub assets: Vec<AssetDef>,
pub parties: Vec<PartyDef>,
pub policies: Vec<PolicyDef>,
pub span: Span,
#[serde(skip)]
pub(crate) scope: Option<Rc<Scope>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct EnvField {
pub name: String,
pub r#type: Type,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct EnvDef {
pub fields: Vec<EnvField>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ParameterList {
pub parameters: Vec<ParamDef>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct TxDef {
pub name: Identifier,
pub parameters: ParameterList,
pub locals: Option<LocalsBlock>,
pub references: Vec<ReferenceBlock>,
pub inputs: Vec<InputBlock>,
pub outputs: Vec<OutputBlock>,
pub validity: Option<ValidityBlock>,
pub mints: Vec<MintBlock>,
pub burns: Vec<MintBlock>,
pub signers: Option<SignersBlock>,
pub adhoc: Vec<ChainSpecificBlock>,
pub span: Span,
pub collateral: Vec<CollateralBlock>,
pub metadata: Option<MetadataBlock>,
#[serde(skip)]
pub(crate) scope: Option<Rc<Scope>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct LocalsAssign {
pub name: Identifier,
pub value: DataExpr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct LocalsBlock {
pub assigns: Vec<LocalsAssign>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct StringLiteral {
pub value: String,
pub span: Span,
}
impl StringLiteral {
pub fn new(value: impl Into<String>) -> Self {
Self {
value: value.into(),
span: Span::DUMMY,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct HexStringLiteral {
pub value: String,
pub span: Span,
}
impl HexStringLiteral {
pub fn new(value: impl Into<String>) -> Self {
Self {
value: value.into(),
span: Span::DUMMY,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum CollateralBlockField {
From(DataExpr),
MinAmount(DataExpr),
Ref(DataExpr),
}
impl CollateralBlockField {
fn key(&self) -> &str {
match self {
CollateralBlockField::From(_) => "from",
CollateralBlockField::MinAmount(_) => "min_amount",
CollateralBlockField::Ref(_) => "ref",
}
}
pub fn as_data_expr(&self) -> Option<&DataExpr> {
match self {
CollateralBlockField::Ref(x) => Some(x),
_ => None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct CollateralBlock {
pub fields: Vec<CollateralBlockField>,
pub span: Span,
}
impl CollateralBlock {
pub(crate) fn find(&self, key: &str) -> Option<&CollateralBlockField> {
self.fields.iter().find(|x| x.key() == key)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum InputBlockField {
From(DataExpr),
DatumIs(Type),
MinAmount(DataExpr),
Redeemer(DataExpr),
Ref(DataExpr),
}
impl InputBlockField {
fn key(&self) -> &str {
match self {
InputBlockField::From(_) => "from",
InputBlockField::DatumIs(_) => "datum_is",
InputBlockField::MinAmount(_) => "min_amount",
InputBlockField::Redeemer(_) => "redeemer",
InputBlockField::Ref(_) => "ref",
}
}
pub fn as_data_expr(&self) -> Option<&DataExpr> {
match self {
InputBlockField::Redeemer(x) => Some(x),
InputBlockField::Ref(x) => Some(x),
_ => None,
}
}
pub fn as_datum_type(&self) -> Option<&Type> {
match self {
InputBlockField::DatumIs(x) => Some(x),
_ => None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ReferenceBlock {
pub name: String,
pub r#ref: DataExpr,
pub datum_is: Option<Type>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct MetadataBlockField {
pub key: DataExpr,
pub value: DataExpr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct MetadataBlock {
pub fields: Vec<MetadataBlockField>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct InputBlock {
pub name: String,
pub many: bool,
pub fields: Vec<InputBlockField>,
pub span: Span,
}
impl InputBlock {
pub(crate) fn find(&self, key: &str) -> Option<&InputBlockField> {
self.fields.iter().find(|x| x.key() == key)
}
pub(crate) fn datum_is(&self) -> Option<&Type> {
self.find("datum_is").and_then(|x| x.as_datum_type())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum OutputBlockField {
To(Box<DataExpr>),
Amount(Box<DataExpr>),
Datum(Box<DataExpr>),
}
impl OutputBlockField {
fn key(&self) -> &str {
match self {
OutputBlockField::To(_) => "to",
OutputBlockField::Amount(_) => "amount",
OutputBlockField::Datum(_) => "datum",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct OutputBlock {
pub name: Option<Identifier>,
pub optional: bool,
pub fields: Vec<OutputBlockField>,
pub span: Span,
}
impl OutputBlock {
pub(crate) fn find(&self, key: &str) -> Option<&OutputBlockField> {
self.fields.iter().find(|x| x.key() == key)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ValidityBlockField {
UntilSlot(Box<DataExpr>),
SinceSlot(Box<DataExpr>),
}
impl ValidityBlockField {
fn key(&self) -> &str {
match self {
ValidityBlockField::UntilSlot(_) => "until_slot",
ValidityBlockField::SinceSlot(_) => "since_slot",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ValidityBlock {
pub fields: Vec<ValidityBlockField>,
pub span: Span,
}
impl ValidityBlock {
pub(crate) fn find(&self, key: &str) -> Option<&ValidityBlockField> {
self.fields.iter().find(|x| x.key() == key)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum MintBlockField {
Amount(Box<DataExpr>),
Redeemer(Box<DataExpr>),
}
impl MintBlockField {
fn key(&self) -> &str {
match self {
MintBlockField::Amount(_) => "amount",
MintBlockField::Redeemer(_) => "redeemer",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct MintBlock {
pub fields: Vec<MintBlockField>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SignersBlock {
pub signers: Vec<DataExpr>,
pub span: Span,
}
impl MintBlock {
pub(crate) fn find(&self, key: &str) -> Option<&MintBlockField> {
self.fields.iter().find(|x| x.key() == key)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RecordField {
pub name: Identifier,
pub r#type: Type,
pub span: Span,
}
impl RecordField {
pub fn new(name: &str, r#type: Type) -> Self {
Self {
name: Identifier::new(name),
r#type,
span: Span::DUMMY,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct PartyDef {
pub name: Identifier,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct PartyField {
pub name: String,
pub party_type: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct PolicyDef {
pub name: Identifier,
pub value: PolicyValue,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum PolicyField {
Hash(DataExpr),
Script(DataExpr),
Ref(DataExpr),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct PolicyConstructor {
pub fields: Vec<PolicyField>,
pub span: Span,
}
impl PolicyConstructor {
pub(crate) fn find_field(&self, field: &str) -> Option<&PolicyField> {
self.fields.iter().find(|x| match x {
PolicyField::Hash(_) => field == "hash",
PolicyField::Script(_) => field == "script",
PolicyField::Ref(_) => field == "ref",
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum PolicyValue {
Constructor(PolicyConstructor),
Assign(HexStringLiteral),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AnyAssetConstructor {
pub policy: Box<DataExpr>,
pub asset_name: Box<DataExpr>,
pub amount: Box<DataExpr>,
pub span: Span,
}
impl AnyAssetConstructor {
pub fn target_type(&self) -> Option<Type> {
Some(Type::AnyAsset)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RecordConstructorField {
pub name: Identifier,
pub value: Box<DataExpr>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct StructConstructor {
pub r#type: Identifier,
pub case: VariantCaseConstructor,
pub span: Span,
#[serde(skip)]
pub scope: Option<Rc<Scope>>,
}
impl StructConstructor {
pub fn target_type(&self) -> Option<Type> {
self.r#type.symbol.as_ref().and_then(|x| x.target_type())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct VariantCaseConstructor {
pub name: Identifier,
pub fields: Vec<RecordConstructorField>,
pub spread: Option<Box<DataExpr>>,
pub span: Span,
#[serde(skip)]
pub scope: Option<Rc<Scope>>,
}
impl VariantCaseConstructor {
pub fn find_field_value(&self, field: &str) -> Option<&DataExpr> {
self.fields
.iter()
.find(|x| x.name.value == field)
.map(|x| x.value.as_ref())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ListConstructor {
pub elements: Vec<DataExpr>,
pub span: Span,
}
impl ListConstructor {
pub fn target_type(&self) -> Option<Type> {
self.elements.first().and_then(|x| x.target_type())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct MapField {
pub key: DataExpr,
pub value: DataExpr,
pub span: Span,
}
impl MapField {
pub fn target_type(&self) -> Option<Type> {
self.key.target_type()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct MapConstructor {
pub fields: Vec<MapField>,
pub span: Span,
}
impl MapConstructor {
pub fn target_type(&self) -> Option<Type> {
if let Some(first_field) = self.fields.first() {
let key_type = first_field.key.target_type()?;
let value_type = first_field.value.target_type()?;
Some(Type::Map(Box::new(key_type), Box::new(value_type)))
} else {
None
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct UtxoRef {
pub txid: Vec<u8>,
pub index: u64,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct NegateOp {
pub operand: Box<DataExpr>,
pub span: Span,
}
impl NegateOp {
pub fn target_type(&self) -> Option<Type> {
self.operand.target_type()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct PropertyOp {
pub operand: Box<DataExpr>,
pub property: Box<DataExpr>,
pub span: Span,
#[serde(skip)]
pub(crate) scope: Option<Rc<Scope>>,
}
impl PropertyOp {
pub fn target_type(&self) -> Option<Type> {
self.property.target_type()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AddOp {
pub lhs: Box<DataExpr>,
pub rhs: Box<DataExpr>,
pub span: Span,
}
impl AddOp {
pub fn target_type(&self) -> Option<Type> {
self.lhs.target_type()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SubOp {
pub lhs: Box<DataExpr>,
pub rhs: Box<DataExpr>,
pub span: Span,
}
impl SubOp {
pub fn target_type(&self) -> Option<Type> {
self.lhs.target_type()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ConcatOp {
pub lhs: Box<DataExpr>,
pub rhs: Box<DataExpr>,
pub span: Span,
}
impl ConcatOp {
pub fn target_type(&self) -> Option<Type> {
self.lhs.target_type()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct FnCall {
pub callee: Identifier,
pub args: Vec<DataExpr>,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum DataExpr {
None,
Unit,
Number(i64),
Bool(bool),
String(StringLiteral),
HexString(HexStringLiteral),
StructConstructor(StructConstructor),
ListConstructor(ListConstructor),
MapConstructor(MapConstructor),
AnyAssetConstructor(AnyAssetConstructor),
Identifier(Identifier),
MinUtxo(Identifier),
ComputeTipSlot,
SlotToTime(Box<DataExpr>),
TimeToSlot(Box<DataExpr>),
AddOp(AddOp),
SubOp(SubOp),
ConcatOp(ConcatOp),
NegateOp(NegateOp),
PropertyOp(PropertyOp),
UtxoRef(UtxoRef),
FnCall(FnCall),
}
impl DataExpr {
pub fn as_identifier(&self) -> Option<&Identifier> {
match self {
DataExpr::Identifier(x) => Some(x),
_ => None,
}
}
pub fn target_type(&self) -> Option<Type> {
match self {
DataExpr::Identifier(x) => x.target_type(),
DataExpr::None => Some(Type::Undefined),
DataExpr::Unit => Some(Type::Unit),
DataExpr::Number(_) => Some(Type::Int),
DataExpr::Bool(_) => Some(Type::Bool),
DataExpr::String(_) => Some(Type::Bytes),
DataExpr::HexString(_) => Some(Type::Bytes),
DataExpr::StructConstructor(x) => x.target_type(),
DataExpr::MapConstructor(x) => x.target_type(),
DataExpr::ListConstructor(x) => match x.target_type() {
Some(inner) => Some(Type::List(Box::new(inner))),
None => None,
},
DataExpr::AddOp(x) => x.target_type(),
DataExpr::SubOp(x) => x.target_type(),
DataExpr::ConcatOp(x) => x.target_type(),
DataExpr::NegateOp(x) => x.target_type(),
DataExpr::PropertyOp(x) => x.target_type(),
DataExpr::AnyAssetConstructor(x) => x.target_type(),
DataExpr::UtxoRef(_) => Some(Type::UtxoRef),
DataExpr::MinUtxo(_) => Some(Type::AnyAsset),
DataExpr::ComputeTipSlot => Some(Type::Int),
DataExpr::SlotToTime(_) => Some(Type::Int),
DataExpr::TimeToSlot(_) => Some(Type::Int),
DataExpr::FnCall(_) => None, }
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum AddressExpr {
String(StringLiteral),
HexString(HexStringLiteral),
Identifier(Identifier),
}
impl AddressExpr {
pub fn as_identifier(&self) -> Option<&Identifier> {
match self {
AddressExpr::Identifier(x) => Some(x),
_ => None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum Type {
Undefined,
Unit,
Int,
Bool,
Bytes,
Address,
Utxo,
UtxoRef,
AnyAsset,
List(Box<Type>),
Map(Box<Type>, Box<Type>),
Custom(Identifier),
}
impl std::fmt::Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Type::Undefined => write!(f, "Undefined"),
Type::Unit => write!(f, "Unit"),
Type::Int => write!(f, "Int"),
Type::Bool => write!(f, "Bool"),
Type::Bytes => write!(f, "Bytes"),
Type::Address => write!(f, "Address"),
Type::UtxoRef => write!(f, "UtxoRef"),
Type::AnyAsset => write!(f, "AnyAsset"),
Type::Utxo => write!(f, "Utxo"),
Type::Map(key, value) => write!(f, "Map<{}, {}>", key, value),
Type::List(inner) => write!(f, "List<{inner}>"),
Type::Custom(id) => write!(f, "{}", id.value),
}
}
}
impl Type {
pub fn properties(&self) -> Vec<(String, Type)> {
match self {
Type::AnyAsset => {
vec![
("amount".to_string(), Type::Int),
("policy".to_string(), Type::Bytes),
("asset_name".to_string(), Type::Bytes),
]
}
Type::UtxoRef => {
vec![
("tx_hash".to_string(), Type::Bytes),
("output_index".to_string(), Type::Int),
]
}
Type::Custom(identifier) => {
let def = identifier.symbol.as_ref().and_then(|s| s.as_type_def());
match def {
Some(ty) if ty.cases.len() == 1 => ty.cases[0]
.fields
.iter()
.map(|f| (f.name.value.clone(), f.r#type.clone()))
.collect(),
_ => vec![],
}
}
_ => vec![],
}
}
pub fn property_index(&self, property: DataExpr) -> Option<DataExpr> {
match self {
Type::AnyAsset | Type::UtxoRef | Type::Custom(_) => {
let identifier = property.as_identifier()?;
let properties = Self::properties(self);
properties
.iter()
.position(|(name, _)| name == &identifier.value)
.map(|index| DataExpr::Number(index as i64))
}
Type::List(_) => property
.target_type()
.filter(|ty| *ty == Type::Int)
.map(|_| property),
_ => None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ParamDef {
pub name: Identifier,
pub r#type: Type,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AliasDef {
pub name: Identifier,
pub alias_type: Type,
pub span: Span,
}
impl AliasDef {
pub fn resolve_alias_chain(&self) -> Option<&TypeDef> {
match &self.alias_type {
Type::Custom(identifier) => match &identifier.symbol {
Some(Symbol::TypeDef(type_def)) => Some(type_def),
Some(Symbol::AliasDef(next_alias)) => next_alias.resolve_alias_chain(),
_ => None,
},
_ => None,
}
}
pub fn is_alias_chain_resolved(&self) -> bool {
self.resolve_alias_chain().is_some()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct TypeDef {
pub name: Identifier,
pub cases: Vec<VariantCase>,
pub span: Span,
}
impl TypeDef {
pub(crate) fn find_case_index(&self, case: &str) -> Option<usize> {
self.cases.iter().position(|x| x.name.value == case)
}
#[allow(dead_code)]
pub(crate) fn find_case(&self, case: &str) -> Option<&VariantCase> {
self.cases.iter().find(|x| x.name.value == case)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct VariantCase {
pub name: Identifier,
pub fields: Vec<RecordField>,
pub span: Span,
}
impl VariantCase {
#[allow(dead_code)]
pub(crate) fn find_field_index(&self, field: &str) -> Option<usize> {
self.fields.iter().position(|x| x.name.value == field)
}
#[allow(dead_code)]
pub(crate) fn find_field(&self, field: &str) -> Option<&RecordField> {
self.fields.iter().find(|x| x.name.value == field)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AssetDef {
pub name: Identifier,
pub policy: DataExpr,
pub asset_name: DataExpr,
pub span: Span,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ChainSpecificBlock {
Cardano(crate::cardano::CardanoBlock),
}