use std::convert::Infallible;
use sapling::builder::{BundleType, OutputInfo, SpendInfo};
use zcash_protocol::value::Zatoshis;
pub trait BundleView<NoteRef> {
type In: InputView<NoteRef>;
type Out: OutputView;
fn bundle_type(&self) -> BundleType;
fn inputs(&self) -> &[Self::In];
fn outputs(&self) -> &[Self::Out];
}
impl<'a, NoteRef, In: InputView<NoteRef>, Out: OutputView> BundleView<NoteRef>
for (BundleType, &'a [In], &'a [Out])
{
type In = In;
type Out = Out;
fn bundle_type(&self) -> BundleType {
self.0
}
fn inputs(&self) -> &[In] {
self.1
}
fn outputs(&self) -> &[Out] {
self.2
}
}
pub struct EmptyBundleView;
impl<NoteRef> BundleView<NoteRef> for EmptyBundleView {
type In = Infallible;
type Out = Infallible;
fn bundle_type(&self) -> BundleType {
BundleType::DEFAULT
}
fn inputs(&self) -> &[Self::In] {
&[]
}
fn outputs(&self) -> &[Self::Out] {
&[]
}
}
pub trait InputView<NoteRef> {
fn note_id(&self) -> &NoteRef;
fn value(&self) -> Zatoshis;
}
impl<N> InputView<N> for Infallible {
fn note_id(&self) -> &N {
unreachable!()
}
fn value(&self) -> Zatoshis {
unreachable!()
}
}
impl InputView<()> for SpendInfo {
fn note_id(&self) -> &() {
&()
}
fn value(&self) -> Zatoshis {
Zatoshis::try_from(self.value().inner())
.expect("An existing note to be spent must have a valid amount value.")
}
}
pub trait OutputView {
fn value(&self) -> Zatoshis;
}
impl OutputView for OutputInfo {
fn value(&self) -> Zatoshis {
Zatoshis::try_from(self.value().inner())
.expect("Output values should be checked at construction.")
}
}
impl OutputView for Infallible {
fn value(&self) -> Zatoshis {
unreachable!()
}
}
impl OutputView for Zatoshis {
fn value(&self) -> Zatoshis {
*self
}
}