Skip to content

Commit

Permalink
Merge branch 'feature/dict-find'
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexagon committed Aug 9, 2023
2 parents c198aac + 4a3621f commit 2b4896d
Show file tree
Hide file tree
Showing 9 changed files with 678 additions and 133 deletions.
14 changes: 6 additions & 8 deletions src/boc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! BOC (Bag Of Cells) implementation.

use std::borrow::Borrow;

use crate::cell::{Cell, CellBuilder, DefaultFinalizer, DynCell, Finalizer, Load, Store};

/// BOC decoder implementation.
Expand Down Expand Up @@ -55,29 +53,29 @@ impl Boc {
#[cfg(any(feature = "base64", test))]
pub fn encode_base64<T>(cell: T) -> String
where
T: Borrow<DynCell>,
T: AsRef<DynCell>,
{
crate::util::encode_base64(Self::encode(cell))
}

/// Encodes the specified cell tree as BOC.
pub fn encode<T>(cell: T) -> Vec<u8>
where
T: Borrow<DynCell>,
T: AsRef<DynCell>,
{
fn encode_impl(cell: &DynCell) -> Vec<u8> {
let mut result = Vec::new();
ser::BocHeader::<ahash::RandomState>::new(cell).encode(&mut result);
result
}
encode_impl(cell.borrow())
encode_impl(cell.as_ref())
}

/// Encodes a pair of cell trees as BOC.
pub fn encode_pair<T1, T2>((cell1, cell2): (T1, T2)) -> Vec<u8>
where
T1: Borrow<DynCell>,
T2: Borrow<DynCell>,
T1: AsRef<DynCell>,
T2: AsRef<DynCell>,
{
fn encode_pair_impl(cell1: &DynCell, cell2: &DynCell) -> Vec<u8> {
let mut result = Vec::new();
Expand All @@ -86,7 +84,7 @@ impl Boc {
encoder.encode(&mut result);
result
}
encode_pair_impl(cell1.borrow(), cell2.borrow())
encode_pair_impl(cell1.as_ref(), cell2.as_ref())
}

/// Decodes a `base64` encoded BOC into a cell tree
Expand Down
27 changes: 19 additions & 8 deletions src/cell/builder.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::borrow::Borrow;
use std::mem::MaybeUninit;
use std::rc::Rc;
use std::sync::Arc;
Expand Down Expand Up @@ -574,7 +573,7 @@ impl CellBuilder {
#[inline]
pub fn store_cell_data<T>(&mut self, value: T) -> Result<(), Error>
where
T: Borrow<DynCell>,
T: AsRef<DynCell>,
{
fn store_cell_data_impl(builder: &mut CellBuilder, value: &DynCell) -> Result<(), Error> {
store_raw(
Expand All @@ -584,15 +583,15 @@ impl CellBuilder {
value.bit_len(),
)
}
store_cell_data_impl(self, value.borrow())
store_cell_data_impl(self, value.as_ref())
}

/// Tries to store the remaining slice data in the cell,
/// returning `false` if there is not enough remaining capacity.
#[inline]
pub fn store_slice_data<'a, T>(&mut self, value: T) -> Result<(), Error>
where
T: Borrow<CellSlice<'a>>,
T: AsRef<CellSlice<'a>>,
{
fn store_slice_data_impl(
builder: &mut CellBuilder,
Expand All @@ -609,7 +608,7 @@ impl CellBuilder {
Err(Error::CellOverflow)
}
}
store_slice_data_impl(self, value.borrow())
store_slice_data_impl(self, value.as_ref())
}

/// Tries to prepend bytes to the cell data (but only the specified number of bits),
Expand Down Expand Up @@ -764,7 +763,7 @@ impl CellBuilder {
#[inline]
pub fn store_slice<'a, T>(&mut self, value: T) -> Result<(), Error>
where
T: Borrow<CellSlice<'a>>,
T: AsRef<CellSlice<'a>>,
{
fn store_slice_impl(builder: &mut CellBuilder, value: &CellSlice<'_>) -> Result<(), Error> {
if builder.bit_len + value.remaining_bits() <= MAX_BIT_LEN
Expand All @@ -779,7 +778,7 @@ impl CellBuilder {
Err(Error::CellOverflow)
}
}
store_slice_impl(self, value.borrow())
store_slice_impl(self, value.as_ref())
}

/// Tries to build a new cell using the specified finalizer.
Expand Down Expand Up @@ -873,7 +872,7 @@ impl CellBuilder {

/// Returns an object which will display data as a bitstring
/// with a termination bit.
pub fn display_data(&self) -> impl std::fmt::Display + '_ {
pub fn display_data(&self) -> impl std::fmt::Display + std::fmt::Binary + '_ {
struct DisplayData<'a>(&'a CellBuilder);

impl std::fmt::Display for DisplayData<'_> {
Expand All @@ -888,6 +887,18 @@ impl CellBuilder {
}
}

impl std::fmt::Binary for DisplayData<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Binary::fmt(
&Bitstring {
bytes: &self.0.data,
bit_len: self.0.bit_len,
},
f,
)
}
}

DisplayData(self)
}
}
Expand Down
28 changes: 27 additions & 1 deletion src/cell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ pub type DynCell = dyn CellImpl;
#[cfg(feature = "sync")]
pub type DynCell = dyn CellImpl + Send + Sync;

