use chia_sdk_types::{Condition, Conditions};
use clvm_traits::{FromClvm, ToClvm, clvm_quote, match_quote};
use clvmr::{Allocator, NodePtr};
use crate::{DriverError, Layer, Puzzle, Spend, SpendContext};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ConditionsLayer<T = NodePtr> {
pub conditions: Conditions<T>,
}
impl<T> ConditionsLayer<T> {
pub fn new(conditions: Conditions<T>) -> Self {
Self { conditions }
}
}
impl<T> Layer for ConditionsLayer<T>
where
T: FromClvm<Allocator> + ToClvm<Allocator> + Clone,
{
type Solution = ();
fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError> {
let Some(puzzle) = puzzle.as_raw() else {
return Ok(None);
};
let (_q, conditions) = <match_quote!(Vec<Condition<T>>)>::from_clvm(allocator, puzzle.ptr)?;
Ok(Some(Self::new(
Conditions::<T>::default().extend(conditions),
)))
}
fn parse_solution(_: &Allocator, _: NodePtr) -> Result<Self::Solution, DriverError> {
Ok(())
}
fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
Ok(clvm_quote!(self.conditions.clone()).to_clvm(ctx)?)
}
fn construct_solution(
&self,
_: &mut SpendContext,
(): Self::Solution,
) -> Result<NodePtr, DriverError> {
Ok(NodePtr::NIL)
}
}
impl<T> ConditionsLayer<T>
where
T: FromClvm<Allocator> + ToClvm<Allocator> + Clone,
{
pub fn spend(self, ctx: &mut SpendContext) -> Result<Spend, DriverError> {
let puzzle = self.construct_puzzle(ctx)?;
let solution = self.construct_solution(ctx, ())?;
Ok(Spend { puzzle, solution })
}
}