Enable iterating over validator's parameters with a callback
This is how we'll construct parameters interactively. We need to lookup the definition, and provide a data representation for it.
This commit is contained in:
parent
051e9a6851
commit
961e323c36
|
@ -5,6 +5,7 @@ use super::{
|
||||||
schema::{Annotated, Schema},
|
schema::{Annotated, Schema},
|
||||||
};
|
};
|
||||||
use crate::module::{CheckedModule, CheckedModules};
|
use crate::module::{CheckedModule, CheckedModules};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use aiken_lang::{
|
use aiken_lang::{
|
||||||
ast::{TypedArg, TypedFunction, TypedValidator},
|
ast::{TypedArg, TypedFunction, TypedValidator},
|
||||||
|
@ -12,7 +13,10 @@ use aiken_lang::{
|
||||||
};
|
};
|
||||||
use miette::NamedSource;
|
use miette::NamedSource;
|
||||||
use serde;
|
use serde;
|
||||||
use uplc::ast::{DeBruijn, Program, Term};
|
use uplc::{
|
||||||
|
ast::{Constant, DeBruijn, Program, Term},
|
||||||
|
PlutusData,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct Validator {
|
pub struct Validator {
|
||||||
|
@ -174,6 +178,39 @@ impl Validator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ask_next_parameter<F>(
|
||||||
|
&self,
|
||||||
|
definitions: &Definitions<Annotated<Schema>>,
|
||||||
|
ask: F,
|
||||||
|
) -> Result<Term<DeBruijn>, Error>
|
||||||
|
where
|
||||||
|
F: Fn(&Annotated<Schema>, &Definitions<Annotated<Schema>>) -> Result<PlutusData, Error>,
|
||||||
|
{
|
||||||
|
match self.parameters.split_first() {
|
||||||
|
None => Err(Error::NoParametersToApply),
|
||||||
|
Some((head, _)) => {
|
||||||
|
let schema = definitions
|
||||||
|
.lookup(&head.schema)
|
||||||
|
.map(|s| {
|
||||||
|
Ok(Annotated {
|
||||||
|
title: s.title.clone().or_else(|| head.title.clone()),
|
||||||
|
description: s.description.clone(),
|
||||||
|
annotated: s.annotated.clone(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
Err(Error::UnresolvedSchemaReference {
|
||||||
|
reference: head.schema.clone(),
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let data = ask(&schema, definitions)?;
|
||||||
|
|
||||||
|
Ok(Term::Constant(Rc::new(Constant::Data(data.clone()))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -15,7 +15,11 @@ pub mod telemetry;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
use crate::blueprint::Blueprint;
|
use crate::blueprint::{
|
||||||
|
definitions::Definitions,
|
||||||
|
schema::{Annotated, Schema},
|
||||||
|
Blueprint,
|
||||||
|
};
|
||||||
use aiken_lang::{
|
use aiken_lang::{
|
||||||
ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction, Validator},
|
ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction, Validator},
|
||||||
builtins,
|
builtins,
|
||||||
|
@ -44,6 +48,7 @@ use telemetry::EventListener;
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{DeBruijn, Name, Program, Term},
|
ast::{DeBruijn, Name, Program, Term},
|
||||||
machine::cost_model::ExBudget,
|
machine::cost_model::ExBudget,
|
||||||
|
PlutusData,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -416,6 +421,36 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn construct_parameter_incrementally<F>(
|
||||||
|
&self,
|
||||||
|
title: Option<&String>,
|
||||||
|
ask: F,
|
||||||
|
) -> Result<Term<DeBruijn>, Error>
|
||||||
|
where
|
||||||
|
F: Fn(
|
||||||
|
&Annotated<Schema>,
|
||||||
|
&Definitions<Annotated<Schema>>,
|
||||||
|
) -> Result<PlutusData, blueprint::error::Error>,
|
||||||
|
{
|
||||||
|
// Read blueprint
|
||||||
|
let blueprint = File::open(self.blueprint_path())
|
||||||
|
.map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?;
|
||||||
|
let blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?;
|
||||||
|
|
||||||
|
// Construct parameter
|
||||||
|
let when_too_many =
|
||||||
|
|known_validators| Error::MoreThanOneValidatorFound { known_validators };
|
||||||
|
let when_missing = |known_validators| Error::NoValidatorNotFound { known_validators };
|
||||||
|
|
||||||
|
let term = blueprint.with_validator(title, when_too_many, when_missing, |validator| {
|
||||||
|
validator
|
||||||
|
.ask_next_parameter(&blueprint.definitions, &ask)
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(term)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn apply_parameter(
|
pub fn apply_parameter(
|
||||||
&self,
|
&self,
|
||||||
title: Option<&String>,
|
title: Option<&String>,
|
||||||
|
|
Loading…
Reference in New Issue