Implement 'blueprint apply' command.

This is still a bit clunky as the interface is expecting parameters in UPLC form and we don't do any kind of verification. So it is easy to shoot oneself in the foot at the moment (for example, to apply an integer into something that should have received a data). To be improved later.
This commit is contained in:
KtorZ
2023-02-04 11:39:55 +01:00
parent ea269b14a2
commit 9b8ff590b8
7 changed files with 112 additions and 14 deletions

View File

@@ -129,14 +129,16 @@ impl<T> Validator<T>
where
T: Clone,
{
pub fn apply(&mut self, arg: &Term<DeBruijn>) -> Result<(), Error> {
pub fn apply(self, arg: &Term<DeBruijn>) -> Result<Self, Error> {
match self.parameters.split_first() {
None => Err(Error::NoParametersToApply),
Some((_, tail)) => {
// TODO: Ideally, we should control that the applied term matches its schema.
self.program = self.program.apply_term(arg);
self.parameters = tail.to_vec();
Ok(())
Ok(Self {
program: self.program.apply_term(arg),
parameters: tail.to_vec(),
..self
})
}
}
}

View File

@@ -331,20 +331,32 @@ where
// Read blueprint
let blueprint = File::open(self.blueprint_path())
.map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?;
let blueprint: Blueprint<serde_json::Value> =
let mut blueprint: Blueprint<serde_json::Value> =
serde_json::from_reader(BufReader::new(blueprint))?;
// Apply parameters
let when_too_many =
|known_validators| Error::MoreThanOneValidatorFound { known_validators };
let when_missing = |known_validators| Error::NoValidatorNotFound { known_validators };
blueprint.with_validator(
title,
purpose,
when_too_many,
when_missing,
|mut validator| validator.apply(param).map_err(|e| e.into()),
)?;
let applied_validator =
blueprint.with_validator(title, purpose, when_too_many, when_missing, |validator| {
validator.apply(param).map_err(|e| e.into())
})?;
// Overwrite validator
blueprint.validators = blueprint
.validators
.into_iter()
.map(|validator| {
let same_title = validator.title == applied_validator.title;
let same_purpose = validator.purpose == applied_validator.purpose;
if same_title && same_purpose {
applied_validator.to_owned()
} else {
validator
}
})
.collect();
Ok(blueprint)
}