concordium_base/common/
encoded.rs1use super::{Deserial, ParseResult, Serial};
2
3#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, derive_more::Into)]
9#[serde(transparent)]
10#[repr(transparent)]
11pub struct Encoded<A> {
12 #[serde(with = "crate::internal::byte_array_hex")]
13 pub(crate) bytes: Vec<u8>,
14 _kind: std::marker::PhantomData<A>,
15}
16
17impl<A> Encoded<A> {
18 pub fn encode(item: &A) -> Self
20 where
21 A: Serial,
22 {
23 Self {
24 bytes: super::to_bytes(item),
25 _kind: Default::default(),
26 }
27 }
28
29 pub fn decode(&self) -> ParseResult<A>
34 where
35 A: Deserial,
36 {
37 use super::Get;
38 let mut source = std::io::Cursor::new(&self.bytes);
39 let payload = source.get()?;
40 let consumed = source.position();
42 anyhow::ensure!(
43 consumed == self.bytes.len() as u64,
44 "Payload length information is inaccurate: {} bytes of input remaining.",
45 self.bytes.len() as u64 - consumed
46 );
47 Ok(payload)
48 }
49}
50
51impl<A> From<Vec<u8>> for Encoded<A> {
52 fn from(encoding: Vec<u8>) -> Self {
53 Self {
54 bytes: encoding,
55 _kind: Default::default(),
56 }
57 }
58}
59
60impl<A> AsRef<[u8]> for Encoded<A> {
61 fn as_ref(&self) -> &[u8] {
62 &self.bytes
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
72 fn test_encode_decode() {
73 let item = vec![1, 2, 4, 3, 4, 5, 6, 8, 4, 89, 5];
74 let encoded = Encoded::encode(&item);
75 let item_decoded = encoded.decode().expect("Failed decoding a vec");
76 assert_eq!(item, item_decoded)
77 }
78
79 #[test]
81 fn test_decode_fails_when_leftover_bytes() {
82 let item = vec![0, 0, 0, 0, 32];
83 let encoded = Encoded::<u32>::from(item);
84 let result = encoded.decode();
85 assert!(result.is_err())
86 }
87}