impl AsRef<DynCell> for DynCell {
#[inline(always)]
fn as_ref(&self) -> &Self {
self
}
}

impl AsMut<DynCell> for DynCell {
#[inline(always)]
fn as_mut(&mut self) -> &mut Self {
self
}
}

/// Represents the interface of a well-formed cell.
///
/// Since all basic operations are implements via dynamic dispatch,
Expand Down Expand Up @@ -254,7 +268,7 @@ impl DynCell {
/// Returns an object which will display cell data as a bitstring
/// with a termination bit.
#[inline]
pub fn display_data(&self) -> impl std::fmt::Display + '_ {
pub fn display_data(&self) -> impl std::fmt::Display + std::fmt::Binary + '_ {
struct DisplayData<'a>(&'a DynCell);

impl std::fmt::Display for DisplayData<'_> {
Expand All @@ -269,6 +283,18 @@ impl DynCell {
}
}

impl std::fmt::Binary for DisplayData<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Binary::fmt(
&Bitstring {
bytes: self.0.data(),
bit_len: self.0.bit_len(),
},
f,
)
}
}

DisplayData(self)
}

Expand Down
50 changes: 35 additions & 15 deletions src/cell/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ impl CellSliceRange {
#[inline]
pub fn apply<T>(self, cell: &T) -> Result<CellSlice<'_>, Error>
where
T: AsRef<DynCell>,
T: AsRef<DynCell> + ?Sized,
{
fn apply_impl(range: CellSliceRange, cell: &DynCell) -> Result<CellSlice<'_>, Error> {
// Handle pruned branch access
Expand Down Expand Up @@ -230,7 +230,7 @@ impl CellSliceRange {
/// - range is in cell bounds
pub unsafe fn apply_unchecked<T>(self, cell: &T) -> CellSlice<'_>
where
T: AsRef<DynCell>,
T: AsRef<DynCell> + ?Sized,
{
CellSlice {
range: self,
Expand Down Expand Up @@ -324,6 +324,20 @@ impl<'a> Clone for CellSlice<'a> {

impl<'a> Copy for CellSlice<'a> {}

impl<'a> AsRef<CellSlice<'a>> for CellSlice<'a> {
#[inline]
fn as_ref(&self) -> &CellSlice<'a> {
self
}
}

impl<'a> AsMut<CellSlice<'a>> for CellSlice<'a> {
#[inline]
fn as_mut(&mut self) -> &mut CellSlice<'a> {
self
}
}

impl<'a> CellSlice<'a> {
/// Constructs a new cell slice from the specified cell.
/// Returns an error if the cell is pruned.
Expand Down Expand Up @@ -1419,25 +1433,31 @@ impl<'a> CellSlice<'a> {

/// Returns an object which will display data as a bitstring
/// with a termination bit.
pub fn display_data<'b: 'a>(&'b self) -> impl std::fmt::Display + 'b {
pub fn display_data<'b: 'a>(&'b self) -> impl std::fmt::Display + std::fmt::Binary + 'b {
fn make_bitstring<'b: 'a, 'a>(
s: &'b CellSlice<'a>,
bytes: &'b mut [u8; 128],
) -> Result<Bitstring<'b>, std::fmt::Error> {
let bit_len = s.remaining_bits();
if s.get_raw(0, bytes, bit_len).is_err() {
return Err(std::fmt::Error);
}
Ok(Bitstring { bytes, bit_len })
}

struct DisplayData<'b, 'a>(&'b CellSlice<'a>);

impl<'b: 'a, 'a> std::fmt::Display for DisplayData<'b, 'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = self.0;
let bit_len = s.remaining_bits();
let mut bytes = [0u8; 128];
if s.get_raw(0, &mut bytes, bit_len).is_err() {
return Err(std::fmt::Error);
}
std::fmt::Display::fmt(&ok!(make_bitstring(self.0, &mut bytes)), f)
}
}

std::fmt::Display::fmt(
&Bitstring {
bytes: &bytes,
bit_len,
},
f,
)
impl<'b: 'a, 'a> std::fmt::Binary for DisplayData<'b, 'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut bytes = [0u8; 128];
std::fmt::Binary::fmt(&ok!(make_bitstring(self.0, &mut bytes)), f)
}
}

Expand Down
Loading

0 comments on commit 2b4896d

Please sign in to comment.