exocore_core/framing/
mod.rs1use std::io;
2
3pub mod capnp;
4pub mod compound;
5pub mod error;
6pub mod multihash;
7pub mod padded;
8pub mod sized;
9
10use bytes::{Buf, Bytes};
11pub use error::Error;
12pub use padded::{PaddedFrame, PaddedFrameBuilder};
13pub use sized::{IteratedSizedSliceFrame, SizedFrame, SizedFrameBuilder, SizedFrameSliceIterator};
14
15pub use self::{
16 capnp::{CapnpFrame, CapnpFrameBuilder, TypedCapnpFrame},
17 multihash::{MultihashFrame, MultihashFrameBuilder},
18};
19
20pub trait FrameReader {
31 type OwnedType: FrameReader;
32
33 fn exposed_data(&self) -> &[u8];
36
37 fn whole_data(&self) -> &[u8];
39
40 #[inline]
42 fn whole_data_size(&self) -> usize {
43 self.whole_data().len()
44 }
45
46 fn to_owned_frame(&self) -> Self::OwnedType;
48
49 fn copy_to<W: io::Write>(&self, writer: &mut W) -> Result<(), Error> {
51 writer.write_all(self.whole_data())?;
52 Ok(())
53 }
54
55 fn copy_into(&self, into: &mut [u8]) -> Result<usize, Error> {
57 let whole_data = self.whole_data();
58 check_into_size(whole_data.len(), into)?;
59 into[0..whole_data.len()].copy_from_slice(whole_data);
60 Ok(whole_data.len())
61 }
62}
63
64impl<B: Buf> FrameReader for B {
65 type OwnedType = Bytes;
66
67 fn exposed_data(&self) -> &[u8] {
68 self.chunk()
69 }
70
71 fn whole_data(&self) -> &[u8] {
72 self.chunk()
73 }
74
75 fn to_owned_frame(&self) -> Self::OwnedType {
76 self.chunk().to_vec().into()
77 }
78}
79
80pub trait FrameBuilder {
87 type OwnedFrameType;
88
89 fn write_to<W: io::Write>(&self, writer: &mut W) -> Result<usize, Error>;
91
92 fn write_into(&self, into: &mut [u8]) -> Result<usize, Error>;
94
95 fn expected_size(&self) -> Option<usize>;
98
99 fn as_owned_frame(&self) -> Self::OwnedFrameType;
102
103 fn as_bytes(&self) -> Bytes {
105 let mut buffer = Vec::new();
106 self.write_to(&mut buffer)
107 .expect("Couldn't write frame into in-memory vec");
108 buffer.into()
109 }
110}
111
112impl<B: Buf> FrameBuilder for B {
115 type OwnedFrameType = Bytes;
116
117 fn write_to<W: io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
118 writer.write_all(self.chunk())?;
119 Ok(self.remaining())
120 }
121
122 fn write_into(&self, into: &mut [u8]) -> Result<usize, Error> {
123 check_into_size(self.remaining(), into)?;
124 into[0..self.remaining()].copy_from_slice(self.chunk());
125 Ok(self.remaining())
126 }
127
128 fn expected_size(&self) -> Option<usize> {
129 Some(self.remaining())
130 }
131
132 fn as_owned_frame(&self) -> Self::OwnedFrameType {
133 self.chunk().to_vec().into()
134 }
135}
136
137fn check_into_size(needed: usize, into: &[u8]) -> Result<(), Error> {
139 if into.len() < needed {
140 Err(Error::DestinationTooSmall(needed, into.len()))
141 } else {
142 Ok(())
143 }
144}
145
146fn check_from_size(needed: usize, from: &[u8]) -> Result<(), Error> {
148 if from.len() < needed {
149 Err(Error::SourceTooSmall(needed, from.len()))
150 } else {
151 Ok(())
152 }
153}
154
155fn check_offset_subtract(offset: usize, sub_offset: usize) -> Result<(), Error> {
157 if sub_offset > offset {
158 Err(Error::OffsetSubtract(offset, sub_offset))
159 } else {
160 Ok(())
161 }
162}
163
164#[cfg(test)]
165fn assert_builder_equals<B: FrameBuilder>(frame_builder: &B) -> anyhow::Result<()> {
166 let mut buffer1 = Vec::new();
167 frame_builder.write_to(&mut buffer1)?;
168
169 assert_ne!(0, buffer1.len());
170
171 let mut buffer2 = vec![0; 500];
172 let size = frame_builder.write_into(&mut buffer2)?;
173 assert_eq!(&buffer1[..], &buffer2[..size]);
174
175 assert_eq!(frame_builder.as_bytes(), buffer1);
176
177 if let Some(expected_size) = frame_builder.expected_size() {
178 assert_eq!(expected_size, buffer1.len());
179 }
180
181 Ok(())
182}