use crate::dag::PostOrderIterItem;
use crate::jet::Jet;
use crate::Value;
use super::{
Commit, CommitNode, Inner, Marker, NoDisconnect, NoWitness, Node, Redeem, RedeemData,
RedeemNode,
};
use std::sync::Arc;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub enum Hide {
Neither,
Left,
Right,
}
pub trait Converter<N: Marker, M: Marker> {
type Error;
fn visit_node(&mut self, _data: &PostOrderIterItem<&Node<N>>) {}
fn convert_witness(
&mut self,
data: &PostOrderIterItem<&Node<N>>,
witness: &N::Witness,
) -> Result<M::Witness, Self::Error>;
fn convert_disconnect(
&mut self,
data: &PostOrderIterItem<&Node<N>>,
maybe_converted: Option<&Arc<Node<M>>>,
disconnect: &N::Disconnect,
) -> Result<M::Disconnect, Self::Error>;
fn prune_case(
&mut self,
_data: &PostOrderIterItem<&Node<N>>,
_left: &Arc<Node<M>>,
_right: &Arc<Node<M>>,
) -> Result<Hide, Self::Error> {
Ok(Hide::Neither)
}
fn convert_data(
&mut self,
data: &PostOrderIterItem<&Node<N>>,
inner: Inner<&Arc<Node<M>>, M::Jet, &M::Disconnect, &M::Witness>,
) -> Result<M::CachedData, Self::Error>;
}
pub struct SimpleFinalizer<W: Iterator<Item = Value>> {
iter: W,
}
impl<W: Iterator<Item = Value>> SimpleFinalizer<W> {
pub fn new(iter: W) -> Self {
SimpleFinalizer { iter }
}
}
impl<W: Iterator<Item = Value>, J: Jet> Converter<Commit<J>, Redeem<J>> for SimpleFinalizer<W> {
type Error = crate::FinalizeError;
fn convert_witness(
&mut self,
data: &PostOrderIterItem<&CommitNode<J>>,
_: &NoWitness,
) -> Result<Value, Self::Error> {
Ok(self
.iter
.next()
.unwrap_or_else(|| Value::zero(&data.node.arrow().target)))
}
fn convert_disconnect(
&mut self,
_: &PostOrderIterItem<&CommitNode<J>>,
_: Option<&Arc<RedeemNode<J>>>,
_: &NoDisconnect,
) -> Result<Arc<RedeemNode<J>>, Self::Error> {
Err(crate::FinalizeError::DisconnectRedeemTime)
}
fn convert_data(
&mut self,
data: &PostOrderIterItem<&CommitNode<J>>,
inner: Inner<&Arc<RedeemNode<J>>, J, &Arc<RedeemNode<J>>, &Value>,
) -> Result<Arc<RedeemData<J>>, Self::Error> {
let converted_data = inner
.map(|node| node.cached_data())
.map_disconnect(|node| node.cached_data())
.map_witness(Value::shallow_clone);
Ok(Arc::new(RedeemData::new(
data.node.arrow().shallow_clone(),
converted_data,
)))
}
}