diff --git a/pallas-machines/src/lib.rs b/pallas-machines/src/lib.rs index 4084f92..516db16 100644 --- a/pallas-machines/src/lib.rs +++ b/pallas-machines/src/lib.rs @@ -1,5 +1,5 @@ use log::{debug, trace, warn}; -use minicbor::{Decoder, Encoder}; +use minicbor::{Decoder, Encode, Encoder}; use pallas_multiplexer::Payload; use std::borrow::Borrow; use std::fmt::{Debug, Display}; @@ -20,10 +20,10 @@ impl Display for MachineError { } MachineError::UnexpectedCbor(msg) => { write!(f, "unexpected cbor: {}", msg) - }, + } MachineError::InvalidMsgForState => { write!(f, "received invalid message for current state") - }, + } } } } @@ -35,15 +35,10 @@ pub type PayloadEncoder<'a> = Encoder<&'a mut Vec>; pub type PayloadDecoder<'a> = Decoder<'a>; pub trait EncodePayload { - fn encode_payload( - &self, - e: &mut PayloadEncoder, - ) -> Result<(), Box>; + fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box>; } -pub fn to_payload( - data: &dyn EncodePayload, -) -> Result> { +pub fn to_payload(data: &dyn EncodePayload) -> Result> { let mut payload = Vec::new(); let mut encoder = minicbor::encode::Encoder::new(&mut payload); data.encode_payload(&mut encoder)?; @@ -51,44 +46,48 @@ pub fn to_payload( Ok(payload) } -pub struct Message + +impl EncodePayload for Vec where D: EncodePayload, { - pub label: u32, - pub data: D, -} + fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box> { + e.array(self.len() as u64)?; -impl EncodePayload for Message -where - D: EncodePayload, -{ - fn encode_payload( - &self, - e: &mut PayloadEncoder, - ) -> Result<(), Box> { - // TODO: map concrete error to W::Error somehow? - // or just implement custom error struct - let data = to_payload(&self.data).unwrap(); - - e.array(2)?.u32(self.label)?.bytes(&data)?; + for item in self { + item.encode_payload(e)?; + } Ok(()) } } +impl DecodePayload for Vec +where + D: DecodePayload, +{ + fn decode_payload(d: &mut PayloadDecoder) -> Result> { + let len = d.array()?.ok_or(MachineError::UnexpectedCbor( + "expecting definite-length array", + ))? as usize; + + let mut output = Vec::::with_capacity(len); + + for i in 0..(len - 1) { + output[i] = D::decode_payload(d)?; + } + + Ok(output) + + } +} + pub trait MachineOutput { - fn send_msg( - &self, - data: &impl EncodePayload, - ) -> Result<(), Box>; + fn send_msg(&self, data: &impl EncodePayload) -> Result<(), Box>; } impl MachineOutput for Sender { - fn send_msg( - &self, - data: &impl EncodePayload, - ) -> Result<(), Box> { + fn send_msg(&self, data: &impl EncodePayload) -> Result<(), Box> { let payload = to_payload(data.borrow())?; self.send(payload)?; @@ -97,9 +96,7 @@ impl MachineOutput for Sender { } pub trait DecodePayload: Sized { - fn decode_payload( - d: &mut PayloadDecoder, - ) -> Result>; + fn decode_payload(d: &mut PayloadDecoder) -> Result>; } pub struct PayloadDeconstructor {