use std::convert::Infallible;
use orchard::{builder::BundleType, bundle::BundleVersion};
use zcash_protocol::value::Zatoshis;
pub(crate) fn transactional_action_count(
bundle_type: BundleType,
bundle_version: BundleVersion,
num_spends: usize,
num_outputs: usize,
) -> Result<usize, &'static str> {
bundle_type.num_actions(bundle_version.default_flags(), num_spends, num_outputs)
}
pub trait BundleView<NoteRef> {
type In: InputView<NoteRef>;
type Out: OutputView;
fn bundle_version(&self) -> BundleVersion;
fn inputs(&self) -> &[Self::In];
fn outputs(&self) -> &[Self::Out];
}
impl<'a, NoteRef, In: InputView<NoteRef>, Out: OutputView> BundleView<NoteRef>
for (BundleVersion, &'a [In], &'a [Out])
{
type In = In;
type Out = Out;
fn bundle_version(&self) -> BundleVersion {
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_version(&self) -> BundleVersion {
BundleVersion::orchard_v2()
}
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!()
}
}
pub trait OutputView {
fn value(&self) -> Zatoshis;
}
impl OutputView for Infallible {
fn value(&self) -> Zatoshis {
unreachable!()
}
}
impl OutputView for Zatoshis {
fn value(&self) -> Zatoshis {
*self
}
}