use core::marker::PhantomData;
use bytes::{Buf, BufMut};
use crate::{
Error,
protocol::{
Address,
codec::{BitSize, Decode, Encode, adapters::DropRemaining},
function,
function::size_argument,
},
};
#[must_use]
pub struct Args<A, V, S>(
A,
PhantomData<V>,
PhantomData<S>,
);
impl<A, V: BitSize, S> From<A> for Args<A, V, S> {
fn from(address: A) -> Self {
Self::new(address)
}
}
impl<A, V: BitSize, S> Args<A, V, S> {
pub const fn new(starting_address: A) -> Self {
Self(starting_address, PhantomData, PhantomData)
}
}
impl<A: Address, V: BitSize> Encode for Args<A, V, size_argument::Bits> {
fn encode(&self, to: &mut impl BufMut) {
V::assert_valid::<246>();
self.0.encode(to);
to.put_u16(V::N_BITS);
}
}
impl<A: Address, V: BitSize> Encode for Args<A, V, size_argument::Words> {
fn encode(&self, to: &mut impl BufMut) {
V::assert_valid::<250>();
self.0.encode(to);
to.put_u16(V::N_WORDS);
}
}
pub struct Output<V>(V);
impl<V: Decode> Decode for Output<V> {
fn decode(from: &mut impl Buf) -> Result<Self, Error> {
let n_bytes = from.try_get_u8()?;
let mut from = DropRemaining(from).take(usize::from(n_bytes));
V::decode(&mut from).map(Self)
}
}
impl<V> function::IntoValue for Output<V> {
type Value = V;
fn into_value(self) -> Self::Value {
self.0
}
}