Skip to content

Commit

Permalink
feat: add support for types from ascii crate (#255)
Browse files Browse the repository at this point in the history
* Add support for types from ascii ccrate

* review

* review

* schema tests

* wip

* wip

* wip

* Update .github/test.sh

Co-authored-by: dj8yf0μl <26653921+dj8yfo@users.noreply.github.com>

* fix

* no_std

* fix

* unused

* test:  add missing assert

* chore: improve impl/test modularity

---------

Co-authored-by: dj8yf0μl <26653921+dj8yfo@users.noreply.github.com>
Co-authored-by: dj8yf0μl <feepdake27@gmail.com>
  • Loading branch information
3 people committed Nov 13, 2023
1 parent df8c3cf commit 2d4cf20
Show file tree
Hide file tree
Showing 13 changed files with 1,720 additions and 12 deletions.
4 changes: 3 additions & 1 deletion .github/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ export INSTA_UPDATE=no
pushd borsh
cargo test --no-run
cargo test
cargo test --features unstable__schema,ascii --test test_ascii_strings
cargo test --features derive
cargo test --features unstable__schema
cargo test --test test_rc --features rc
cargo test --test test_hash_map --test test_btree_map --features de_strict_order

cargo test --no-default-features
cargo test --no-default-features --features unstable__schema,ascii --test test_ascii_strings
cargo test --no-default-features --features derive
cargo test --no-default-features --features unstable__schema
cargo test --no-default-features --test test_rc --features rc
cargo test --no-default-features --features hashbrown
popd
pushd borsh-derive
cargo test --features schema
cargo test --features schema
3 changes: 2 additions & 1 deletion borsh/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ required-features = ["std", "unstable__schema"]
cfg_aliases = "0.1.0"

[dependencies]
ascii = { version = "1.1", optional = true }
borsh-derive = { path = "../borsh-derive", version = "~1.1.2", optional = true }

# hashbrown can be used in no-std context.
# NOTE: There is no reason to restrict use of older versions, but we don't want to get
# NOTE: There is no reason to restrict use of older versions, but we don't want to get
# sudden breaking changes with an open range of versions, so we limit the range by not yet released 0.15.0 version:
hashbrown = { version = ">=0.11,<0.15.0", optional = true }
bytes = { version = "1", optional = true }
Expand Down
29 changes: 29 additions & 0 deletions borsh/src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,35 @@ impl BorshDeserialize for String {
}
}

/// Module is available if borsh is built with `features = ["ascii"]`.
#[cfg(feature = "ascii")]
pub mod ascii {
//!
//! Module defines [BorshDeserialize] implementation for
//! some types from [ascii](::ascii) crate.
use crate::BorshDeserialize;
use crate::__private::maybestd::{string::ToString, vec::Vec};
use crate::io::{Error, ErrorKind, Read, Result};

impl BorshDeserialize for ascii::AsciiString {
#[inline]
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
let bytes = Vec::<u8>::deserialize_reader(reader)?;
ascii::AsciiString::from_ascii(bytes)
.map_err(|err| Error::new(ErrorKind::InvalidData, err.to_string()))
}
}

impl BorshDeserialize for ascii::AsciiChar {
#[inline]
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
let byte = u8::deserialize_reader(reader)?;
ascii::AsciiChar::from_ascii(byte)
.map_err(|err| Error::new(ErrorKind::InvalidData, err.to_string()))
}
}
}

impl<T> BorshDeserialize for Vec<T>
where
T: BorshDeserialize,
Expand Down
3 changes: 3 additions & 0 deletions borsh/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
* **bson** -
Gates implementation of [BorshSerialize] and [BorshDeserialize]
for [ObjectId](bson::oid::ObjectId).
* **ascii** -
Gates implementation of [BorshSerialize], [BorshDeserialize], [BorshSchema] for
types from [ascii](https://docs.rs/ascii/1.1.0/ascii/) crate.
* **de_strict_order** -
Enables check that keys, parsed during deserialization of
[HashMap](std::collections::HashMap)/[HashSet](std::collections::HashSet) and
Expand Down
52 changes: 52 additions & 0 deletions borsh/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ impl BorshSchema for String {
str::declaration()
}
}

impl BorshSchema for str {
#[inline]
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
Expand All @@ -401,6 +402,57 @@ impl BorshSchema for str {
}
}

/// Module is available if borsh is built with `features = ["ascii"]`.
#[cfg(feature = "ascii")]
pub mod ascii {
//!
//! Module defines [BorshSchema] implementation for
//! some types from [ascii](::ascii) crate.
use crate::BorshSchema;

use super::{add_definition, Declaration, Definition};
use crate::__private::maybestd::collections::BTreeMap;

impl BorshSchema for ascii::AsciiString {
#[inline]
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
ascii::AsciiStr::add_definitions_recursively(definitions);
}
#[inline]
fn declaration() -> Declaration {
ascii::AsciiStr::declaration()
}
}

impl BorshSchema for ascii::AsciiStr {
#[inline]
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
let definition = Definition::Sequence {
length_width: Definition::DEFAULT_LENGTH_WIDTH,
length_range: Definition::DEFAULT_LENGTH_RANGE,
elements: ascii::AsciiChar::declaration(),
};
add_definition(Self::declaration(), definition, definitions);
ascii::AsciiChar::add_definitions_recursively(definitions);
}
#[inline]
fn declaration() -> Declaration {
"AsciiString".into()
}
}

impl BorshSchema for ascii::AsciiChar {
#[inline]
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
add_definition(Self::declaration(), Definition::Primitive(1), definitions);
}
#[inline]
fn declaration() -> Declaration {
"AsciiChar".into()
}
}
}

impl BorshSchema for core::ops::RangeFull {
#[inline]
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
Expand Down
31 changes: 31 additions & 0 deletions borsh/src/ser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,37 @@ impl BorshSerialize for String {
}
}

/// Module is available if borsh is built with `features = ["ascii"]`.
#[cfg(feature = "ascii")]
pub mod ascii {
//!
//! Module defines [BorshSerialize] implementation for
//! some types from [ascii](::ascii) crate.
use super::BorshSerialize;
use crate::io::{Result, Write};

impl BorshSerialize for ascii::AsciiChar {
#[inline]
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
self.as_byte().serialize(writer)
}
}

impl BorshSerialize for ascii::AsciiStr {
#[inline]
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
self.as_bytes().serialize(writer)
}
}

impl BorshSerialize for ascii::AsciiString {
#[inline]
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
self.as_bytes().serialize(writer)
}
}
}

/// Helper method that is used to serialize a slice of data (without the length marker).
#[inline]
fn serialize_slice<T: BorshSerialize, W: Write>(data: &[T], writer: &mut W) -> Result<()> {
Expand Down
11 changes: 11 additions & 0 deletions borsh/tests/snapshots/test_ascii_strings__a.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: borsh/tests/test_ascii_strings.rs
expression: buf
---
[
1,
0,
0,
0,
97,
]
10 changes: 10 additions & 0 deletions borsh/tests/snapshots/test_ascii_strings__empty_string.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
source: borsh/tests/test_ascii_strings.rs
expression: buf
---
[
0,
0,
0,
0,
]
Loading

0 comments on commit 2d4cf20

Please sign in to comment.