#![allow(clippy::needless_lifetimes)]
#![allow(clippy::needless_borrow)]
#![allow(clippy::wrong_self_convention)]
#![allow(clippy::if_same_then_else)]
#![allow(clippy::derivable_impls)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::write_literal)]
#![allow(clippy::clone_on_copy)]
#![allow(clippy::fallible_impl_from)]
use molecule::prelude::*;
#[derive(Clone)]
pub struct VmIndex(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for VmIndex {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for VmIndex {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for VmIndex {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
let raw_data = hex_string(&self.raw_data());
write!(f, "{}(0x{})", Self::NAME, raw_data)
}
}
impl ::core::default::Default for VmIndex {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
VmIndex::new_unchecked(v)
}
}
impl VmIndex {
const DEFAULT_VALUE: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
pub const TOTAL_SIZE: usize = 8;
pub const ITEM_SIZE: usize = 1;
pub const ITEM_COUNT: usize = 8;
pub fn nth0(&self) -> Byte {
Byte::new_unchecked(self.0.slice(0..1))
}
pub fn nth1(&self) -> Byte {
Byte::new_unchecked(self.0.slice(1..2))
}
pub fn nth2(&self) -> Byte {
Byte::new_unchecked(self.0.slice(2..3))
}
pub fn nth3(&self) -> Byte {
Byte::new_unchecked(self.0.slice(3..4))
}
pub fn nth4(&self) -> Byte {
Byte::new_unchecked(self.0.slice(4..5))
}
pub fn nth5(&self) -> Byte {
Byte::new_unchecked(self.0.slice(5..6))
}
pub fn nth6(&self) -> Byte {
Byte::new_unchecked(self.0.slice(6..7))
}
pub fn nth7(&self) -> Byte {
Byte::new_unchecked(self.0.slice(7..8))
}
pub fn raw_data(&self) -> molecule::bytes::Bytes {
self.as_bytes()
}
pub fn as_reader<'r>(&'r self) -> VmIndexReader<'r> {
VmIndexReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for VmIndex {
type Builder = VmIndexBuilder;
const NAME: &'static str = "VmIndex";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
VmIndex(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
VmIndexReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
VmIndexReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().set([
self.nth0(),
self.nth1(),
self.nth2(),
self.nth3(),
self.nth4(),
self.nth5(),
self.nth6(),
self.nth7(),
])
}
}
#[derive(Clone, Copy)]
pub struct VmIndexReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for VmIndexReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for VmIndexReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for VmIndexReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
let raw_data = hex_string(&self.raw_data());
write!(f, "{}(0x{})", Self::NAME, raw_data)
}
}
impl<'r> VmIndexReader<'r> {
pub const TOTAL_SIZE: usize = 8;
pub const ITEM_SIZE: usize = 1;
pub const ITEM_COUNT: usize = 8;
pub fn nth0(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[0..1])
}
pub fn nth1(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[1..2])
}
pub fn nth2(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[2..3])
}
pub fn nth3(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[3..4])
}
pub fn nth4(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[4..5])
}
pub fn nth5(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[5..6])
}
pub fn nth6(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[6..7])
}
pub fn nth7(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[7..8])
}
pub fn raw_data(&self) -> &'r [u8] {
self.as_slice()
}
}
impl<'r> molecule::prelude::Reader<'r> for VmIndexReader<'r> {
type Entity = VmIndex;
const NAME: &'static str = "VmIndexReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
VmIndexReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len != Self::TOTAL_SIZE {
return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len);
}
Ok(())
}
}
#[derive(Clone)]
pub struct VmIndexBuilder(pub(crate) [Byte; 8]);
impl ::core::fmt::Debug for VmIndexBuilder {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:?})", Self::NAME, &self.0[..])
}
}
impl ::core::default::Default for VmIndexBuilder {
fn default() -> Self {
VmIndexBuilder([
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
])
}
}
impl VmIndexBuilder {
pub const TOTAL_SIZE: usize = 8;
pub const ITEM_SIZE: usize = 1;
pub const ITEM_COUNT: usize = 8;
pub fn set(mut self, v: [Byte; 8]) -> Self {
self.0 = v;
self
}
pub fn nth0(mut self, v: Byte) -> Self {
self.0[0] = v;
self
}
pub fn nth1(mut self, v: Byte) -> Self {
self.0[1] = v;
self
}
pub fn nth2(mut self, v: Byte) -> Self {
self.0[2] = v;
self
}
pub fn nth3(mut self, v: Byte) -> Self {
self.0[3] = v;
self
}
pub fn nth4(mut self, v: Byte) -> Self {
self.0[4] = v;
self
}
pub fn nth5(mut self, v: Byte) -> Self {
self.0[5] = v;
self
}
pub fn nth6(mut self, v: Byte) -> Self {
self.0[6] = v;
self
}
pub fn nth7(mut self, v: Byte) -> Self {
self.0[7] = v;
self
}
}
impl molecule::prelude::Builder for VmIndexBuilder {
type Entity = VmIndex;
const NAME: &'static str = "VmIndexBuilder";
fn expected_length(&self) -> usize {
Self::TOTAL_SIZE
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
writer.write_all(self.0[0].as_slice())?;
writer.write_all(self.0[1].as_slice())?;
writer.write_all(self.0[2].as_slice())?;
writer.write_all(self.0[3].as_slice())?;
writer.write_all(self.0[4].as_slice())?;
writer.write_all(self.0[5].as_slice())?;
writer.write_all(self.0[6].as_slice())?;
writer.write_all(self.0[7].as_slice())?;
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
VmIndex::new_unchecked(inner.into())
}
}
impl From<[Byte; 8usize]> for VmIndex {
fn from(value: [Byte; 8usize]) -> Self {
Self::new_builder().set(value).build()
}
}
impl ::core::convert::TryFrom<&[Byte]> for VmIndex {
type Error = ::core::array::TryFromSliceError;
fn try_from(value: &[Byte]) -> Result<Self, ::core::array::TryFromSliceError> {
Ok(Self::new_builder()
.set(<&[Byte; 8usize]>::try_from(value)?.clone())
.build())
}
}
impl From<VmIndex> for [Byte; 8usize] {
#[track_caller]
fn from(value: VmIndex) -> Self {
[
value.nth0(),
value.nth1(),
value.nth2(),
value.nth3(),
value.nth4(),
value.nth5(),
value.nth6(),
value.nth7(),
]
}
}
impl From<[u8; 8usize]> for VmIndex {
fn from(value: [u8; 8usize]) -> Self {
VmIndexReader::new_unchecked(&value).to_entity()
}
}
impl ::core::convert::TryFrom<&[u8]> for VmIndex {
type Error = ::core::array::TryFromSliceError;
fn try_from(value: &[u8]) -> Result<Self, ::core::array::TryFromSliceError> {
Ok(<[u8; 8usize]>::try_from(value)?.into())
}
}
impl From<VmIndex> for [u8; 8usize] {
#[track_caller]
fn from(value: VmIndex) -> Self {
::core::convert::TryFrom::try_from(value.as_slice()).unwrap()
}
}
impl<'a> From<VmIndexReader<'a>> for &'a [u8; 8usize] {
#[track_caller]
fn from(value: VmIndexReader<'a>) -> Self {
::core::convert::TryFrom::try_from(value.as_slice()).unwrap()
}
}
impl<'a> From<&'a VmIndexReader<'a>> for &'a [u8; 8usize] {
#[track_caller]
fn from(value: &'a VmIndexReader<'a>) -> Self {
::core::convert::TryFrom::try_from(value.as_slice()).unwrap()
}
}
#[derive(Clone)]
pub struct FdIndex(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for FdIndex {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for FdIndex {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for FdIndex {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
let raw_data = hex_string(&self.raw_data());
write!(f, "{}(0x{})", Self::NAME, raw_data)
}
}
impl ::core::default::Default for FdIndex {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
FdIndex::new_unchecked(v)
}
}
impl FdIndex {
const DEFAULT_VALUE: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
pub const TOTAL_SIZE: usize = 8;
pub const ITEM_SIZE: usize = 1;
pub const ITEM_COUNT: usize = 8;
pub fn nth0(&self) -> Byte {
Byte::new_unchecked(self.0.slice(0..1))
}
pub fn nth1(&self) -> Byte {
Byte::new_unchecked(self.0.slice(1..2))
}
pub fn nth2(&self) -> Byte {
Byte::new_unchecked(self.0.slice(2..3))
}
pub fn nth3(&self) -> Byte {
Byte::new_unchecked(self.0.slice(3..4))
}
pub fn nth4(&self) -> Byte {
Byte::new_unchecked(self.0.slice(4..5))
}
pub fn nth5(&self) -> Byte {
Byte::new_unchecked(self.0.slice(5..6))
}
pub fn nth6(&self) -> Byte {
Byte::new_unchecked(self.0.slice(6..7))
}
pub fn nth7(&self) -> Byte {
Byte::new_unchecked(self.0.slice(7..8))
}
pub fn raw_data(&self) -> molecule::bytes::Bytes {
self.as_bytes()
}
pub fn as_reader<'r>(&'r self) -> FdIndexReader<'r> {
FdIndexReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for FdIndex {
type Builder = FdIndexBuilder;
const NAME: &'static str = "FdIndex";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
FdIndex(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
FdIndexReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
FdIndexReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().set([
self.nth0(),
self.nth1(),
self.nth2(),
self.nth3(),
self.nth4(),
self.nth5(),
self.nth6(),
self.nth7(),
])
}
}
#[derive(Clone, Copy)]
pub struct FdIndexReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for FdIndexReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for FdIndexReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for FdIndexReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
let raw_data = hex_string(&self.raw_data());
write!(f, "{}(0x{})", Self::NAME, raw_data)
}
}
impl<'r> FdIndexReader<'r> {
pub const TOTAL_SIZE: usize = 8;
pub const ITEM_SIZE: usize = 1;
pub const ITEM_COUNT: usize = 8;
pub fn nth0(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[0..1])
}
pub fn nth1(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[1..2])
}
pub fn nth2(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[2..3])
}
pub fn nth3(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[3..4])
}
pub fn nth4(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[4..5])
}
pub fn nth5(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[5..6])
}
pub fn nth6(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[6..7])
}
pub fn nth7(&self) -> ByteReader<'r> {
ByteReader::new_unchecked(&self.as_slice()[7..8])
}
pub fn raw_data(&self) -> &'r [u8] {
self.as_slice()
}
}
impl<'r> molecule::prelude::Reader<'r> for FdIndexReader<'r> {
type Entity = FdIndex;
const NAME: &'static str = "FdIndexReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
FdIndexReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len != Self::TOTAL_SIZE {
return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len);
}
Ok(())
}
}
#[derive(Clone)]
pub struct FdIndexBuilder(pub(crate) [Byte; 8]);
impl ::core::fmt::Debug for FdIndexBuilder {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:?})", Self::NAME, &self.0[..])
}
}
impl ::core::default::Default for FdIndexBuilder {
fn default() -> Self {
FdIndexBuilder([
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
Byte::default(),
])
}
}
impl FdIndexBuilder {
pub const TOTAL_SIZE: usize = 8;
pub const ITEM_SIZE: usize = 1;
pub const ITEM_COUNT: usize = 8;
pub fn set(mut self, v: [Byte; 8]) -> Self {
self.0 = v;
self
}
pub fn nth0(mut self, v: Byte) -> Self {
self.0[0] = v;
self
}
pub fn nth1(mut self, v: Byte) -> Self {
self.0[1] = v;
self
}
pub fn nth2(mut self, v: Byte) -> Self {
self.0[2] = v;
self
}
pub fn nth3(mut self, v: Byte) -> Self {
self.0[3] = v;
self
}
pub fn nth4(mut self, v: Byte) -> Self {
self.0[4] = v;
self
}
pub fn nth5(mut self, v: Byte) -> Self {
self.0[5] = v;
self
}
pub fn nth6(mut self, v: Byte) -> Self {
self.0[6] = v;
self
}
pub fn nth7(mut self, v: Byte) -> Self {
self.0[7] = v;
self
}
}
impl molecule::prelude::Builder for FdIndexBuilder {
type Entity = FdIndex;
const NAME: &'static str = "FdIndexBuilder";
fn expected_length(&self) -> usize {
Self::TOTAL_SIZE
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
writer.write_all(self.0[0].as_slice())?;
writer.write_all(self.0[1].as_slice())?;
writer.write_all(self.0[2].as_slice())?;
writer.write_all(self.0[3].as_slice())?;
writer.write_all(self.0[4].as_slice())?;
writer.write_all(self.0[5].as_slice())?;
writer.write_all(self.0[6].as_slice())?;
writer.write_all(self.0[7].as_slice())?;
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
FdIndex::new_unchecked(inner.into())
}
}
impl From<[Byte; 8usize]> for FdIndex {
fn from(value: [Byte; 8usize]) -> Self {
Self::new_builder().set(value).build()
}
}
impl ::core::convert::TryFrom<&[Byte]> for FdIndex {
type Error = ::core::array::TryFromSliceError;
fn try_from(value: &[Byte]) -> Result<Self, ::core::array::TryFromSliceError> {
Ok(Self::new_builder()
.set(<&[Byte; 8usize]>::try_from(value)?.clone())
.build())
}
}
impl From<FdIndex> for [Byte; 8usize] {
#[track_caller]
fn from(value: FdIndex) -> Self {
[
value.nth0(),
value.nth1(),
value.nth2(),
value.nth3(),
value.nth4(),
value.nth5(),
value.nth6(),
value.nth7(),
]
}
}
impl From<[u8; 8usize]> for FdIndex {
fn from(value: [u8; 8usize]) -> Self {
FdIndexReader::new_unchecked(&value).to_entity()
}
}
impl ::core::convert::TryFrom<&[u8]> for FdIndex {
type Error = ::core::array::TryFromSliceError;
fn try_from(value: &[u8]) -> Result<Self, ::core::array::TryFromSliceError> {
Ok(<[u8; 8usize]>::try_from(value)?.into())
}
}
impl From<FdIndex> for [u8; 8usize] {
#[track_caller]
fn from(value: FdIndex) -> Self {
::core::convert::TryFrom::try_from(value.as_slice()).unwrap()
}
}
impl<'a> From<FdIndexReader<'a>> for &'a [u8; 8usize] {
#[track_caller]
fn from(value: FdIndexReader<'a>) -> Self {
::core::convert::TryFrom::try_from(value.as_slice()).unwrap()
}
}
impl<'a> From<&'a FdIndexReader<'a>> for &'a [u8; 8usize] {
#[track_caller]
fn from(value: &'a FdIndexReader<'a>) -> Self {
::core::convert::TryFrom::try_from(value.as_slice()).unwrap()
}
}
#[derive(Clone)]
pub struct FdIndices(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for FdIndices {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for FdIndices {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for FdIndices {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} [", Self::NAME)?;
for i in 0..self.len() {
if i == 0 {
write!(f, "{}", self.get_unchecked(i))?;
} else {
write!(f, ", {}", self.get_unchecked(i))?;
}
}
write!(f, "]")
}
}
impl ::core::default::Default for FdIndices {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
FdIndices::new_unchecked(v)
}
}
impl FdIndices {
const DEFAULT_VALUE: [u8; 4] = [0, 0, 0, 0];
pub const ITEM_SIZE: usize = 8;
pub fn total_size(&self) -> usize {
molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.item_count()
}
pub fn item_count(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<FdIndex> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> FdIndex {
let start = molecule::NUMBER_SIZE + Self::ITEM_SIZE * idx;
let end = start + Self::ITEM_SIZE;
FdIndex::new_unchecked(self.0.slice(start..end))
}
pub fn as_reader<'r>(&'r self) -> FdIndicesReader<'r> {
FdIndicesReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for FdIndices {
type Builder = FdIndicesBuilder;
const NAME: &'static str = "FdIndices";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
FdIndices(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
FdIndicesReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
FdIndicesReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().extend(self.into_iter())
}
}
#[derive(Clone, Copy)]
pub struct FdIndicesReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for FdIndicesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for FdIndicesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for FdIndicesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} [", Self::NAME)?;
for i in 0..self.len() {
if i == 0 {
write!(f, "{}", self.get_unchecked(i))?;
} else {
write!(f, ", {}", self.get_unchecked(i))?;
}
}
write!(f, "]")
}
}
impl<'r> FdIndicesReader<'r> {
pub const ITEM_SIZE: usize = 8;
pub fn total_size(&self) -> usize {
molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.item_count()
}
pub fn item_count(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<FdIndexReader<'r>> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> FdIndexReader<'r> {
let start = molecule::NUMBER_SIZE + Self::ITEM_SIZE * idx;
let end = start + Self::ITEM_SIZE;
FdIndexReader::new_unchecked(&self.as_slice()[start..end])
}
}
impl<'r> molecule::prelude::Reader<'r> for FdIndicesReader<'r> {
type Entity = FdIndices;
const NAME: &'static str = "FdIndicesReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
FdIndicesReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len < molecule::NUMBER_SIZE {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len);
}
let item_count = molecule::unpack_number(slice) as usize;
if item_count == 0 {
if slice_len != molecule::NUMBER_SIZE {
return ve!(Self, TotalSizeNotMatch, molecule::NUMBER_SIZE, slice_len);
}
return Ok(());
}
let total_size = molecule::NUMBER_SIZE + Self::ITEM_SIZE * item_count;
if slice_len != total_size {
return ve!(Self, TotalSizeNotMatch, total_size, slice_len);
}
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct FdIndicesBuilder(pub(crate) Vec<FdIndex>);
impl FdIndicesBuilder {
pub const ITEM_SIZE: usize = 8;
pub fn set(mut self, v: Vec<FdIndex>) -> Self {
self.0 = v;
self
}
pub fn push(mut self, v: FdIndex) -> Self {
self.0.push(v);
self
}
pub fn extend<T: ::core::iter::IntoIterator<Item = FdIndex>>(mut self, iter: T) -> Self {
for elem in iter {
self.0.push(elem);
}
self
}
pub fn replace(&mut self, index: usize, v: FdIndex) -> Option<FdIndex> {
self.0
.get_mut(index)
.map(|item| ::core::mem::replace(item, v))
}
}
impl molecule::prelude::Builder for FdIndicesBuilder {
type Entity = FdIndices;
const NAME: &'static str = "FdIndicesBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.0.len()
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
writer.write_all(&molecule::pack_number(self.0.len() as molecule::Number))?;
for inner in &self.0[..] {
writer.write_all(inner.as_slice())?;
}
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
FdIndices::new_unchecked(inner.into())
}
}
pub struct FdIndicesIterator(FdIndices, usize, usize);
impl ::core::iter::Iterator for FdIndicesIterator {
type Item = FdIndex;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= self.2 {
None
} else {
let ret = self.0.get_unchecked(self.1);
self.1 += 1;
Some(ret)
}
}
}
impl ::core::iter::ExactSizeIterator for FdIndicesIterator {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::core::iter::IntoIterator for FdIndices {
type Item = FdIndex;
type IntoIter = FdIndicesIterator;
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
FdIndicesIterator(self, 0, len)
}
}
impl<'r> FdIndicesReader<'r> {
pub fn iter<'t>(&'t self) -> FdIndicesReaderIterator<'t, 'r> {
FdIndicesReaderIterator(&self, 0, self.len())
}
}
pub struct FdIndicesReaderIterator<'t, 'r>(&'t FdIndicesReader<'r>, usize, usize);
impl<'t: 'r, 'r> ::core::iter::Iterator for FdIndicesReaderIterator<'t, 'r> {
type Item = FdIndexReader<'t>;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= self.2 {
None
} else {
let ret = self.0.get_unchecked(self.1);
self.1 += 1;
Some(ret)
}
}
}
impl<'t: 'r, 'r> ::core::iter::ExactSizeIterator for FdIndicesReaderIterator<'t, 'r> {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::core::iter::FromIterator<FdIndex> for FdIndices {
fn from_iter<T: IntoIterator<Item = FdIndex>>(iter: T) -> Self {
Self::new_builder().extend(iter).build()
}
}
#[derive(Clone)]
pub struct Bytes(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for Bytes {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for Bytes {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for Bytes {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
let raw_data = hex_string(&self.raw_data());
write!(f, "{}(0x{})", Self::NAME, raw_data)
}
}
impl ::core::default::Default for Bytes {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
Bytes::new_unchecked(v)
}
}
impl Bytes {
const DEFAULT_VALUE: [u8; 4] = [0, 0, 0, 0];
pub const ITEM_SIZE: usize = 1;
pub fn total_size(&self) -> usize {
molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.item_count()
}
pub fn item_count(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<Byte> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> Byte {
let start = molecule::NUMBER_SIZE + Self::ITEM_SIZE * idx;
let end = start + Self::ITEM_SIZE;
Byte::new_unchecked(self.0.slice(start..end))
}
pub fn raw_data(&self) -> molecule::bytes::Bytes {
self.0.slice(molecule::NUMBER_SIZE..)
}
pub fn as_reader<'r>(&'r self) -> BytesReader<'r> {
BytesReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for Bytes {
type Builder = BytesBuilder;
const NAME: &'static str = "Bytes";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
Bytes(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
BytesReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
BytesReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().extend(self.into_iter())
}
}
#[derive(Clone, Copy)]
pub struct BytesReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for BytesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for BytesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for BytesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
let raw_data = hex_string(&self.raw_data());
write!(f, "{}(0x{})", Self::NAME, raw_data)
}
}
impl<'r> BytesReader<'r> {
pub const ITEM_SIZE: usize = 1;
pub fn total_size(&self) -> usize {
molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.item_count()
}
pub fn item_count(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<ByteReader<'r>> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> ByteReader<'r> {
let start = molecule::NUMBER_SIZE + Self::ITEM_SIZE * idx;
let end = start + Self::ITEM_SIZE;
ByteReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn raw_data(&self) -> &'r [u8] {
&self.as_slice()[molecule::NUMBER_SIZE..]
}
}
impl<'r> molecule::prelude::Reader<'r> for BytesReader<'r> {
type Entity = Bytes;
const NAME: &'static str = "BytesReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
BytesReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len < molecule::NUMBER_SIZE {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len);
}
let item_count = molecule::unpack_number(slice) as usize;
if item_count == 0 {
if slice_len != molecule::NUMBER_SIZE {
return ve!(Self, TotalSizeNotMatch, molecule::NUMBER_SIZE, slice_len);
}
return Ok(());
}
let total_size = molecule::NUMBER_SIZE + Self::ITEM_SIZE * item_count;
if slice_len != total_size {
return ve!(Self, TotalSizeNotMatch, total_size, slice_len);
}
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct BytesBuilder(pub(crate) Vec<Byte>);
impl BytesBuilder {
pub const ITEM_SIZE: usize = 1;
pub fn set(mut self, v: Vec<Byte>) -> Self {
self.0 = v;
self
}
pub fn push(mut self, v: Byte) -> Self {
self.0.push(v);
self
}
pub fn extend<T: ::core::iter::IntoIterator<Item = Byte>>(mut self, iter: T) -> Self {
for elem in iter {
self.0.push(elem);
}
self
}
pub fn replace(&mut self, index: usize, v: Byte) -> Option<Byte> {
self.0
.get_mut(index)
.map(|item| ::core::mem::replace(item, v))
}
}
impl molecule::prelude::Builder for BytesBuilder {
type Entity = Bytes;
const NAME: &'static str = "BytesBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.0.len()
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
writer.write_all(&molecule::pack_number(self.0.len() as molecule::Number))?;
for inner in &self.0[..] {
writer.write_all(inner.as_slice())?;
}
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
Bytes::new_unchecked(inner.into())
}
}
pub struct BytesIterator(Bytes, usize, usize);
impl ::core::iter::Iterator for BytesIterator {
type Item = Byte;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= self.2 {
None
} else {
let ret = self.0.get_unchecked(self.1);
self.1 += 1;
Some(ret)
}
}
}
impl ::core::iter::ExactSizeIterator for BytesIterator {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::core::iter::IntoIterator for Bytes {
type Item = Byte;
type IntoIter = BytesIterator;
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
BytesIterator(self, 0, len)
}
}
impl ::core::iter::FromIterator<Byte> for Bytes {
fn from_iter<T: IntoIterator<Item = Byte>>(iter: T) -> Self {
Self::new_builder().extend(iter).build()
}
}
impl ::core::iter::FromIterator<u8> for Bytes {
fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
Self::new_builder()
.extend(iter.into_iter().map(Into::into))
.build()
}
}
#[derive(Clone)]
pub struct Pipe(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for Pipe {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for Pipe {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for Pipe {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "vm", self.vm())?;
write!(f, ", {}: {}", "read_fd", self.read_fd())?;
write!(f, ", {}: {}", "write_fd", self.write_fd())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl ::core::default::Default for Pipe {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
Pipe::new_unchecked(v)
}
}
impl Pipe {
const DEFAULT_VALUE: [u8; 40] = [
40, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
pub const FIELD_COUNT: usize = 3;
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn field_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn count_extra_fields(&self) -> usize {
self.field_count() - Self::FIELD_COUNT
}
pub fn has_extra_fields(&self) -> bool {
Self::FIELD_COUNT != self.field_count()
}
pub fn vm(&self) -> VmIndex {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
VmIndex::new_unchecked(self.0.slice(start..end))
}
pub fn read_fd(&self) -> FdIndex {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[8..]) as usize;
let end = molecule::unpack_number(&slice[12..]) as usize;
FdIndex::new_unchecked(self.0.slice(start..end))
}
pub fn write_fd(&self) -> FdIndex {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[12..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&slice[16..]) as usize;
FdIndex::new_unchecked(self.0.slice(start..end))
} else {
FdIndex::new_unchecked(self.0.slice(start..))
}
}
pub fn as_reader<'r>(&'r self) -> PipeReader<'r> {
PipeReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for Pipe {
type Builder = PipeBuilder;
const NAME: &'static str = "Pipe";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
Pipe(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
PipeReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
PipeReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder()
.vm(self.vm())
.read_fd(self.read_fd())
.write_fd(self.write_fd())
}
}
#[derive(Clone, Copy)]
pub struct PipeReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for PipeReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for PipeReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for PipeReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "vm", self.vm())?;
write!(f, ", {}: {}", "read_fd", self.read_fd())?;
write!(f, ", {}: {}", "write_fd", self.write_fd())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl<'r> PipeReader<'r> {
pub const FIELD_COUNT: usize = 3;
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn field_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn count_extra_fields(&self) -> usize {
self.field_count() - Self::FIELD_COUNT
}
pub fn has_extra_fields(&self) -> bool {
Self::FIELD_COUNT != self.field_count()
}
pub fn vm(&self) -> VmIndexReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
VmIndexReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn read_fd(&self) -> FdIndexReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[8..]) as usize;
let end = molecule::unpack_number(&slice[12..]) as usize;
FdIndexReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn write_fd(&self) -> FdIndexReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[12..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&slice[16..]) as usize;
FdIndexReader::new_unchecked(&self.as_slice()[start..end])
} else {
FdIndexReader::new_unchecked(&self.as_slice()[start..])
}
}
}
impl<'r> molecule::prelude::Reader<'r> for PipeReader<'r> {
type Entity = Pipe;
const NAME: &'static str = "PipeReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
PipeReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len < molecule::NUMBER_SIZE {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len);
}
let total_size = molecule::unpack_number(slice) as usize;
if slice_len != total_size {
return ve!(Self, TotalSizeNotMatch, total_size, slice_len);
}
if slice_len < molecule::NUMBER_SIZE * 2 {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len);
}
let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize;
if !offset_first.is_multiple_of(molecule::NUMBER_SIZE)
|| offset_first < molecule::NUMBER_SIZE * 2
{
return ve!(Self, OffsetsNotMatch);
}
if slice_len < offset_first {
return ve!(Self, HeaderIsBroken, offset_first, slice_len);
}
let field_count = offset_first / molecule::NUMBER_SIZE - 1;
if field_count < Self::FIELD_COUNT {
return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count);
} else if !compatible && field_count > Self::FIELD_COUNT {
return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count);
};
let mut offsets: Vec<usize> = slice[molecule::NUMBER_SIZE..offset_first]
.chunks_exact(molecule::NUMBER_SIZE)
.map(|x| molecule::unpack_number(x) as usize)
.collect();
offsets.push(total_size);
if offsets.windows(2).any(|i| i[0] > i[1]) {
return ve!(Self, OffsetsNotMatch);
}
VmIndexReader::verify(&slice[offsets[0]..offsets[1]], compatible)?;
FdIndexReader::verify(&slice[offsets[1]..offsets[2]], compatible)?;
FdIndexReader::verify(&slice[offsets[2]..offsets[3]], compatible)?;
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct PipeBuilder {
pub(crate) vm: VmIndex,
pub(crate) read_fd: FdIndex,
pub(crate) write_fd: FdIndex,
}
impl PipeBuilder {
pub const FIELD_COUNT: usize = 3;
pub fn vm(mut self, v: VmIndex) -> Self {
self.vm = v;
self
}
pub fn read_fd(mut self, v: FdIndex) -> Self {
self.read_fd = v;
self
}
pub fn write_fd(mut self, v: FdIndex) -> Self {
self.write_fd = v;
self
}
}
impl molecule::prelude::Builder for PipeBuilder {
type Entity = Pipe;
const NAME: &'static str = "PipeBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1)
+ self.vm.as_slice().len()
+ self.read_fd.as_slice().len()
+ self.write_fd.as_slice().len()
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1);
let mut offsets = Vec::with_capacity(Self::FIELD_COUNT);
offsets.push(total_size);
total_size += self.vm.as_slice().len();
offsets.push(total_size);
total_size += self.read_fd.as_slice().len();
offsets.push(total_size);
total_size += self.write_fd.as_slice().len();
writer.write_all(&molecule::pack_number(total_size as molecule::Number))?;
for offset in offsets.into_iter() {
writer.write_all(&molecule::pack_number(offset as molecule::Number))?;
}
writer.write_all(self.vm.as_slice())?;
writer.write_all(self.read_fd.as_slice())?;
writer.write_all(self.write_fd.as_slice())?;
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
Pipe::new_unchecked(inner.into())
}
}
#[derive(Clone)]
pub struct Pipes(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for Pipes {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for Pipes {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for Pipes {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} [", Self::NAME)?;
for i in 0..self.len() {
if i == 0 {
write!(f, "{}", self.get_unchecked(i))?;
} else {
write!(f, ", {}", self.get_unchecked(i))?;
}
}
write!(f, "]")
}
}
impl ::core::default::Default for Pipes {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
Pipes::new_unchecked(v)
}
}
impl Pipes {
const DEFAULT_VALUE: [u8; 4] = [4, 0, 0, 0];
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn item_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<Pipe> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> Pipe {
let slice = self.as_slice();
let start_idx = molecule::NUMBER_SIZE * (1 + idx);
let start = molecule::unpack_number(&slice[start_idx..]) as usize;
if idx == self.len() - 1 {
Pipe::new_unchecked(self.0.slice(start..))
} else {
let end_idx = start_idx + molecule::NUMBER_SIZE;
let end = molecule::unpack_number(&slice[end_idx..]) as usize;
Pipe::new_unchecked(self.0.slice(start..end))
}
}
pub fn as_reader<'r>(&'r self) -> PipesReader<'r> {
PipesReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for Pipes {
type Builder = PipesBuilder;
const NAME: &'static str = "Pipes";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
Pipes(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
PipesReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
PipesReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().extend(self.into_iter())
}
}
#[derive(Clone, Copy)]
pub struct PipesReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for PipesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for PipesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for PipesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} [", Self::NAME)?;
for i in 0..self.len() {
if i == 0 {
write!(f, "{}", self.get_unchecked(i))?;
} else {
write!(f, ", {}", self.get_unchecked(i))?;
}
}
write!(f, "]")
}
}
impl<'r> PipesReader<'r> {
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn item_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<PipeReader<'r>> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> PipeReader<'r> {
let slice = self.as_slice();
let start_idx = molecule::NUMBER_SIZE * (1 + idx);
let start = molecule::unpack_number(&slice[start_idx..]) as usize;
if idx == self.len() - 1 {
PipeReader::new_unchecked(&self.as_slice()[start..])
} else {
let end_idx = start_idx + molecule::NUMBER_SIZE;
let end = molecule::unpack_number(&slice[end_idx..]) as usize;
PipeReader::new_unchecked(&self.as_slice()[start..end])
}
}
}
impl<'r> molecule::prelude::Reader<'r> for PipesReader<'r> {
type Entity = Pipes;
const NAME: &'static str = "PipesReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
PipesReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len < molecule::NUMBER_SIZE {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len);
}
let total_size = molecule::unpack_number(slice) as usize;
if slice_len != total_size {
return ve!(Self, TotalSizeNotMatch, total_size, slice_len);
}
if slice_len == molecule::NUMBER_SIZE {
return Ok(());
}
if slice_len < molecule::NUMBER_SIZE * 2 {
return ve!(
Self,
TotalSizeNotMatch,
molecule::NUMBER_SIZE * 2,
slice_len
);
}
let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize;
if !offset_first.is_multiple_of(molecule::NUMBER_SIZE)
|| offset_first < molecule::NUMBER_SIZE * 2
{
return ve!(Self, OffsetsNotMatch);
}
if slice_len < offset_first {
return ve!(Self, HeaderIsBroken, offset_first, slice_len);
}
let mut offsets: Vec<usize> = slice[molecule::NUMBER_SIZE..offset_first]
.chunks_exact(molecule::NUMBER_SIZE)
.map(|x| molecule::unpack_number(x) as usize)
.collect();
offsets.push(total_size);
if offsets.windows(2).any(|i| i[0] > i[1]) {
return ve!(Self, OffsetsNotMatch);
}
for pair in offsets.windows(2) {
let start = pair[0];
let end = pair[1];
PipeReader::verify(&slice[start..end], compatible)?;
}
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct PipesBuilder(pub(crate) Vec<Pipe>);
impl PipesBuilder {
pub fn set(mut self, v: Vec<Pipe>) -> Self {
self.0 = v;
self
}
pub fn push(mut self, v: Pipe) -> Self {
self.0.push(v);
self
}
pub fn extend<T: ::core::iter::IntoIterator<Item = Pipe>>(mut self, iter: T) -> Self {
for elem in iter {
self.0.push(elem);
}
self
}
pub fn replace(&mut self, index: usize, v: Pipe) -> Option<Pipe> {
self.0
.get_mut(index)
.map(|item| ::core::mem::replace(item, v))
}
}
impl molecule::prelude::Builder for PipesBuilder {
type Entity = Pipes;
const NAME: &'static str = "PipesBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE * (self.0.len() + 1)
+ self
.0
.iter()
.map(|inner| inner.as_slice().len())
.sum::<usize>()
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
let item_count = self.0.len();
if item_count == 0 {
writer.write_all(&molecule::pack_number(
molecule::NUMBER_SIZE as molecule::Number,
))?;
} else {
let (total_size, offsets) = self.0.iter().fold(
(
molecule::NUMBER_SIZE * (item_count + 1),
Vec::with_capacity(item_count),
),
|(start, mut offsets), inner| {
offsets.push(start);
(start + inner.as_slice().len(), offsets)
},
);
writer.write_all(&molecule::pack_number(total_size as molecule::Number))?;
for offset in offsets.into_iter() {
writer.write_all(&molecule::pack_number(offset as molecule::Number))?;
}
for inner in self.0.iter() {
writer.write_all(inner.as_slice())?;
}
}
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
Pipes::new_unchecked(inner.into())
}
}
pub struct PipesIterator(Pipes, usize, usize);
impl ::core::iter::Iterator for PipesIterator {
type Item = Pipe;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= self.2 {
None
} else {
let ret = self.0.get_unchecked(self.1);
self.1 += 1;
Some(ret)
}
}
}
impl ::core::iter::ExactSizeIterator for PipesIterator {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::core::iter::IntoIterator for Pipes {
type Item = Pipe;
type IntoIter = PipesIterator;
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
PipesIterator(self, 0, len)
}
}
impl<'r> PipesReader<'r> {
pub fn iter<'t>(&'t self) -> PipesReaderIterator<'t, 'r> {
PipesReaderIterator(&self, 0, self.len())
}
}
pub struct PipesReaderIterator<'t, 'r>(&'t PipesReader<'r>, usize, usize);
impl<'t: 'r, 'r> ::core::iter::Iterator for PipesReaderIterator<'t, 'r> {
type Item = PipeReader<'t>;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= self.2 {
None
} else {
let ret = self.0.get_unchecked(self.1);
self.1 += 1;
Some(ret)
}
}
}
impl<'t: 'r, 'r> ::core::iter::ExactSizeIterator for PipesReaderIterator<'t, 'r> {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::core::iter::FromIterator<Pipe> for Pipes {
fn from_iter<T: IntoIterator<Item = Pipe>>(iter: T) -> Self {
Self::new_builder().extend(iter).build()
}
}
#[derive(Clone)]
pub struct Write(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for Write {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for Write {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for Write {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "from", self.from())?;
write!(f, ", {}: {}", "from_fd", self.from_fd())?;
write!(f, ", {}: {}", "to", self.to())?;
write!(f, ", {}: {}", "to_fd", self.to_fd())?;
write!(f, ", {}: {}", "data", self.data())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl ::core::default::Default for Write {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
Write::new_unchecked(v)
}
}
impl Write {
const DEFAULT_VALUE: [u8; 60] = [
60, 0, 0, 0, 24, 0, 0, 0, 32, 0, 0, 0, 40, 0, 0, 0, 48, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
];
pub const FIELD_COUNT: usize = 5;
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn field_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn count_extra_fields(&self) -> usize {
self.field_count() - Self::FIELD_COUNT
}
pub fn has_extra_fields(&self) -> bool {
Self::FIELD_COUNT != self.field_count()
}
pub fn from(&self) -> VmIndex {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
VmIndex::new_unchecked(self.0.slice(start..end))
}
pub fn from_fd(&self) -> FdIndex {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[8..]) as usize;
let end = molecule::unpack_number(&slice[12..]) as usize;
FdIndex::new_unchecked(self.0.slice(start..end))
}
pub fn to(&self) -> VmIndex {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[12..]) as usize;
let end = molecule::unpack_number(&slice[16..]) as usize;
VmIndex::new_unchecked(self.0.slice(start..end))
}
pub fn to_fd(&self) -> FdIndex {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[16..]) as usize;
let end = molecule::unpack_number(&slice[20..]) as usize;
FdIndex::new_unchecked(self.0.slice(start..end))
}
pub fn data(&self) -> Bytes {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[20..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&slice[24..]) as usize;
Bytes::new_unchecked(self.0.slice(start..end))
} else {
Bytes::new_unchecked(self.0.slice(start..))
}
}
pub fn as_reader<'r>(&'r self) -> WriteReader<'r> {
WriteReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for Write {
type Builder = WriteBuilder;
const NAME: &'static str = "Write";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
Write(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
WriteReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
WriteReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder()
.from(self.from())
.from_fd(self.from_fd())
.to(self.to())
.to_fd(self.to_fd())
.data(self.data())
}
}
#[derive(Clone, Copy)]
pub struct WriteReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for WriteReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for WriteReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for WriteReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "from", self.from())?;
write!(f, ", {}: {}", "from_fd", self.from_fd())?;
write!(f, ", {}: {}", "to", self.to())?;
write!(f, ", {}: {}", "to_fd", self.to_fd())?;
write!(f, ", {}: {}", "data", self.data())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl<'r> WriteReader<'r> {
pub const FIELD_COUNT: usize = 5;
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn field_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn count_extra_fields(&self) -> usize {
self.field_count() - Self::FIELD_COUNT
}
pub fn has_extra_fields(&self) -> bool {
Self::FIELD_COUNT != self.field_count()
}
pub fn from(&self) -> VmIndexReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
VmIndexReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn from_fd(&self) -> FdIndexReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[8..]) as usize;
let end = molecule::unpack_number(&slice[12..]) as usize;
FdIndexReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn to(&self) -> VmIndexReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[12..]) as usize;
let end = molecule::unpack_number(&slice[16..]) as usize;
VmIndexReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn to_fd(&self) -> FdIndexReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[16..]) as usize;
let end = molecule::unpack_number(&slice[20..]) as usize;
FdIndexReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn data(&self) -> BytesReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[20..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&slice[24..]) as usize;
BytesReader::new_unchecked(&self.as_slice()[start..end])
} else {
BytesReader::new_unchecked(&self.as_slice()[start..])
}
}
}
impl<'r> molecule::prelude::Reader<'r> for WriteReader<'r> {
type Entity = Write;
const NAME: &'static str = "WriteReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
WriteReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len < molecule::NUMBER_SIZE {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len);
}
let total_size = molecule::unpack_number(slice) as usize;
if slice_len != total_size {
return ve!(Self, TotalSizeNotMatch, total_size, slice_len);
}
if slice_len < molecule::NUMBER_SIZE * 2 {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len);
}
let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize;
if !offset_first.is_multiple_of(molecule::NUMBER_SIZE)
|| offset_first < molecule::NUMBER_SIZE * 2
{
return ve!(Self, OffsetsNotMatch);
}
if slice_len < offset_first {
return ve!(Self, HeaderIsBroken, offset_first, slice_len);
}
let field_count = offset_first / molecule::NUMBER_SIZE - 1;
if field_count < Self::FIELD_COUNT {
return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count);
} else if !compatible && field_count > Self::FIELD_COUNT {
return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count);
};
let mut offsets: Vec<usize> = slice[molecule::NUMBER_SIZE..offset_first]
.chunks_exact(molecule::NUMBER_SIZE)
.map(|x| molecule::unpack_number(x) as usize)
.collect();
offsets.push(total_size);
if offsets.windows(2).any(|i| i[0] > i[1]) {
return ve!(Self, OffsetsNotMatch);
}
VmIndexReader::verify(&slice[offsets[0]..offsets[1]], compatible)?;
FdIndexReader::verify(&slice[offsets[1]..offsets[2]], compatible)?;
VmIndexReader::verify(&slice[offsets[2]..offsets[3]], compatible)?;
FdIndexReader::verify(&slice[offsets[3]..offsets[4]], compatible)?;
BytesReader::verify(&slice[offsets[4]..offsets[5]], compatible)?;
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct WriteBuilder {
pub(crate) from: VmIndex,
pub(crate) from_fd: FdIndex,
pub(crate) to: VmIndex,
pub(crate) to_fd: FdIndex,
pub(crate) data: Bytes,
}
impl WriteBuilder {
pub const FIELD_COUNT: usize = 5;
pub fn from(mut self, v: VmIndex) -> Self {
self.from = v;
self
}
pub fn from_fd(mut self, v: FdIndex) -> Self {
self.from_fd = v;
self
}
pub fn to(mut self, v: VmIndex) -> Self {
self.to = v;
self
}
pub fn to_fd(mut self, v: FdIndex) -> Self {
self.to_fd = v;
self
}
pub fn data(mut self, v: Bytes) -> Self {
self.data = v;
self
}
}
impl molecule::prelude::Builder for WriteBuilder {
type Entity = Write;
const NAME: &'static str = "WriteBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1)
+ self.from.as_slice().len()
+ self.from_fd.as_slice().len()
+ self.to.as_slice().len()
+ self.to_fd.as_slice().len()
+ self.data.as_slice().len()
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1);
let mut offsets = Vec::with_capacity(Self::FIELD_COUNT);
offsets.push(total_size);
total_size += self.from.as_slice().len();
offsets.push(total_size);
total_size += self.from_fd.as_slice().len();
offsets.push(total_size);
total_size += self.to.as_slice().len();
offsets.push(total_size);
total_size += self.to_fd.as_slice().len();
offsets.push(total_size);
total_size += self.data.as_slice().len();
writer.write_all(&molecule::pack_number(total_size as molecule::Number))?;
for offset in offsets.into_iter() {
writer.write_all(&molecule::pack_number(offset as molecule::Number))?;
}
writer.write_all(self.from.as_slice())?;
writer.write_all(self.from_fd.as_slice())?;
writer.write_all(self.to.as_slice())?;
writer.write_all(self.to_fd.as_slice())?;
writer.write_all(self.data.as_slice())?;
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
Write::new_unchecked(inner.into())
}
}
#[derive(Clone)]
pub struct Writes(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for Writes {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for Writes {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for Writes {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} [", Self::NAME)?;
for i in 0..self.len() {
if i == 0 {
write!(f, "{}", self.get_unchecked(i))?;
} else {
write!(f, ", {}", self.get_unchecked(i))?;
}
}
write!(f, "]")
}
}
impl ::core::default::Default for Writes {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
Writes::new_unchecked(v)
}
}
impl Writes {
const DEFAULT_VALUE: [u8; 4] = [4, 0, 0, 0];
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn item_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<Write> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> Write {
let slice = self.as_slice();
let start_idx = molecule::NUMBER_SIZE * (1 + idx);
let start = molecule::unpack_number(&slice[start_idx..]) as usize;
if idx == self.len() - 1 {
Write::new_unchecked(self.0.slice(start..))
} else {
let end_idx = start_idx + molecule::NUMBER_SIZE;
let end = molecule::unpack_number(&slice[end_idx..]) as usize;
Write::new_unchecked(self.0.slice(start..end))
}
}
pub fn as_reader<'r>(&'r self) -> WritesReader<'r> {
WritesReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for Writes {
type Builder = WritesBuilder;
const NAME: &'static str = "Writes";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
Writes(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
WritesReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
WritesReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().extend(self.into_iter())
}
}
#[derive(Clone, Copy)]
pub struct WritesReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for WritesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for WritesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for WritesReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} [", Self::NAME)?;
for i in 0..self.len() {
if i == 0 {
write!(f, "{}", self.get_unchecked(i))?;
} else {
write!(f, ", {}", self.get_unchecked(i))?;
}
}
write!(f, "]")
}
}
impl<'r> WritesReader<'r> {
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn item_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<WriteReader<'r>> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> WriteReader<'r> {
let slice = self.as_slice();
let start_idx = molecule::NUMBER_SIZE * (1 + idx);
let start = molecule::unpack_number(&slice[start_idx..]) as usize;
if idx == self.len() - 1 {
WriteReader::new_unchecked(&self.as_slice()[start..])
} else {
let end_idx = start_idx + molecule::NUMBER_SIZE;
let end = molecule::unpack_number(&slice[end_idx..]) as usize;
WriteReader::new_unchecked(&self.as_slice()[start..end])
}
}
}
impl<'r> molecule::prelude::Reader<'r> for WritesReader<'r> {
type Entity = Writes;
const NAME: &'static str = "WritesReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
WritesReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len < molecule::NUMBER_SIZE {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len);
}
let total_size = molecule::unpack_number(slice) as usize;
if slice_len != total_size {
return ve!(Self, TotalSizeNotMatch, total_size, slice_len);
}
if slice_len == molecule::NUMBER_SIZE {
return Ok(());
}
if slice_len < molecule::NUMBER_SIZE * 2 {
return ve!(
Self,
TotalSizeNotMatch,
molecule::NUMBER_SIZE * 2,
slice_len
);
}
let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize;
if !offset_first.is_multiple_of(molecule::NUMBER_SIZE)
|| offset_first < molecule::NUMBER_SIZE * 2
{
return ve!(Self, OffsetsNotMatch);
}
if slice_len < offset_first {
return ve!(Self, HeaderIsBroken, offset_first, slice_len);
}
let mut offsets: Vec<usize> = slice[molecule::NUMBER_SIZE..offset_first]
.chunks_exact(molecule::NUMBER_SIZE)
.map(|x| molecule::unpack_number(x) as usize)
.collect();
offsets.push(total_size);
if offsets.windows(2).any(|i| i[0] > i[1]) {
return ve!(Self, OffsetsNotMatch);
}
for pair in offsets.windows(2) {
let start = pair[0];
let end = pair[1];
WriteReader::verify(&slice[start..end], compatible)?;
}
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct WritesBuilder(pub(crate) Vec<Write>);
impl WritesBuilder {
pub fn set(mut self, v: Vec<Write>) -> Self {
self.0 = v;
self
}
pub fn push(mut self, v: Write) -> Self {
self.0.push(v);
self
}
pub fn extend<T: ::core::iter::IntoIterator<Item = Write>>(mut self, iter: T) -> Self {
for elem in iter {
self.0.push(elem);
}
self
}
pub fn replace(&mut self, index: usize, v: Write) -> Option<Write> {
self.0
.get_mut(index)
.map(|item| ::core::mem::replace(item, v))
}
}
impl molecule::prelude::Builder for WritesBuilder {
type Entity = Writes;
const NAME: &'static str = "WritesBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE * (self.0.len() + 1)
+ self
.0
.iter()
.map(|inner| inner.as_slice().len())
.sum::<usize>()
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
let item_count = self.0.len();
if item_count == 0 {
writer.write_all(&molecule::pack_number(
molecule::NUMBER_SIZE as molecule::Number,
))?;
} else {
let (total_size, offsets) = self.0.iter().fold(
(
molecule::NUMBER_SIZE * (item_count + 1),
Vec::with_capacity(item_count),
),
|(start, mut offsets), inner| {
offsets.push(start);
(start + inner.as_slice().len(), offsets)
},
);
writer.write_all(&molecule::pack_number(total_size as molecule::Number))?;
for offset in offsets.into_iter() {
writer.write_all(&molecule::pack_number(offset as molecule::Number))?;
}
for inner in self.0.iter() {
writer.write_all(inner.as_slice())?;
}
}
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
Writes::new_unchecked(inner.into())
}
}
pub struct WritesIterator(Writes, usize, usize);
impl ::core::iter::Iterator for WritesIterator {
type Item = Write;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= self.2 {
None
} else {
let ret = self.0.get_unchecked(self.1);
self.1 += 1;
Some(ret)
}
}
}
impl ::core::iter::ExactSizeIterator for WritesIterator {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::core::iter::IntoIterator for Writes {
type Item = Write;
type IntoIter = WritesIterator;
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
WritesIterator(self, 0, len)
}
}
impl<'r> WritesReader<'r> {
pub fn iter<'t>(&'t self) -> WritesReaderIterator<'t, 'r> {
WritesReaderIterator(&self, 0, self.len())
}
}
pub struct WritesReaderIterator<'t, 'r>(&'t WritesReader<'r>, usize, usize);
impl<'t: 'r, 'r> ::core::iter::Iterator for WritesReaderIterator<'t, 'r> {
type Item = WriteReader<'t>;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= self.2 {
None
} else {
let ret = self.0.get_unchecked(self.1);
self.1 += 1;
Some(ret)
}
}
}
impl<'t: 'r, 'r> ::core::iter::ExactSizeIterator for WritesReaderIterator<'t, 'r> {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::core::iter::FromIterator<Write> for Writes {
fn from_iter<T: IntoIterator<Item = Write>>(iter: T) -> Self {
Self::new_builder().extend(iter).build()
}
}
#[derive(Clone)]
pub struct Spawn(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for Spawn {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for Spawn {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for Spawn {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "from", self.from())?;
write!(f, ", {}: {}", "child", self.child())?;
write!(f, ", {}: {}", "fds", self.fds())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl ::core::default::Default for Spawn {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
Spawn::new_unchecked(v)
}
}
impl Spawn {
const DEFAULT_VALUE: [u8; 36] = [
36, 0, 0, 0, 16, 0, 0, 0, 24, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
];
pub const FIELD_COUNT: usize = 3;
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn field_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn count_extra_fields(&self) -> usize {
self.field_count() - Self::FIELD_COUNT
}
pub fn has_extra_fields(&self) -> bool {
Self::FIELD_COUNT != self.field_count()
}
pub fn from(&self) -> VmIndex {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
VmIndex::new_unchecked(self.0.slice(start..end))
}
pub fn child(&self) -> VmIndex {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[8..]) as usize;
let end = molecule::unpack_number(&slice[12..]) as usize;
VmIndex::new_unchecked(self.0.slice(start..end))
}
pub fn fds(&self) -> FdIndices {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[12..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&slice[16..]) as usize;
FdIndices::new_unchecked(self.0.slice(start..end))
} else {
FdIndices::new_unchecked(self.0.slice(start..))
}
}
pub fn as_reader<'r>(&'r self) -> SpawnReader<'r> {
SpawnReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for Spawn {
type Builder = SpawnBuilder;
const NAME: &'static str = "Spawn";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
Spawn(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
SpawnReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
SpawnReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder()
.from(self.from())
.child(self.child())
.fds(self.fds())
}
}
#[derive(Clone, Copy)]
pub struct SpawnReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for SpawnReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for SpawnReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for SpawnReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "from", self.from())?;
write!(f, ", {}: {}", "child", self.child())?;
write!(f, ", {}: {}", "fds", self.fds())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl<'r> SpawnReader<'r> {
pub const FIELD_COUNT: usize = 3;
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn field_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn count_extra_fields(&self) -> usize {
self.field_count() - Self::FIELD_COUNT
}
pub fn has_extra_fields(&self) -> bool {
Self::FIELD_COUNT != self.field_count()
}
pub fn from(&self) -> VmIndexReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
VmIndexReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn child(&self) -> VmIndexReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[8..]) as usize;
let end = molecule::unpack_number(&slice[12..]) as usize;
VmIndexReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn fds(&self) -> FdIndicesReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[12..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&slice[16..]) as usize;
FdIndicesReader::new_unchecked(&self.as_slice()[start..end])
} else {
FdIndicesReader::new_unchecked(&self.as_slice()[start..])
}
}
}
impl<'r> molecule::prelude::Reader<'r> for SpawnReader<'r> {
type Entity = Spawn;
const NAME: &'static str = "SpawnReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
SpawnReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len < molecule::NUMBER_SIZE {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len);
}
let total_size = molecule::unpack_number(slice) as usize;
if slice_len != total_size {
return ve!(Self, TotalSizeNotMatch, total_size, slice_len);
}
if slice_len < molecule::NUMBER_SIZE * 2 {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len);
}
let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize;
if !offset_first.is_multiple_of(molecule::NUMBER_SIZE)
|| offset_first < molecule::NUMBER_SIZE * 2
{
return ve!(Self, OffsetsNotMatch);
}
if slice_len < offset_first {
return ve!(Self, HeaderIsBroken, offset_first, slice_len);
}
let field_count = offset_first / molecule::NUMBER_SIZE - 1;
if field_count < Self::FIELD_COUNT {
return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count);
} else if !compatible && field_count > Self::FIELD_COUNT {
return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count);
};
let mut offsets: Vec<usize> = slice[molecule::NUMBER_SIZE..offset_first]
.chunks_exact(molecule::NUMBER_SIZE)
.map(|x| molecule::unpack_number(x) as usize)
.collect();
offsets.push(total_size);
if offsets.windows(2).any(|i| i[0] > i[1]) {
return ve!(Self, OffsetsNotMatch);
}
VmIndexReader::verify(&slice[offsets[0]..offsets[1]], compatible)?;
VmIndexReader::verify(&slice[offsets[1]..offsets[2]], compatible)?;
FdIndicesReader::verify(&slice[offsets[2]..offsets[3]], compatible)?;
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct SpawnBuilder {
pub(crate) from: VmIndex,
pub(crate) child: VmIndex,
pub(crate) fds: FdIndices,
}
impl SpawnBuilder {
pub const FIELD_COUNT: usize = 3;
pub fn from(mut self, v: VmIndex) -> Self {
self.from = v;
self
}
pub fn child(mut self, v: VmIndex) -> Self {
self.child = v;
self
}
pub fn fds(mut self, v: FdIndices) -> Self {
self.fds = v;
self
}
}
impl molecule::prelude::Builder for SpawnBuilder {
type Entity = Spawn;
const NAME: &'static str = "SpawnBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1)
+ self.from.as_slice().len()
+ self.child.as_slice().len()
+ self.fds.as_slice().len()
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1);
let mut offsets = Vec::with_capacity(Self::FIELD_COUNT);
offsets.push(total_size);
total_size += self.from.as_slice().len();
offsets.push(total_size);
total_size += self.child.as_slice().len();
offsets.push(total_size);
total_size += self.fds.as_slice().len();
writer.write_all(&molecule::pack_number(total_size as molecule::Number))?;
for offset in offsets.into_iter() {
writer.write_all(&molecule::pack_number(offset as molecule::Number))?;
}
writer.write_all(self.from.as_slice())?;
writer.write_all(self.child.as_slice())?;
writer.write_all(self.fds.as_slice())?;
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
Spawn::new_unchecked(inner.into())
}
}
#[derive(Clone)]
pub struct Spawns(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for Spawns {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for Spawns {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for Spawns {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} [", Self::NAME)?;
for i in 0..self.len() {
if i == 0 {
write!(f, "{}", self.get_unchecked(i))?;
} else {
write!(f, ", {}", self.get_unchecked(i))?;
}
}
write!(f, "]")
}
}
impl ::core::default::Default for Spawns {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
Spawns::new_unchecked(v)
}
}
impl Spawns {
const DEFAULT_VALUE: [u8; 4] = [4, 0, 0, 0];
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn item_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<Spawn> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> Spawn {
let slice = self.as_slice();
let start_idx = molecule::NUMBER_SIZE * (1 + idx);
let start = molecule::unpack_number(&slice[start_idx..]) as usize;
if idx == self.len() - 1 {
Spawn::new_unchecked(self.0.slice(start..))
} else {
let end_idx = start_idx + molecule::NUMBER_SIZE;
let end = molecule::unpack_number(&slice[end_idx..]) as usize;
Spawn::new_unchecked(self.0.slice(start..end))
}
}
pub fn as_reader<'r>(&'r self) -> SpawnsReader<'r> {
SpawnsReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for Spawns {
type Builder = SpawnsBuilder;
const NAME: &'static str = "Spawns";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
Spawns(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
SpawnsReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
SpawnsReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().extend(self.into_iter())
}
}
#[derive(Clone, Copy)]
pub struct SpawnsReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for SpawnsReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for SpawnsReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for SpawnsReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} [", Self::NAME)?;
for i in 0..self.len() {
if i == 0 {
write!(f, "{}", self.get_unchecked(i))?;
} else {
write!(f, ", {}", self.get_unchecked(i))?;
}
}
write!(f, "]")
}
}
impl<'r> SpawnsReader<'r> {
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn item_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<SpawnReader<'r>> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> SpawnReader<'r> {
let slice = self.as_slice();
let start_idx = molecule::NUMBER_SIZE * (1 + idx);
let start = molecule::unpack_number(&slice[start_idx..]) as usize;
if idx == self.len() - 1 {
SpawnReader::new_unchecked(&self.as_slice()[start..])
} else {
let end_idx = start_idx + molecule::NUMBER_SIZE;
let end = molecule::unpack_number(&slice[end_idx..]) as usize;
SpawnReader::new_unchecked(&self.as_slice()[start..end])
}
}
}
impl<'r> molecule::prelude::Reader<'r> for SpawnsReader<'r> {
type Entity = Spawns;
const NAME: &'static str = "SpawnsReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
SpawnsReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len < molecule::NUMBER_SIZE {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len);
}
let total_size = molecule::unpack_number(slice) as usize;
if slice_len != total_size {
return ve!(Self, TotalSizeNotMatch, total_size, slice_len);
}
if slice_len == molecule::NUMBER_SIZE {
return Ok(());
}
if slice_len < molecule::NUMBER_SIZE * 2 {
return ve!(
Self,
TotalSizeNotMatch,
molecule::NUMBER_SIZE * 2,
slice_len
);
}
let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize;
if !offset_first.is_multiple_of(molecule::NUMBER_SIZE)
|| offset_first < molecule::NUMBER_SIZE * 2
{
return ve!(Self, OffsetsNotMatch);
}
if slice_len < offset_first {
return ve!(Self, HeaderIsBroken, offset_first, slice_len);
}
let mut offsets: Vec<usize> = slice[molecule::NUMBER_SIZE..offset_first]
.chunks_exact(molecule::NUMBER_SIZE)
.map(|x| molecule::unpack_number(x) as usize)
.collect();
offsets.push(total_size);
if offsets.windows(2).any(|i| i[0] > i[1]) {
return ve!(Self, OffsetsNotMatch);
}
for pair in offsets.windows(2) {
let start = pair[0];
let end = pair[1];
SpawnReader::verify(&slice[start..end], compatible)?;
}
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct SpawnsBuilder(pub(crate) Vec<Spawn>);
impl SpawnsBuilder {
pub fn set(mut self, v: Vec<Spawn>) -> Self {
self.0 = v;
self
}
pub fn push(mut self, v: Spawn) -> Self {
self.0.push(v);
self
}
pub fn extend<T: ::core::iter::IntoIterator<Item = Spawn>>(mut self, iter: T) -> Self {
for elem in iter {
self.0.push(elem);
}
self
}
pub fn replace(&mut self, index: usize, v: Spawn) -> Option<Spawn> {
self.0
.get_mut(index)
.map(|item| ::core::mem::replace(item, v))
}
}
impl molecule::prelude::Builder for SpawnsBuilder {
type Entity = Spawns;
const NAME: &'static str = "SpawnsBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE * (self.0.len() + 1)
+ self
.0
.iter()
.map(|inner| inner.as_slice().len())
.sum::<usize>()
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
let item_count = self.0.len();
if item_count == 0 {
writer.write_all(&molecule::pack_number(
molecule::NUMBER_SIZE as molecule::Number,
))?;
} else {
let (total_size, offsets) = self.0.iter().fold(
(
molecule::NUMBER_SIZE * (item_count + 1),
Vec::with_capacity(item_count),
),
|(start, mut offsets), inner| {
offsets.push(start);
(start + inner.as_slice().len(), offsets)
},
);
writer.write_all(&molecule::pack_number(total_size as molecule::Number))?;
for offset in offsets.into_iter() {
writer.write_all(&molecule::pack_number(offset as molecule::Number))?;
}
for inner in self.0.iter() {
writer.write_all(inner.as_slice())?;
}
}
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
Spawns::new_unchecked(inner.into())
}
}
pub struct SpawnsIterator(Spawns, usize, usize);
impl ::core::iter::Iterator for SpawnsIterator {
type Item = Spawn;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= self.2 {
None
} else {
let ret = self.0.get_unchecked(self.1);
self.1 += 1;
Some(ret)
}
}
}
impl ::core::iter::ExactSizeIterator for SpawnsIterator {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::core::iter::IntoIterator for Spawns {
type Item = Spawn;
type IntoIter = SpawnsIterator;
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
SpawnsIterator(self, 0, len)
}
}
impl<'r> SpawnsReader<'r> {
pub fn iter<'t>(&'t self) -> SpawnsReaderIterator<'t, 'r> {
SpawnsReaderIterator(&self, 0, self.len())
}
}
pub struct SpawnsReaderIterator<'t, 'r>(&'t SpawnsReader<'r>, usize, usize);
impl<'t: 'r, 'r> ::core::iter::Iterator for SpawnsReaderIterator<'t, 'r> {
type Item = SpawnReader<'t>;
fn next(&mut self) -> Option<Self::Item> {
if self.1 >= self.2 {
None
} else {
let ret = self.0.get_unchecked(self.1);
self.1 += 1;
Some(ret)
}
}
}
impl<'t: 'r, 'r> ::core::iter::ExactSizeIterator for SpawnsReaderIterator<'t, 'r> {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::core::iter::FromIterator<Spawn> for Spawns {
fn from_iter<T: IntoIterator<Item = Spawn>>(iter: T) -> Self {
Self::new_builder().extend(iter).build()
}
}
#[derive(Clone)]
pub struct Data(molecule::bytes::Bytes);
impl ::core::fmt::LowerHex for Data {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl ::core::fmt::Debug for Data {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::core::fmt::Display for Data {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "spawns", self.spawns())?;
write!(f, ", {}: {}", "pipes", self.pipes())?;
write!(f, ", {}: {}", "writes", self.writes())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl ::core::default::Default for Data {
fn default() -> Self {
let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE);
Data::new_unchecked(v)
}
}
impl Data {
const DEFAULT_VALUE: [u8; 28] = [
28, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0,
];
pub const FIELD_COUNT: usize = 3;
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn field_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn count_extra_fields(&self) -> usize {
self.field_count() - Self::FIELD_COUNT
}
pub fn has_extra_fields(&self) -> bool {
Self::FIELD_COUNT != self.field_count()
}
pub fn spawns(&self) -> Spawns {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
Spawns::new_unchecked(self.0.slice(start..end))
}
pub fn pipes(&self) -> Pipes {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[8..]) as usize;
let end = molecule::unpack_number(&slice[12..]) as usize;
Pipes::new_unchecked(self.0.slice(start..end))
}
pub fn writes(&self) -> Writes {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[12..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&slice[16..]) as usize;
Writes::new_unchecked(self.0.slice(start..end))
} else {
Writes::new_unchecked(self.0.slice(start..))
}
}
pub fn as_reader<'r>(&'r self) -> DataReader<'r> {
DataReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for Data {
type Builder = DataBuilder;
const NAME: &'static str = "Data";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
Data(data)
}
fn as_bytes(&self) -> molecule::bytes::Bytes {
self.0.clone()
}
fn as_slice(&self) -> &[u8] {
&self.0[..]
}
fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
DataReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
DataReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder()
.spawns(self.spawns())
.pipes(self.pipes())
.writes(self.writes())
}
}
#[derive(Clone, Copy)]
pub struct DataReader<'r>(&'r [u8]);
impl<'r> ::core::fmt::LowerHex for DataReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use molecule::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()))
}
}
impl<'r> ::core::fmt::Debug for DataReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::core::fmt::Display for DataReader<'r> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "spawns", self.spawns())?;
write!(f, ", {}: {}", "pipes", self.pipes())?;
write!(f, ", {}: {}", "writes", self.writes())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl<'r> DataReader<'r> {
pub const FIELD_COUNT: usize = 3;
pub fn total_size(&self) -> usize {
molecule::unpack_number(self.as_slice()) as usize
}
pub fn field_count(&self) -> usize {
if self.total_size() == molecule::NUMBER_SIZE {
0
} else {
(molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1
}
}
pub fn count_extra_fields(&self) -> usize {
self.field_count() - Self::FIELD_COUNT
}
pub fn has_extra_fields(&self) -> bool {
Self::FIELD_COUNT != self.field_count()
}
pub fn spawns(&self) -> SpawnsReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
SpawnsReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn pipes(&self) -> PipesReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[8..]) as usize;
let end = molecule::unpack_number(&slice[12..]) as usize;
PipesReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn writes(&self) -> WritesReader<'r> {
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[12..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&slice[16..]) as usize;
WritesReader::new_unchecked(&self.as_slice()[start..end])
} else {
WritesReader::new_unchecked(&self.as_slice()[start..])
}
}
}
impl<'r> molecule::prelude::Reader<'r> for DataReader<'r> {
type Entity = Data;
const NAME: &'static str = "DataReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().to_owned().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
DataReader(slice)
}
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> {
use molecule::verification_error as ve;
let slice_len = slice.len();
if slice_len < molecule::NUMBER_SIZE {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len);
}
let total_size = molecule::unpack_number(slice) as usize;
if slice_len != total_size {
return ve!(Self, TotalSizeNotMatch, total_size, slice_len);
}
if slice_len < molecule::NUMBER_SIZE * 2 {
return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len);
}
let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize;
if !offset_first.is_multiple_of(molecule::NUMBER_SIZE)
|| offset_first < molecule::NUMBER_SIZE * 2
{
return ve!(Self, OffsetsNotMatch);
}
if slice_len < offset_first {
return ve!(Self, HeaderIsBroken, offset_first, slice_len);
}
let field_count = offset_first / molecule::NUMBER_SIZE - 1;
if field_count < Self::FIELD_COUNT {
return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count);
} else if !compatible && field_count > Self::FIELD_COUNT {
return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count);
};
let mut offsets: Vec<usize> = slice[molecule::NUMBER_SIZE..offset_first]
.chunks_exact(molecule::NUMBER_SIZE)
.map(|x| molecule::unpack_number(x) as usize)
.collect();
offsets.push(total_size);
if offsets.windows(2).any(|i| i[0] > i[1]) {
return ve!(Self, OffsetsNotMatch);
}
SpawnsReader::verify(&slice[offsets[0]..offsets[1]], compatible)?;
PipesReader::verify(&slice[offsets[1]..offsets[2]], compatible)?;
WritesReader::verify(&slice[offsets[2]..offsets[3]], compatible)?;
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct DataBuilder {
pub(crate) spawns: Spawns,
pub(crate) pipes: Pipes,
pub(crate) writes: Writes,
}
impl DataBuilder {
pub const FIELD_COUNT: usize = 3;
pub fn spawns(mut self, v: Spawns) -> Self {
self.spawns = v;
self
}
pub fn pipes(mut self, v: Pipes) -> Self {
self.pipes = v;
self
}
pub fn writes(mut self, v: Writes) -> Self {
self.writes = v;
self
}
}
impl molecule::prelude::Builder for DataBuilder {
type Entity = Data;
const NAME: &'static str = "DataBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1)
+ self.spawns.as_slice().len()
+ self.pipes.as_slice().len()
+ self.writes.as_slice().len()
}
fn write<W: molecule::io::Write>(&self, writer: &mut W) -> molecule::io::Result<()> {
let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1);
let mut offsets = Vec::with_capacity(Self::FIELD_COUNT);
offsets.push(total_size);
total_size += self.spawns.as_slice().len();
offsets.push(total_size);
total_size += self.pipes.as_slice().len();
offsets.push(total_size);
total_size += self.writes.as_slice().len();
writer.write_all(&molecule::pack_number(total_size as molecule::Number))?;
for offset in offsets.into_iter() {
writer.write_all(&molecule::pack_number(offset as molecule::Number))?;
}
writer.write_all(self.spawns.as_slice())?;
writer.write_all(self.pipes.as_slice())?;
writer.write_all(self.writes.as_slice())?;
Ok(())
}
fn build(&self) -> Self::Entity {
let mut inner = Vec::with_capacity(self.expected_length());
self.write(&mut inner)
.unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME));
Data::new_unchecked(inner.into())
}
}