pub trait Converter<N: Marker, M: Marker> {
type Error;
// Required methods
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 convert_data(
&mut self,
data: &PostOrderIterItem<&Node<N>>,
inner: Inner<&Arc<Node<M>>, M::Jet, &M::Disconnect, &M::Witness>,
) -> Result<M::CachedData, Self::Error>;
// Provided methods
fn visit_node(&mut self, _data: &PostOrderIterItem<&Node<N>>) { ... }
fn prune_case(
&mut self,
_data: &PostOrderIterItem<&Node<N>>,
_left: &Arc<Node<M>>,
_right: &Arc<Node<M>>,
) -> Result<Hide, Self::Error> { ... }
}
Expand description
The primary trait controlling how a node conversion is done.
When a node is converted using Node::convert
, the original DAG rooted at
that node is traversed in post order. For each node, the following steps are
taken:
-
First,
Self::visit_node
is called, before any other checks are done. This happens regardless of the node’s type or whether it is going to be pruned.This method is provided for convenience and does not affect the course of the algorithm. It has a default implementation which does nothing.
-
Then, if the node is a witness node,
Self::convert_witness
is called to obtain witness data. -
If the node is a case node,
Self::prune_case
is called to decide whether to prune either child of the node (turning thecase
into anassertl
orassertr
). The default implementation hides neither. -
Finally, the node’s data is passed to
Self::convert_data
, whose job it is to compute the cached data for the new node. Forcase
combinators where one child was pruned,convert_data
will receive anassertl
orassertl
, as appropriate, rather than acase
.
If any method returns an error, then iteration is aborted immediately and the error returned to the caller. If the converter would like to recover from errors and/or accumulate multiple errors, it needs to do this by tracking errors internally.
The finalization method will not return any errors except those returned by
methods on Converter
.
Required Associated Types§
Required Methods§
Sourcefn convert_witness(
&mut self,
data: &PostOrderIterItem<&Node<N>>,
witness: &N::Witness,
) -> Result<M::Witness, Self::Error>
fn convert_witness( &mut self, data: &PostOrderIterItem<&Node<N>>, witness: &N::Witness, ) -> Result<M::Witness, Self::Error>
For witness nodes, this method is called first to attach witness data to the node.
It takes the iteration data of the current node, as well as the current witness (which in a typical scenario will be an empty structure, but with custom node types may be a placeholder or other useful information)
No typechecking or other sanity-checking is done on the returned value. It is the caller’s responsibility to make sure that the provided witness actually matches the type of the combinator that it is being attached to.
Sourcefn convert_disconnect(
&mut self,
data: &PostOrderIterItem<&Node<N>>,
maybe_converted: Option<&Arc<Node<M>>>,
disconnect: &N::Disconnect,
) -> Result<M::Disconnect, 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>
For disconnect nodes, this method is called first to attach a disconnected expression to the node.
It takes the iteration data of the current node, as well as the current disconnected expression (which in a typical scenario will be an empty structure, but with custom node types may be a placeholder or other useful information)
No typechecking or other sanity-checking is done on the returned expression. It is the caller’s responsibility to make sure that the provided expression actually matches the type of the combinator that it is being attached to.
Sourcefn convert_data(
&mut self,
data: &PostOrderIterItem<&Node<N>>,
inner: Inner<&Arc<Node<M>>, M::Jet, &M::Disconnect, &M::Witness>,
) -> Result<M::CachedData, Self::Error>
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>
This method is called for every node, after Self::convert_witness
or
Self::prune_case
, if either is applicable.
For case nodes for which Self::prune_case
returned Hide::Left
or
Hide::Right
, inner
will be an Inner::AssertR
or Inner::AssertL
respectively; the pruned child will then appear only as a CMR.
It accepts the iteration data of the current node, from which the existing
cached data can be obtained by calling data.node.cached_data()
, as well
as an Inner
structure containing its already-converted children.
Returns new cached data which will be attached to the newly-converted node.
Provided Methods§
Sourcefn visit_node(&mut self, _data: &PostOrderIterItem<&Node<N>>)
fn visit_node(&mut self, _data: &PostOrderIterItem<&Node<N>>)
This method is called on every node, to inform the Converter
about the
state of the iterator.
No action needs to be taken. The default implementation does nothing.
Sourcefn prune_case(
&mut self,
_data: &PostOrderIterItem<&Node<N>>,
_left: &Arc<Node<M>>,
_right: &Arc<Node<M>>,
) -> Result<Hide, Self::Error>
fn prune_case( &mut self, _data: &PostOrderIterItem<&Node<N>>, _left: &Arc<Node<M>>, _right: &Arc<Node<M>>, ) -> Result<Hide, Self::Error>
For case nodes, this method is called first to decide which, if any, children to prune.
It takes the iteration data of the current node, as well as both of its already converted children. This method returns a hiding decision.
The default implementation doesn’t do any hiding.