use molecule::prelude::*;
#[derive(Clone)]
pub struct Bytes(molecule::bytes::Bytes);
impl ::std::fmt::LowerHex for Bytes {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()).unwrap())
}
}
impl ::std::fmt::Debug for Bytes {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::std::fmt::Display for Bytes {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
let raw_data = hex_string(&self.raw_data()).unwrap();
write!(f, "{}(0x{})", Self::NAME, raw_data)
}
}
impl ::std::default::Default for Bytes {
fn default() -> Self {
let v: Vec<u8> = vec![0, 0, 0, 0];
Bytes::new_unchecked(v.into())
}
}
impl Bytes {
pub const ITEM_SIZE: usize = 1;
pub fn total_size(&self) -> usize {
molecule::NUMBER_SIZE * (self.item_count() + 1)
}
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_from(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 {
::std::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> ::std::fmt::LowerHex for BytesReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()).unwrap())
}
}
impl<'r> ::std::fmt::Debug for BytesReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::std::fmt::Display for BytesReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
let raw_data = hex_string(&self.raw_data()).unwrap();
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_count() + 1)
}
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().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(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: ::std::iter::IntoIterator<Item = Byte>>(mut self, iter: T) -> Self {
for elem in iter {
self.0.push(elem);
}
self
}
}
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: ::std::io::Write>(&self, writer: &mut W) -> ::std::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 ::std::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 ::std::iter::ExactSizeIterator for BytesIterator {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::std::iter::IntoIterator for Bytes {
type Item = Byte;
type IntoIter = BytesIterator;
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
BytesIterator(self, 0, len)
}
}
#[derive(Clone)]
pub struct AddressVec(molecule::bytes::Bytes);
impl ::std::fmt::LowerHex for AddressVec {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()).unwrap())
}
}
impl ::std::fmt::Debug for AddressVec {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::std::fmt::Display for AddressVec {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::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 ::std::default::Default for AddressVec {
fn default() -> Self {
let v: Vec<u8> = vec![4, 0, 0, 0];
AddressVec::new_unchecked(v.into())
}
}
impl AddressVec {
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 item_offsets(&self) -> &[[u8; 4]] {
molecule::unpack_number_vec(&self.as_slice()[molecule::NUMBER_SIZE..])
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<Address> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> Address {
let offsets = self.item_offsets();
let start = molecule::unpack_number(&offsets[idx][..]) as usize;
if idx == self.len() - 1 {
Address::new_unchecked(self.0.slice_from(start))
} else {
let end = molecule::unpack_number(&offsets[idx + 1][..]) as usize;
Address::new_unchecked(self.0.slice(start, end))
}
}
pub fn as_reader<'r>(&'r self) -> AddressVecReader<'r> {
AddressVecReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for AddressVec {
type Builder = AddressVecBuilder;
const NAME: &'static str = "AddressVec";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
AddressVec(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> {
AddressVecReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
AddressVecReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::std::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().extend(self.into_iter())
}
}
#[derive(Clone, Copy)]
pub struct AddressVecReader<'r>(&'r [u8]);
impl<'r> ::std::fmt::LowerHex for AddressVecReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()).unwrap())
}
}
impl<'r> ::std::fmt::Debug for AddressVecReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::std::fmt::Display for AddressVecReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::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> AddressVecReader<'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 item_offsets(&self) -> &[[u8; 4]] {
molecule::unpack_number_vec(&self.as_slice()[molecule::NUMBER_SIZE..])
}
pub fn len(&self) -> usize {
self.item_count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, idx: usize) -> Option<AddressReader<'r>> {
if idx >= self.len() {
None
} else {
Some(self.get_unchecked(idx))
}
}
pub fn get_unchecked(&self, idx: usize) -> AddressReader<'r> {
let offsets = self.item_offsets();
let start = molecule::unpack_number(&offsets[idx][..]) as usize;
if idx == self.len() - 1 {
AddressReader::new_unchecked(&self.as_slice()[start..])
} else {
let end = molecule::unpack_number(&offsets[idx + 1][..]) as usize;
AddressReader::new_unchecked(&self.as_slice()[start..end])
}
}
}
impl<'r> molecule::prelude::Reader<'r> for AddressVecReader<'r> {
type Entity = AddressVec;
const NAME: &'static str = "AddressVecReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
AddressVecReader(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 % 4 != 0 || offset_first < molecule::NUMBER_SIZE * 2 {
return ve!(Self, OffsetsNotMatch);
}
let item_count = offset_first / 4 - 1;
let header_size = molecule::NUMBER_SIZE * (item_count + 1);
if slice_len < header_size {
return ve!(Self, HeaderIsBroken, header_size, slice_len);
}
let ptr = molecule::unpack_number_vec(&slice[molecule::NUMBER_SIZE..]);
let mut offsets: Vec<usize> = ptr[..item_count]
.iter()
.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];
AddressReader::verify(&slice[start..end], compatible)?;
}
Ok(())
}
}
#[derive(Debug, Default)]
pub struct AddressVecBuilder(pub(crate) Vec<Address>);
impl AddressVecBuilder {
pub fn set(mut self, v: Vec<Address>) -> Self {
self.0 = v;
self
}
pub fn push(mut self, v: Address) -> Self {
self.0.push(v);
self
}
pub fn extend<T: ::std::iter::IntoIterator<Item = Address>>(mut self, iter: T) -> Self {
for elem in iter {
self.0.push(elem);
}
self
}
}
impl molecule::prelude::Builder for AddressVecBuilder {
type Entity = AddressVec;
const NAME: &'static str = "AddressVecBuilder";
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: ::std::io::Write>(&self, writer: &mut W) -> ::std::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));
AddressVec::new_unchecked(inner.into())
}
}
pub struct AddressVecIterator(AddressVec, usize, usize);
impl ::std::iter::Iterator for AddressVecIterator {
type Item = Address;
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 ::std::iter::ExactSizeIterator for AddressVecIterator {
fn len(&self) -> usize {
self.2 - self.1
}
}
impl ::std::iter::IntoIterator for AddressVec {
type Item = Address;
type IntoIter = AddressVecIterator;
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
AddressVecIterator(self, 0, len)
}
}
impl<'r> AddressVecReader<'r> {
pub fn iter<'t>(&'t self) -> AddressVecReaderIterator<'t, 'r> {
AddressVecReaderIterator(&self, 0, self.len())
}
}
pub struct AddressVecReaderIterator<'t, 'r>(&'t AddressVecReader<'r>, usize, usize);
impl<'t: 'r, 'r> ::std::iter::Iterator for AddressVecReaderIterator<'t, 'r> {
type Item = AddressReader<'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> ::std::iter::ExactSizeIterator for AddressVecReaderIterator<'t, 'r> {
fn len(&self) -> usize {
self.2 - self.1
}
}
#[derive(Clone)]
pub struct Address(molecule::bytes::Bytes);
impl ::std::fmt::LowerHex for Address {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()).unwrap())
}
}
impl ::std::fmt::Debug for Address {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::std::fmt::Display for Address {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "bytes", self.bytes())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl ::std::default::Default for Address {
fn default() -> Self {
let v: Vec<u8> = vec![12, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0];
Address::new_unchecked(v.into())
}
}
impl Address {
pub const FIELD_COUNT: usize = 1;
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 field_offsets(&self) -> &[[u8; 4]] {
molecule::unpack_number_vec(&self.as_slice()[molecule::NUMBER_SIZE..])
}
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 bytes(&self) -> Bytes {
let offsets = self.field_offsets();
let start = molecule::unpack_number(&offsets[0][..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&offsets[1][..]) as usize;
Bytes::new_unchecked(self.0.slice(start, end))
} else {
Bytes::new_unchecked(self.0.slice_from(start))
}
}
pub fn as_reader<'r>(&'r self) -> AddressReader<'r> {
AddressReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for Address {
type Builder = AddressBuilder;
const NAME: &'static str = "Address";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
Address(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> {
AddressReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
AddressReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::std::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().bytes(self.bytes())
}
}
#[derive(Clone, Copy)]
pub struct AddressReader<'r>(&'r [u8]);
impl<'r> ::std::fmt::LowerHex for AddressReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()).unwrap())
}
}
impl<'r> ::std::fmt::Debug for AddressReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::std::fmt::Display for AddressReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "bytes", self.bytes())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl<'r> AddressReader<'r> {
pub const FIELD_COUNT: usize = 1;
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 field_offsets(&self) -> &[[u8; 4]] {
molecule::unpack_number_vec(&self.as_slice()[molecule::NUMBER_SIZE..])
}
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 bytes(&self) -> BytesReader<'r> {
let offsets = self.field_offsets();
let start = molecule::unpack_number(&offsets[0][..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&offsets[1][..]) 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 AddressReader<'r> {
type Entity = Address;
const NAME: &'static str = "AddressReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
AddressReader(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 && Self::FIELD_COUNT == 0 {
return Ok(());
}
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 % 4 != 0 || offset_first < molecule::NUMBER_SIZE * 2 {
return ve!(Self, OffsetsNotMatch);
}
let field_count = offset_first / 4 - 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 header_size = molecule::NUMBER_SIZE * (field_count + 1);
if slice_len < header_size {
return ve!(Self, HeaderIsBroken, header_size, slice_len);
}
let ptr = molecule::unpack_number_vec(&slice[molecule::NUMBER_SIZE..]);
let mut offsets: Vec<usize> = ptr[..field_count]
.iter()
.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);
}
BytesReader::verify(&slice[offsets[0]..offsets[1]], compatible)?;
Ok(())
}
}
#[derive(Debug, Default)]
pub struct AddressBuilder {
pub(crate) bytes: Bytes,
}
impl AddressBuilder {
pub const FIELD_COUNT: usize = 1;
pub fn bytes(mut self, v: Bytes) -> Self {
self.bytes = v;
self
}
}
impl molecule::prelude::Builder for AddressBuilder {
type Entity = Address;
const NAME: &'static str = "AddressBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + self.bytes.as_slice().len()
}
fn write<W: ::std::io::Write>(&self, writer: &mut W) -> ::std::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.bytes.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.bytes.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));
Address::new_unchecked(inner.into())
}
}
#[derive(Clone)]
pub struct IdentifyMessage(molecule::bytes::Bytes);
impl ::std::fmt::LowerHex for IdentifyMessage {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()).unwrap())
}
}
impl ::std::fmt::Debug for IdentifyMessage {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl ::std::fmt::Display for IdentifyMessage {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "listen_addrs", self.listen_addrs())?;
write!(f, ", {}: {}", "observed_addr", self.observed_addr())?;
write!(f, ", {}: {}", "identify", self.identify())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl ::std::default::Default for IdentifyMessage {
fn default() -> Self {
let v: Vec<u8> = vec![
36, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 32, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
];
IdentifyMessage::new_unchecked(v.into())
}
}
impl IdentifyMessage {
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 field_offsets(&self) -> &[[u8; 4]] {
molecule::unpack_number_vec(&self.as_slice()[molecule::NUMBER_SIZE..])
}
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 listen_addrs(&self) -> AddressVec {
let offsets = self.field_offsets();
let start = molecule::unpack_number(&offsets[0][..]) as usize;
let end = molecule::unpack_number(&offsets[1][..]) as usize;
AddressVec::new_unchecked(self.0.slice(start, end))
}
pub fn observed_addr(&self) -> Address {
let offsets = self.field_offsets();
let start = molecule::unpack_number(&offsets[1][..]) as usize;
let end = molecule::unpack_number(&offsets[2][..]) as usize;
Address::new_unchecked(self.0.slice(start, end))
}
pub fn identify(&self) -> Bytes {
let offsets = self.field_offsets();
let start = molecule::unpack_number(&offsets[2][..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&offsets[3][..]) as usize;
Bytes::new_unchecked(self.0.slice(start, end))
} else {
Bytes::new_unchecked(self.0.slice_from(start))
}
}
pub fn as_reader<'r>(&'r self) -> IdentifyMessageReader<'r> {
IdentifyMessageReader::new_unchecked(self.as_slice())
}
}
impl molecule::prelude::Entity for IdentifyMessage {
type Builder = IdentifyMessageBuilder;
const NAME: &'static str = "IdentifyMessage";
fn new_unchecked(data: molecule::bytes::Bytes) -> Self {
IdentifyMessage(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> {
IdentifyMessageReader::from_slice(slice).map(|reader| reader.to_entity())
}
fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult<Self> {
IdentifyMessageReader::from_compatible_slice(slice).map(|reader| reader.to_entity())
}
fn new_builder() -> Self::Builder {
::std::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder()
.listen_addrs(self.listen_addrs())
.observed_addr(self.observed_addr())
.identify(self.identify())
}
}
#[derive(Clone, Copy)]
pub struct IdentifyMessageReader<'r>(&'r [u8]);
impl<'r> ::std::fmt::LowerHex for IdentifyMessageReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use molecule::faster_hex::hex_string;
if f.alternate() {
write!(f, "0x")?;
}
write!(f, "{}", hex_string(self.as_slice()).unwrap())
}
}
impl<'r> ::std::fmt::Debug for IdentifyMessageReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}({:#x})", Self::NAME, self)
}
}
impl<'r> ::std::fmt::Display for IdentifyMessageReader<'r> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "listen_addrs", self.listen_addrs())?;
write!(f, ", {}: {}", "observed_addr", self.observed_addr())?;
write!(f, ", {}: {}", "identify", self.identify())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl<'r> IdentifyMessageReader<'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 field_offsets(&self) -> &[[u8; 4]] {
molecule::unpack_number_vec(&self.as_slice()[molecule::NUMBER_SIZE..])
}
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 listen_addrs(&self) -> AddressVecReader<'r> {
let offsets = self.field_offsets();
let start = molecule::unpack_number(&offsets[0][..]) as usize;
let end = molecule::unpack_number(&offsets[1][..]) as usize;
AddressVecReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn observed_addr(&self) -> AddressReader<'r> {
let offsets = self.field_offsets();
let start = molecule::unpack_number(&offsets[1][..]) as usize;
let end = molecule::unpack_number(&offsets[2][..]) as usize;
AddressReader::new_unchecked(&self.as_slice()[start..end])
}
pub fn identify(&self) -> BytesReader<'r> {
let offsets = self.field_offsets();
let start = molecule::unpack_number(&offsets[2][..]) as usize;
if self.has_extra_fields() {
let end = molecule::unpack_number(&offsets[3][..]) 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 IdentifyMessageReader<'r> {
type Entity = IdentifyMessage;
const NAME: &'static str = "IdentifyMessageReader";
fn to_entity(&self) -> Self::Entity {
Self::Entity::new_unchecked(self.as_slice().into())
}
fn new_unchecked(slice: &'r [u8]) -> Self {
IdentifyMessageReader(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 && Self::FIELD_COUNT == 0 {
return Ok(());
}
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 % 4 != 0 || offset_first < molecule::NUMBER_SIZE * 2 {
return ve!(Self, OffsetsNotMatch);
}
let field_count = offset_first / 4 - 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 header_size = molecule::NUMBER_SIZE * (field_count + 1);
if slice_len < header_size {
return ve!(Self, HeaderIsBroken, header_size, slice_len);
}
let ptr = molecule::unpack_number_vec(&slice[molecule::NUMBER_SIZE..]);
let mut offsets: Vec<usize> = ptr[..field_count]
.iter()
.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);
}
AddressVecReader::verify(&slice[offsets[0]..offsets[1]], compatible)?;
AddressReader::verify(&slice[offsets[1]..offsets[2]], compatible)?;
BytesReader::verify(&slice[offsets[2]..offsets[3]], compatible)?;
Ok(())
}
}
#[derive(Debug, Default)]
pub struct IdentifyMessageBuilder {
pub(crate) listen_addrs: AddressVec,
pub(crate) observed_addr: Address,
pub(crate) identify: Bytes,
}
impl IdentifyMessageBuilder {
pub const FIELD_COUNT: usize = 3;
pub fn listen_addrs(mut self, v: AddressVec) -> Self {
self.listen_addrs = v;
self
}
pub fn observed_addr(mut self, v: Address) -> Self {
self.observed_addr = v;
self
}
pub fn identify(mut self, v: Bytes) -> Self {
self.identify = v;
self
}
}
impl molecule::prelude::Builder for IdentifyMessageBuilder {
type Entity = IdentifyMessage;
const NAME: &'static str = "IdentifyMessageBuilder";
fn expected_length(&self) -> usize {
molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1)
+ self.listen_addrs.as_slice().len()
+ self.observed_addr.as_slice().len()
+ self.identify.as_slice().len()
}
fn write<W: ::std::io::Write>(&self, writer: &mut W) -> ::std::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.listen_addrs.as_slice().len();
offsets.push(total_size);
total_size += self.observed_addr.as_slice().len();
offsets.push(total_size);
total_size += self.identify.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.listen_addrs.as_slice())?;
writer.write_all(self.observed_addr.as_slice())?;
writer.write_all(self.identify.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));
IdentifyMessage::new_unchecked(inner.into())
}
}