Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.0.0 release #2

Merged
merged 7 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Rust

on:
push:
branches: [ "main" ]
branches: [ "main", "dev" ]
pull_request:
branches: [ "main" ]

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
resolver = "2"

members = [
"borsh-serde-adapter",
Expand Down
7 changes: 4 additions & 3 deletions borsh-schema-writer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "borsh-schema-writer"
version = "0.1.0"
version = "1.0.0"
edition = "2021"
authors = ["Will Kennedy"]
description = "Write a BorshSchemaContainer to a binary file"
Expand All @@ -12,8 +12,9 @@ categories = ["parsing"]
exclude=["/tests", "/examples", "/benches", "/docs", "/target", "/.github", "/.gitignore", "/.gitattributes", "/.gitmodules", "/.travis.yml", "/.cargo-ok", "/.git", "/.idea"]

[dependencies]
borsh = ">= 0.9.3, <= 0.10.3"
borsh-derive = ">= 0.9.3, <= 0.10.3"
borsh = { version = "1.1.1", features = ["std", "unstable__schema"] }
borsh-derive = "1.1.1"


[lib]
doctest = false
12 changes: 5 additions & 7 deletions borsh-schema-writer/src/schema_writer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fs::File;
use std::io::Write;
use borsh::{BorshSchema, BorshSerialize};
use borsh::{BorshSchema, to_vec};
use borsh::schema::BorshSchemaContainer;

/// This function takes a Struct with the BorshSchema trait and writes the schema to a specified file.
Expand All @@ -16,9 +16,8 @@ use borsh::schema::BorshSchemaContainer;
pub fn write_schema<T: BorshSchema>(_: T, file_path: String) -> std::io::Result<()> {
let mut defs = Default::default();
T::add_definitions_recursively(&mut defs);
let container: BorshSchemaContainer = T::schema_container();
let data = container
.try_to_vec()
let container: BorshSchemaContainer = BorshSchemaContainer::for_type::<T>();
let data = to_vec(&container)
.expect("Failed to serialize BorshSchemaContainer");
let mut file = File::create(file_path).expect("Failed to create borsh schema file");
file.write_all(&data).expect("Failed to write file");
Expand All @@ -36,9 +35,8 @@ pub fn write_schema<T: BorshSchema>(_: T, file_path: String) -> std::io::Result<
pub fn schema_to_bytes<T: BorshSchema>(_: T) -> std::io::Result<Vec<u8>> {
let mut defs = Default::default();
T::add_definitions_recursively(&mut defs);
let container: BorshSchemaContainer = T::schema_container();
let data = container
.try_to_vec()
let container: BorshSchemaContainer = BorshSchemaContainer::for_type::<T>();
let data = to_vec(&container)
.expect("Failed to serialize BorshSchemaContainer");
Ok(data)
}
12 changes: 6 additions & 6 deletions borsh-schema-writer/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ fn write_schema_test() {
let mut reader = BufReader::new(file);
let container_from_file = BorshSchemaContainer::deserialize_reader(&mut reader).expect("Deserialization for BorshSchemaContainer failed");

assert_eq!(container_from_file.declaration.to_string(), "Person");
let definition = container_from_file.definitions.get(container_from_file.declaration.as_str()).unwrap();
assert_eq!(container_from_file.declaration().to_string(), "Person");
let definition = container_from_file.get_definition(container_from_file.declaration().as_str()).unwrap();
assert!(matches!(definition, Definition::Struct { .. }));

match definition {
Definition::Struct { fields } => match fields {
Fields::NamedFields(fields) => {
for (key, value_declaration) in fields {
assert!(key.as_str() == "first_name" || key.as_str() == "last_name");
assert!(value_declaration.as_str() == "string");
assert_eq!(value_declaration.as_str(), "String");
}
}
_ => {assert!(false)}
Expand All @@ -42,16 +42,16 @@ fn write_to_bytes_test() {

let container_from_bytes = BorshSchemaContainer::deserialize(&mut schema.as_slice()).expect("Deserialization for BorshSchemaContainer failed");

assert_eq!(container_from_bytes.declaration.to_string(), "Person");
let definition = container_from_bytes.definitions.get(container_from_bytes.declaration.as_str()).unwrap();
assert_eq!(container_from_bytes.declaration().to_string(), "Person");
let definition = container_from_bytes.get_definition(container_from_bytes.declaration().as_str()).unwrap();
assert!(matches!(definition, Definition::Struct { .. }));

match definition {
Definition::Struct { fields } => match fields {
Fields::NamedFields(fields) => {
for (key, value_declaration) in fields {
assert!(key.as_str() == "first_name" || key.as_str() == "last_name");
assert!(value_declaration.as_str() == "string");
assert_eq!(value_declaration.as_str(), "String");
}
}
_ => {assert!(false)}
Expand Down
Binary file modified borsh-schema-writer/tests/schema/person_schema.dat
Binary file not shown.
18 changes: 9 additions & 9 deletions borsh-serde-adapter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "borsh-serde-adapter"
version = "0.1.0"
version = "1.0.0"
edition = "2021"
authors = ["Will Kennedy"]
description = "Adapter to go from borsh to serde and vice versa"
Expand All @@ -12,15 +12,15 @@ categories = ["parsing"]
exclude=["/tests", "/examples", "/benches", "/docs", "/target", "/.github", "/.gitignore", "/.gitattributes", "/.gitmodules", "/.travis.yml", "/.cargo-ok", "/.git", "/.idea"]

[dependencies]
log = "0.4.19"
serde = { version = "1.0.171", features = ["derive"] }
serde_derive = "1.0.180"
serde_json = "1.0.104"
anyhow = "1.0.72"
log = "0.4.20"
serde = { version = "1.0.190", features = ["derive"] }
serde_derive = "1.0.190"
serde_json = "1.0.108"
anyhow = "1.0.75"
simdutf8 = { version = "0.1.4", optional = true }
borsh = ">= 0.9.3, <= 0.10.3"
borsh-derive = ">= 0.9.3, <= 0.10.3"
thiserror = "1.0.44"
borsh = { version = "1.1.1", features = ["unstable__schema", "std"] }
borsh-derive = "1.1.1"
thiserror = "1.0.50"

[lib]
doctest = false
10 changes: 4 additions & 6 deletions borsh-serde-adapter/src/borsh_schema_util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fs::File;
use std::io::{Write};
use borsh::{BorshSchema, BorshSerialize};
use borsh::{BorshSchema, schema_container_of, to_vec};
use borsh::schema::BorshSchemaContainer;
use crate::deserialize_adapter::deserialize_from_schema;

Expand All @@ -9,14 +9,12 @@ use crate::deserialize_adapter::deserialize_from_schema;
pub fn write_schema_as_json<T: BorshSchema>(_: T, file_path: String) -> std::io::Result<()> {
let mut defs = Default::default();
T::add_definitions_recursively(&mut defs);
let container: BorshSchemaContainer = T::schema_container();
let data = container
.try_to_vec()
.expect("Failed to serialize BorshSchemaContainer");
let container: BorshSchemaContainer = BorshSchemaContainer::for_type::<T>();
let data = to_vec(&container).expect("Failed to serialize BorshSchemaContainer");

let mut con_defs = Default::default();
BorshSchemaContainer::add_definitions_recursively(&mut con_defs);
let con_container: BorshSchemaContainer = BorshSchemaContainer::schema_container();
let con_container: BorshSchemaContainer = schema_container_of::<BorshSchemaContainer>();

let result = deserialize_from_schema(&mut data.as_slice(), &con_container).expect("Deserialization failed");

Expand Down
33 changes: 18 additions & 15 deletions borsh-serde-adapter/src/deserialize_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,27 @@ fn deserialize_to_serde_json(buffer: &mut &[u8], schema: &BorshSchemaContainer,
.map_err(|_| Error::new(std::io::ErrorKind::InvalidData, "i128")),
"f32" => deserialize_to_serde_json_by_type::<f32>(buffer, "f32"),
"f64" => deserialize_to_serde_json_by_type::<f64>(buffer, "f64"),
"string" => deserialize_to_serde_json_by_type::<String>(buffer, "string"),
"String" => deserialize_to_serde_json_by_type::<String>(buffer, "String"),
"bool" => deserialize_to_serde_json_by_type::<bool>(buffer, "bool"),

_ => {
if let Some(d) = schema.definitions.get(declaration) {
if let Some(d) = schema.get_definition(declaration) {
match d {
Definition::Array { length, ref elements, } => {
let mut values = Vec::<serde_json::Value>::with_capacity(*length as usize);
for _ in 0..*length {
let value = deserialize_to_serde_json(buffer, schema, elements)?;
values.push(value);
}
Ok(values.into())
Definition::Primitive { .. } => {
let value = deserialize_to_serde_json(buffer, schema, declaration)?;

Ok(value)
}

Definition::Sequence { elements } => {
let length = u32::deserialize(buffer)?;
let mut values = Vec::<serde_json::Value>::with_capacity(length as usize);
Definition::Sequence { length_width, length_range, elements } => {
let length_width = *length_width as u32;
let length = if length_width == 0 {
*length_range.end() as usize
} else {
u32::deserialize(buffer)? as usize
};

let mut values = Vec::<serde_json::Value>::with_capacity(length);
for _ in 0..length {
let value = deserialize_to_serde_json(buffer, schema, elements)?;
values.push(value);
Expand All @@ -66,9 +69,9 @@ fn deserialize_to_serde_json(buffer: &mut &[u8], schema: &BorshSchemaContainer,
Ok(values.into())
}

Definition::Enum { variants } => {
Definition::Enum { tag_width: _, variants } => {
let variant_index = u8::deserialize(buffer)?;
let (variant_name, variant_declaration) = &variants[variant_index as usize];
let (_dicriminator_value, variant_name, variant_declaration) = &variants[variant_index as usize];
deserialize_to_serde_json(buffer, schema, variant_declaration)
.map(|value| json!({ variant_name: value }))
}
Expand Down Expand Up @@ -109,5 +112,5 @@ fn deserialize_to_serde_json(buffer: &mut &[u8], schema: &BorshSchemaContainer,

/// Deserializes borsh serialized bytes to serde_json::Value using the provided schema
pub fn deserialize_from_schema(buffer: &mut &[u8], schema: &BorshSchemaContainer) -> std::io::Result<serde_json::Value> {
deserialize_to_serde_json(buffer, schema, &schema.declaration)
deserialize_to_serde_json(buffer, schema, schema.declaration())
}
2 changes: 1 addition & 1 deletion borsh-serde-adapter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
//! This library is still in early development and there are some caveats to be aware of. The use of u128 and i128 are
//! somewhat supported. In the case of deserialization u128/i128 are deserialized as strings, but serialization is not
//! supported.

pub mod deserialize_adapter;
pub mod serialize_adapter;
pub mod errors;
Expand Down
38 changes: 17 additions & 21 deletions borsh-serde-adapter/src/serialize_adapter.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(clippy::unnecessary_find_map)]

use std::io::{Write};
use std::str::FromStr;

Expand All @@ -10,7 +12,7 @@ use crate::errors::ExpectationError;

/// Serializes serde_json::Value to borsh serialized bytes using the provided schema
pub fn serialize_serde_json_to_borsh(writer: &mut impl Write, value: &serde_json::Value, schema: &BorshSchemaContainer) -> anyhow::Result<()> {
serialize_serde_json_by_declaration_with_schema(writer, value, schema, &schema.declaration)
serialize_serde_json_by_declaration_with_schema(writer, value, schema, schema.declaration())
}

fn serialize_signed_to_borsh<T: BorshSerialize + TryFrom<i64>>(writer: &mut impl Write, value: &serde_json::Value) -> anyhow::Result<()>
Expand Down Expand Up @@ -71,30 +73,28 @@ fn serialize_serde_json_by_declaration_with_schema(
BorshSerialize::serialize(&value, writer)?;
Ok(())
},
"string" => serialize_serde_json_to_borsh_by_type::<String>(writer, value),
"String" => serialize_serde_json_to_borsh_by_type::<String>(writer, value),
"bool" => {
let value = value.as_bool().ok_or(ExpectationError::Boolean)?;
BorshSerialize::serialize(&value, writer)?;
Ok(())
}
_ => {
if let Some(definition) = schema.definitions.get(declaration) {
if let Some(definition) = schema.get_definition(declaration) {
match definition {

Definition::Array { length, elements } => {
let array = value.as_array().ok_or(ExpectationError::Array)?;
if array.len() != *length as usize {
return Err(ExpectationError::ArrayOfLength(*length).into());
}
for value in array {
serialize_serde_json_by_declaration_with_schema(writer, value, schema, elements)?;
}
Definition::Primitive { .. } => {
serialize_serde_json_by_declaration_with_schema(writer, value, schema, declaration)?;
Ok(())
}

Definition::Sequence { elements } => {
Definition::Sequence { length_width, length_range: _, elements } => {
let sequence = value.as_array().ok_or(ExpectationError::Array)?;
BorshSerialize::serialize(&(sequence.len() as u32), writer)?;
let length_width = *length_width as u32;
if length_width != 0 {
let length = sequence.len();
BorshSerialize::serialize(&(length as u32), writer)?;
};
for item in sequence {
serialize_serde_json_by_declaration_with_schema(writer, item, schema, elements)?;
}
Expand All @@ -114,7 +114,7 @@ fn serialize_serde_json_by_declaration_with_schema(
Ok(())
}

Definition::Enum { variants } => {
Definition::Enum { variants, .. } => {
let (input_variant, variant_values) = value
.as_object()
.and_then(|o| o.keys().next().map(|s| (s.as_str(), Some(&o[s]))))
Expand All @@ -124,12 +124,8 @@ fn serialize_serde_json_by_declaration_with_schema(
let (variant_index, variant_declaration) = variants
.iter()
.enumerate()
.find_map(|(i, (k, v))| {
if k == input_variant {
Some((i, v))
} else {
None
}
.find_map(|(i, (.., v))| {
Some((i, v))
})
.ok_or_else(|| {
anyhow!(
Expand All @@ -152,7 +148,7 @@ fn serialize_serde_json_by_declaration_with_schema(
let object = value.as_object().ok_or(ExpectationError::Object)?;
for (key, value_declaration) in fields {
let property_value = object
.get(key)
.get(key.as_str())
.ok_or_else(|| anyhow!("Expected property {key}"))?;
serialize_serde_json_by_declaration_with_schema(
writer,
Expand Down
Loading
Loading