Turn evaluation hints into strings earlier, to make project's Error thread-safe.

This commit is contained in:
KtorZ 2023-11-24 09:44:02 +01:00
parent d04094560b
commit 1ca81ec133
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
3 changed files with 58 additions and 37 deletions

View File

@ -1,9 +1,6 @@
use crate::{
blueprint::error as blueprint, deps::manifest::Package, package_name::PackageName, pretty,
script::EvalHint,
};
use crate::{blueprint::error as blueprint, deps::manifest::Package, package_name::PackageName};
use aiken_lang::{
ast::{self, BinOp, Span},
ast::{self, Span},
error::ExtraData,
parser::error::ParseError,
tipo,
@ -18,7 +15,6 @@ use std::{
ops::Deref,
path::{Path, PathBuf},
};
use uplc::machine::cost_model::ExBudget;
use zip::result::ZipError;
#[allow(dead_code)]
@ -97,7 +93,7 @@ pub enum Error {
path: PathBuf,
verbose: bool,
src: String,
evaluation_hint: Option<EvalHint>,
evaluation_hint: Option<String>,
},
#[error(
@ -313,33 +309,9 @@ impl Diagnostic for Error {
Error::MissingManifest { .. } => Some(Box::new("Try running `aiken new <REPOSITORY/PROJECT>` to initialise a project with an example manifest.")),
Error::TomlLoading { .. } => None,
Error::Format { .. } => None,
Error::TestFailure { evaluation_hint, .. } =>{
match evaluation_hint {
None => None,
Some(hint) => {
let budget = ExBudget { mem: i64::MAX, cpu: i64::MAX, };
let left = pretty::boxed("left", &match hint.left.clone().eval(budget).result() {
Ok(term) => format!("{term}"),
Err(err) => format!("{err}"),
});
let right = pretty::boxed("right", &match hint.right.clone().eval(budget).result() {
Ok(term) => format!("{term}"),
Err(err) => format!("{err}"),
});
let msg = match hint.bin_op {
BinOp::And => Some(format!("{left}\n\nand\n\n{right}\n\nshould both be true.")),
BinOp::Or => Some(format!("{left}\n\nor\n\n{right}\n\nshould be true.")),
BinOp::Eq => Some(format!("{left}\n\nshould be equal to\n\n{right}")),
BinOp::NotEq => Some(format!("{left}\n\nshould not be equal to\n\n{right}")),
BinOp::LtInt => Some(format!("{left}\n\nshould be lower than\n\n{right}")),
BinOp::LtEqInt => Some(format!("{left}\n\nshould be lower than or equal to\n\n{right}")),
BinOp::GtEqInt => Some(format!("{left}\n\nshould be greater than\n\n{right}")),
BinOp::GtInt => Some(format!("{left}\n\nshould be greater than or equal to\n\n{right}")),
_ => None
}?;
Some(Box::new(msg))
}
}
Error::TestFailure { evaluation_hint, .. } => match evaluation_hint {
None => None,
Some(hint) => Some(Box::new(hint.to_string()))
},
Error::Http(_) => None,
Error::ZipExtract(_) => None,

View File

@ -329,7 +329,11 @@ where
Some(Error::TestFailure {
name: e.script.name.clone(),
path: e.script.input_path.clone(),
evaluation_hint: e.script.evaluation_hint.clone(),
evaluation_hint: e
.script
.evaluation_hint
.as_ref()
.map(|hint| hint.to_string()),
src: e.script.program.to_pretty(),
verbose,
})

View File

@ -1,6 +1,9 @@
use crate::{ExBudget, Term};
use crate::{pretty, ExBudget, Term};
use aiken_lang::ast::BinOp;
use std::path::PathBuf;
use std::{
fmt::{self, Display},
path::PathBuf,
};
use uplc::ast::{NamedDeBruijn, Program};
#[derive(Debug, Clone)]
@ -42,6 +45,48 @@ pub struct EvalHint {
pub right: Program<NamedDeBruijn>,
}
impl Display for EvalHint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let unlimited_budget = ExBudget {
mem: i64::MAX,
cpu: i64::MAX,
};
let left = pretty::boxed(
"left",
&match self.left.clone().eval(unlimited_budget).result() {
Ok(term) => format!("{term}"),
Err(err) => format!("{err}"),
},
);
let right = pretty::boxed(
"right",
&match self.right.clone().eval(unlimited_budget).result() {
Ok(term) => format!("{term}"),
Err(err) => format!("{err}"),
},
);
let msg = match self.bin_op {
BinOp::And => Some(format!("{left}\n\nand\n\n{right}\n\nshould both be true.")),
BinOp::Or => Some(format!("{left}\n\nor\n\n{right}\n\nshould be true.")),
BinOp::Eq => Some(format!("{left}\n\nshould be equal to\n\n{right}")),
BinOp::NotEq => Some(format!("{left}\n\nshould not be equal to\n\n{right}")),
BinOp::LtInt => Some(format!("{left}\n\nshould be lower than\n\n{right}")),
BinOp::LtEqInt => Some(format!(
"{left}\n\nshould be lower than or equal to\n\n{right}"
)),
BinOp::GtEqInt => Some(format!("{left}\n\nshould be greater than\n\n{right}")),
BinOp::GtInt => Some(format!(
"{left}\n\nshould be greater than or equal to\n\n{right}"
)),
_ => None,
}
.ok_or(fmt::Error::default())?;
f.write_str(&msg)
}
}
#[derive(Debug)]
pub struct EvalInfo {
pub success: bool,