1use std::fmt;
28
29use serde::de::{self, Visitor};
30use serde::{Deserialize, Deserializer, Serialize, Serializer};
31
32#[derive(Clone, Default, PartialEq, Eq, Hash)]
34pub struct Payload(pub Vec<u8>);
35
36impl Payload {
37 pub fn new() -> Self {
38 Self::default()
39 }
40
41 pub fn len(&self) -> usize {
42 self.0.len()
43 }
44
45 pub fn is_empty(&self) -> bool {
46 self.0.is_empty()
47 }
48
49 pub fn as_slice(&self) -> &[u8] {
50 &self.0
51 }
52
53 pub fn into_inner(self) -> Vec<u8> {
54 self.0
55 }
56}
57
58impl From<Vec<u8>> for Payload {
59 fn from(bytes: Vec<u8>) -> Self {
60 Self(bytes)
61 }
62}
63
64impl From<Payload> for Vec<u8> {
65 fn from(payload: Payload) -> Self {
66 payload.0
67 }
68}
69
70impl AsRef<[u8]> for Payload {
71 fn as_ref(&self) -> &[u8] {
72 &self.0
73 }
74}
75
76impl std::ops::Deref for Payload {
77 type Target = [u8];
78
79 fn deref(&self) -> &[u8] {
80 &self.0
81 }
82}
83
84impl fmt::Debug for Payload {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 write!(f, "Payload({} bytes)", self.0.len())
89 }
90}
91
92impl Serialize for Payload {
93 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
94 serializer.serialize_bytes(&self.0)
95 }
96}
97
98impl<'de> Deserialize<'de> for Payload {
99 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
100 struct Raw;
101
102 impl<'de> Visitor<'de> for Raw {
103 type Value = Vec<u8>;
104
105 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 f.write_str("bytes")
107 }
108
109 fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Vec<u8>, E> {
110 Ok(v.to_vec())
111 }
112
113 fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Vec<u8>, E> {
114 Ok(v)
115 }
116
117 fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Vec<u8>, A::Error> {
120 let mut out = Vec::with_capacity(seq.size_hint().unwrap_or(0));
121 while let Some(byte) = seq.next_element::<u8>()? {
122 out.push(byte);
123 }
124 Ok(out)
125 }
126 }
127
128 deserializer.deserialize_byte_buf(Raw).map(Payload)
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[cfg(feature = "msgpack")]
137 #[test]
138 fn bytes_cost_a_header_rather_than_a_second_encoding() {
139 use crate::{MsgPackCodec, WireCodec};
140
141 let raw = vec![200u8; 4096];
143 let as_payload = MsgPackCodec.encode(&Payload::from(raw.clone())).unwrap();
144 let as_vec = MsgPackCodec.encode(&raw).unwrap();
145
146 assert!(as_payload.len() <= raw.len() + 8, "{} for {}", as_payload.len(), raw.len());
147 assert!(as_vec.len() > raw.len() * 3 / 2, "a Vec<u8> should visibly cost more");
148 }
149
150 #[cfg(feature = "msgpack")]
151 #[test]
152 fn it_round_trips() {
153 use crate::{MsgPackCodec, WireCodec};
154
155 let payload = Payload::from((0..=255u8).collect::<Vec<_>>());
156 let back: Payload = MsgPackCodec.decode(&MsgPackCodec.encode(&payload).unwrap()).unwrap();
157 assert_eq!(back, payload);
158 }
159
160 #[cfg(feature = "json")]
161 #[test]
162 fn a_text_codec_still_round_trips_through_an_array() {
163 use crate::{JsonCodec, WireCodec};
164
165 let payload = Payload::from(vec![1u8, 127, 128, 255]);
166 let back: Payload = JsonCodec.decode(&JsonCodec.encode(&payload).unwrap()).unwrap();
167 assert_eq!(back, payload);
168 }
169
170 #[test]
171 fn debug_prints_the_length_not_the_bytes() {
172 assert_eq!(format!("{:?}", Payload::from(vec![0u8; 900])), "Payload(900 bytes)");
173 }
174}