litep2p/codec/
identity.rs1use crate::error::Error;
24
25use bytes::{BufMut, Bytes, BytesMut};
26use tokio_util::codec::{Decoder, Encoder};
27
28pub struct Identity {
30 payload_len: usize,
31}
32
33impl Identity {
34 pub fn new(payload_len: usize) -> Self {
36 assert!(payload_len != 0);
37
38 Self { payload_len }
39 }
40
41 pub fn encode<T: Into<Bytes>>(payload: T) -> crate::Result<Vec<u8>> {
43 let payload: Bytes = payload.into();
44 Ok(payload.into())
45 }
46}
47
48impl Decoder for Identity {
49 type Item = BytesMut;
50 type Error = Error;
51
52 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
53 if src.is_empty() {
54 return Ok(None);
55 }
56
57 Ok(Some(src.split_to(self.payload_len)))
58 }
59}
60
61impl Encoder<Bytes> for Identity {
62 type Error = Error;
63
64 fn encode(&mut self, item: Bytes, dst: &mut bytes::BytesMut) -> Result<(), Self::Error> {
65 if item.len() > self.payload_len || item.is_empty() {
66 return Err(Error::InvalidData);
67 }
68
69 dst.put_slice(item.as_ref());
70 Ok(())
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn encoding_works() {
80 let mut codec = Identity::new(48);
81 let mut out_buf = BytesMut::with_capacity(32);
82 let bytes = Bytes::from(vec![0u8; 48]);
83
84 assert!(codec.encode(bytes.clone(), &mut out_buf).is_ok());
85 assert_eq!(out_buf.freeze(), bytes);
86 }
87
88 #[test]
89 fn decoding_works() {
90 let mut codec = Identity::new(64);
91 let bytes = vec![3u8; 64];
92 let copy = bytes.clone();
93 let mut bytes = BytesMut::from(&bytes[..]);
94
95 let decoded = codec.decode(&mut bytes).unwrap().unwrap();
96 assert_eq!(decoded, copy);
97 }
98
99 #[test]
100 fn empty_encode() {
101 let mut codec = Identity::new(32);
102 let mut out_buf = BytesMut::with_capacity(32);
103 assert!(codec.encode(Bytes::new(), &mut out_buf).is_err());
104 }
105
106 #[test]
107 fn decode_encode() {
108 let mut codec = Identity::new(32);
109 assert!(codec.decode(&mut BytesMut::new()).unwrap().is_none());
110 }
111
112 #[test]
113 fn direct_encoding_works() {
114 assert_eq!(
115 Identity::encode(vec![1, 3, 3, 7]).unwrap(),
116 vec![1, 3, 3, 7]
117 );
118 }
119
120 #[test]
121 #[should_panic]
122 #[cfg(debug_assertions)]
123 fn empty_identity_codec() {
124 let _codec = Identity::new(0usize);
125 }
126}