Skip to main content

jam_types/
segment_bytes.rs

1use crate::{AnyBytes, SEGMENT_LEN, Segment};
2use alloc::{vec, vec::Vec};
3use bytes::Bytes;
4
5/// Zero-copy segment wrapper.
6///
7/// The segment is immutable and its length is fixed.
8#[derive(Clone, PartialEq, Eq)]
9pub struct SegmentBytes(Bytes);
10
11impl SegmentBytes {
12	pub fn as_array(&self) -> &[u8; SEGMENT_LEN] {
13		(&self.0[..]).try_into().expect("Segment length is fixed")
14	}
15
16	pub fn as_slice(&self) -> &[u8] {
17		&self.0[..]
18	}
19
20	pub fn as_bytes(&self) -> &Bytes {
21		&self.0
22	}
23
24	pub fn into_inner(self) -> Bytes {
25		self.0
26	}
27}
28
29impl Default for SegmentBytes {
30	fn default() -> Self {
31		Self(vec![0_u8; SEGMENT_LEN].into())
32	}
33}
34
35impl core::ops::Deref for SegmentBytes {
36	type Target = [u8];
37
38	fn deref(&self) -> &Self::Target {
39		&self.0[..]
40	}
41}
42
43impl AsRef<[u8; SEGMENT_LEN]> for SegmentBytes {
44	fn as_ref(&self) -> &[u8; SEGMENT_LEN] {
45		self.as_array()
46	}
47}
48
49impl AsRef<[u8]> for SegmentBytes {
50	fn as_ref(&self) -> &[u8] {
51		self.as_slice()
52	}
53}
54
55impl core::borrow::Borrow<Bytes> for &SegmentBytes {
56	fn borrow(&self) -> &Bytes {
57		&self.0
58	}
59}
60
61impl From<Segment> for SegmentBytes {
62	fn from(other: Segment) -> Self {
63		Self(other.into_vec().into())
64	}
65}
66
67impl From<&[u8; SEGMENT_LEN]> for SegmentBytes {
68	fn from(other: &[u8; SEGMENT_LEN]) -> Self {
69		Self(other.to_vec().into())
70	}
71}
72
73impl TryFrom<Vec<u8>> for SegmentBytes {
74	type Error = ();
75
76	fn try_from(other: Vec<u8>) -> Result<Self, Self::Error> {
77		if other.len() != SEGMENT_LEN {
78			return Err(());
79		}
80		Ok(Self(other.into()))
81	}
82}
83
84impl TryFrom<Bytes> for SegmentBytes {
85	type Error = ();
86
87	fn try_from(other: Bytes) -> Result<Self, Self::Error> {
88		if other.len() != SEGMENT_LEN {
89			return Err(());
90		}
91		Ok(Self(other))
92	}
93}
94
95impl From<SegmentBytes> for Bytes {
96	fn from(other: SegmentBytes) -> Self {
97		other.0
98	}
99}
100
101impl core::fmt::Debug for SegmentBytes {
102	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
103		core::fmt::Debug::fmt(&AnyBytes(self.0.clone()), f)
104	}
105}
106
107impl core::fmt::Display for SegmentBytes {
108	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
109		core::fmt::Debug::fmt(self, f)
110	}
111}
112
113#[cfg(feature = "serde")]
114impl serde::Serialize for SegmentBytes {
115	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
116	where
117		S: serde::Serializer,
118	{
119		AnyBytes(self.0.clone()).serialize(serializer)
120	}
121}
122
123#[cfg(feature = "serde")]
124impl<'a> serde::Deserialize<'a> for SegmentBytes {
125	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
126	where
127		D: serde::Deserializer<'a>,
128	{
129		let AnyBytes(bytes) = AnyBytes::deserialize(deserializer)?;
130		bytes
131			.try_into()
132			.map_err(|_| serde::de::Error::custom("Invalid SegmentBytes length"))
133	}
134}
135
136impl codec::Encode for SegmentBytes {
137	fn encode_to<T: codec::Output + ?Sized>(&self, output: &mut T) {
138		output.write(&self.0[..]);
139	}
140
141	fn encoded_size(&self) -> usize {
142		SEGMENT_LEN
143	}
144}
145
146impl codec::MaxEncodedLen for SegmentBytes {
147	fn max_encoded_len() -> usize {
148		SEGMENT_LEN
149	}
150}
151
152impl codec::Decode for SegmentBytes {
153	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
154		let mut segment = vec![0_u8; SEGMENT_LEN];
155		input.read(&mut segment[..])?;
156		Ok(Self(Bytes::from(segment)))
157	}
158}
159
160#[cfg(all(feature = "serde", test))]
161mod tests {
162	use super::*;
163
164	#[test]
165	fn segment_base64_works() {
166		let segment = SegmentBytes::from(&[123_u8; SEGMENT_LEN]);
167		let string = serde_json::to_string(&segment).unwrap();
168		let actual: SegmentBytes = serde_json::from_str(&string).unwrap();
169		assert_eq!(segment, actual);
170	}
171}