use std::io;
pub mod capnp;
pub mod compound;
pub mod error;
pub mod multihash;
pub mod padded;
pub mod sized;
use bytes::{Buf, Bytes};
pub use error::Error;
pub use padded::{PaddedFrame, PaddedFrameBuilder};
pub use sized::{IteratedSizedSliceFrame, SizedFrame, SizedFrameBuilder, SizedFrameSliceIterator};
pub use self::{
capnp::{CapnpFrame, CapnpFrameBuilder, TypedCapnpFrame},
multihash::{MultihashFrame, MultihashFrameBuilder},
};
pub trait FrameReader {
type OwnedType: FrameReader;
fn exposed_data(&self) -> &[u8];
fn whole_data(&self) -> &[u8];
#[inline]
fn whole_data_size(&self) -> usize {
self.whole_data().len()
}
fn to_owned_frame(&self) -> Self::OwnedType;
fn copy_to<W: io::Write>(&self, writer: &mut W) -> Result<(), Error> {
writer.write_all(self.whole_data())?;
Ok(())
}
fn copy_into(&self, into: &mut [u8]) -> Result<usize, Error> {
let whole_data = self.whole_data();
check_into_size(whole_data.len(), into)?;
into[0..whole_data.len()].copy_from_slice(whole_data);
Ok(whole_data.len())
}
}
impl<B: Buf> FrameReader for B {
type OwnedType = Bytes;
fn exposed_data(&self) -> &[u8] {
self.chunk()
}
fn whole_data(&self) -> &[u8] {
self.chunk()
}
fn to_owned_frame(&self) -> Self::OwnedType {
self.chunk().to_vec().into()
}
}
pub trait FrameBuilder {
type OwnedFrameType;
fn write_to<W: io::Write>(&self, writer: &mut W) -> Result<usize, Error>;
fn write_into(&self, into: &mut [u8]) -> Result<usize, Error>;
fn expected_size(&self) -> Option<usize>;
fn as_owned_frame(&self) -> Self::OwnedFrameType;
fn as_bytes(&self) -> Bytes {
let mut buffer = Vec::new();
self.write_to(&mut buffer)
.expect("Couldn't write frame into in-memory vec");
buffer.into()
}
}
impl<B: Buf> FrameBuilder for B {
type OwnedFrameType = Bytes;
fn write_to<W: io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
writer.write_all(self.chunk())?;
Ok(self.remaining())
}
fn write_into(&self, into: &mut [u8]) -> Result<usize, Error> {
check_into_size(self.remaining(), into)?;
into[0..self.remaining()].copy_from_slice(self.chunk());
Ok(self.remaining())
}
fn expected_size(&self) -> Option<usize> {
Some(self.remaining())
}
fn as_owned_frame(&self) -> Self::OwnedFrameType {
self.chunk().to_vec().into()
}
}
fn check_into_size(needed: usize, into: &[u8]) -> Result<(), Error> {
if into.len() < needed {
Err(Error::DestinationTooSmall(needed, into.len()))
} else {
Ok(())
}
}
fn check_from_size(needed: usize, from: &[u8]) -> Result<(), Error> {
if from.len() < needed {
Err(Error::SourceTooSmall(needed, from.len()))
} else {
Ok(())
}
}
fn check_offset_subtract(offset: usize, sub_offset: usize) -> Result<(), Error> {
if sub_offset > offset {
Err(Error::OffsetSubtract(offset, sub_offset))
} else {
Ok(())
}
}
#[cfg(test)]
fn assert_builder_equals<B: FrameBuilder>(frame_builder: &B) -> anyhow::Result<()> {
let mut buffer1 = Vec::new();
frame_builder.write_to(&mut buffer1)?;
assert_ne!(0, buffer1.len());
let mut buffer2 = vec![0; 500];
let size = frame_builder.write_into(&mut buffer2)?;
assert_eq!(&buffer1[..], &buffer2[..size]);
assert_eq!(frame_builder.as_bytes(), buffer1);
if let Some(expected_size) = frame_builder.expected_size() {
assert_eq!(expected_size, buffer1.len());
}
Ok(())
}