Skip to main content

jam_types/
segment_bytes.rs

1use crate::{AnyBytes, Segment, SEGMENT_LEN};
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 From<Segment> for SegmentBytes {
56	fn from(other: Segment) -> Self {
57		Self(other.into_vec().into())
58	}
59}
60
61impl From<&[u8; SEGMENT_LEN]> for SegmentBytes {
62	fn from(other: &[u8; SEGMENT_LEN]) -> Self {
63		Self(other.to_vec().into())
64	}
65}
66
67impl TryFrom<Vec<u8>> for SegmentBytes {
68	type Error = ();
69
70	fn try_from(other: Vec<u8>) -> Result<Self, Self::Error> {
71		if other.len() != SEGMENT_LEN {
72			return Err(());
73		}
74		Ok(Self(other.into()))
75	}
76}
77
78impl TryFrom<Bytes> for SegmentBytes {
79	type Error = ();
80
81	fn try_from(other: Bytes) -> Result<Self, Self::Error> {
82		if other.len() != SEGMENT_LEN {
83			return Err(());
84		}
85		Ok(Self(other))
86	}
87}
88
89impl From<SegmentBytes> for Bytes {
90	fn from(other: SegmentBytes) -> Self {
91		other.0
92	}
93}
94
95impl core::fmt::Debug for SegmentBytes {
96	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
97		core::fmt::Debug::fmt(&AnyBytes(self.0.clone()), f)
98	}
99}
100
101impl core::fmt::Display for SegmentBytes {
102	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
103		core::fmt::Debug::fmt(self, f)
104	}
105}
106
107#[cfg(feature = "serde")]
108impl serde::Serialize for SegmentBytes {
109	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
110	where
111		S: serde::Serializer,
112	{
113		AnyBytes(self.0.clone()).serialize(serializer)
114	}
115}
116
117#[cfg(feature = "serde")]
118impl<'a> serde::Deserialize<'a> for SegmentBytes {
119	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
120	where
121		D: serde::Deserializer<'a>,
122	{
123		let AnyBytes(bytes) = AnyBytes::deserialize(deserializer)?;
124		bytes
125			.try_into()
126			.map_err(|_| serde::de::Error::custom("Invalid SegmentBytes length"))
127	}
128}
129
130#[cfg(all(feature = "serde", test))]
131mod tests {
132	use super::*;
133
134	#[test]
135	fn segment_base64_works() {
136		let segment = SegmentBytes::from(&[123_u8; SEGMENT_LEN]);
137		let string = serde_json::to_string(&segment).unwrap();
138		let actual: SegmentBytes = serde_json::from_str(&string).unwrap();
139		assert_eq!(segment, actual);
140	}
141}