Last active
June 26, 2023 10:33
-
-
Save dj8yfo/da468206a03feca6d08698cbfc868ea0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![cfg_attr(not(feature = "std"), no_std)] | |
#[cfg(feature = "std")] | |
use std::collections::{btree_map::Entry, BTreeMap}; | |
#[cfg(not(feature = "std"))] | |
extern crate alloc; | |
#[cfg(not(feature = "std"))] | |
use alloc::{ | |
boxed::Box, | |
collections::{btree_map::Entry, BTreeMap}, | |
format, | |
string::ToString, | |
vec, | |
}; | |
use inner::{Declaration, Definition, Fields}; | |
pub mod inner; | |
pub trait BorshSchema { | |
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>); | |
fn add_definition( | |
declaration: Declaration, | |
definition: Definition, | |
definitions: &mut BTreeMap<Declaration, Definition>, | |
) { | |
match definitions.entry(declaration) { | |
Entry::Occupied(occ) => { | |
let existing_def = occ.get(); | |
assert_eq!(existing_def, &definition, "Redefining type schema for the same type name. Types with the same names are not supported."); | |
} | |
Entry::Vacant(vac) => { | |
vac.insert(definition); | |
} | |
} | |
} | |
fn declaration() -> Declaration; | |
fn schema_container() -> BorshSchemaContainer { | |
let mut definitions = BTreeMap::new(); | |
Self::add_definitions_recursively(&mut definitions); | |
BorshSchemaContainer::new(Self::declaration(), definitions) | |
} | |
} | |
// https://github.com/dj8yfo/borsh-rs/blob/tmp_link_container_guarantee/borsh/tests/test_schema_enums.rs#L164 | |
#[cfg(feature = "std")] | |
pub mod container_serialization_guarantee { | |
use std::collections::BTreeMap; | |
use std::io::{Read, Write}; | |
use crate::inner::{Declaration, Definition}; | |
use crate::BorshSchemaContainer; | |
pub trait BorshSerialize { | |
fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()>; | |
} | |
pub trait BorshDeserialize: Sized { | |
fn deserialize_reader<R: Read>(reader: &mut R) -> std::io::Result<Self>; | |
} | |
impl BorshSerialize for Declaration { | |
fn serialize<W: Write>(&self, _writer: &mut W) -> std::io::Result<()> { | |
todo!("done already"); | |
} | |
} | |
impl BorshSerialize for Definition { | |
fn serialize<W: Write>(&self, _writer: &mut W) -> std::io::Result<()> { | |
todo!("done already"); | |
} | |
} | |
impl<K, V> BorshSerialize for BTreeMap<K, V> | |
where | |
K: BorshSerialize, | |
V: BorshSerialize, | |
{ | |
fn serialize<W: Write>(&self, _writer: &mut W) -> std::io::Result<()> { | |
todo!("done already"); | |
} | |
} | |
impl BorshDeserialize for Declaration { | |
fn deserialize_reader<R: Read>(_reader: &mut R) -> std::io::Result<Self> { | |
todo!("done already"); | |
} | |
} | |
impl BorshDeserialize for Definition { | |
fn deserialize_reader<R: Read>(_reader: &mut R) -> std::io::Result<Self> { | |
todo!("done already"); | |
} | |
} | |
impl<K, V> BorshDeserialize for BTreeMap<K, V> | |
where | |
K: BorshDeserialize + Ord + core::hash::Hash, | |
V: BorshDeserialize, | |
{ | |
fn deserialize_reader<R: Read>(_reader: &mut R) -> std::io::Result<Self> { | |
todo!("done already"); | |
} | |
} | |
impl BorshSerialize for BorshSchemaContainer | |
where | |
Declaration: BorshSerialize, | |
BTreeMap<Declaration, Definition>: BorshSerialize, | |
{ | |
fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> { | |
let declaration = self.declaration(); | |
let definitions: BTreeMap<Declaration, Definition> = self | |
.definitions() | |
.map(|(k, v)| (k.clone(), v.clone())) | |
.collect(); | |
BorshSerialize::serialize(declaration, writer)?; | |
BorshSerialize::serialize(&definitions, writer)?; | |
Ok(()) | |
} | |
} | |
impl BorshDeserialize for BorshSchemaContainer | |
where | |
Declaration: BorshDeserialize, | |
BTreeMap<Declaration, Definition>: BorshDeserialize, | |
{ | |
fn deserialize_reader<R: Read>(reader: &mut R) -> std::io::Result<Self> { | |
let declaration: Declaration = BorshDeserialize::deserialize_reader(reader)?; | |
let definitions: BTreeMap<Declaration, Definition> = | |
BorshDeserialize::deserialize_reader(reader)?; | |
Ok(Self::new(declaration, definitions)) | |
} | |
} | |
} | |
#[derive(Clone, PartialEq, Eq, Debug)] | |
pub struct BorshSchemaContainer { | |
declaration: Declaration, | |
definitions: BTreeMap<Declaration, Definition>, | |
} | |
impl BorshSchemaContainer { | |
pub fn new(declaration: Declaration, definitions: BTreeMap<Declaration, Definition>) -> Self { | |
Self { | |
declaration, | |
definitions, | |
} | |
} | |
pub fn declaration(&self) -> &Declaration { | |
&self.declaration | |
} | |
pub fn definitions<'_self>( | |
&'_self self, | |
) -> impl Iterator<Item = (&'_self Declaration, &'_self Definition)> { | |
self.definitions.iter() | |
} | |
pub fn get_def(&self, declaration: &Declaration) -> Option<&Definition> { | |
self.definitions.get(declaration) | |
} | |
pub fn get_mut_def(&mut self, declaration: &Declaration) -> Option<&mut Definition> { | |
self.definitions.get_mut(declaration) | |
} | |
pub fn insert_def( | |
&mut self, | |
declaration: Declaration, | |
definition: Definition, | |
) -> Option<Definition> { | |
self.definitions.insert(declaration, definition) | |
} | |
pub fn remove_def(&mut self, declaration: &Declaration) -> Option<Definition> { | |
self.definitions.remove(declaration) | |
} | |
} | |
impl BorshSchema for Declaration { | |
fn add_definitions_recursively(_definitions: &mut BTreeMap<Declaration, Definition>) { | |
todo!("done"); | |
} | |
fn add_definition( | |
_declaration: Declaration, | |
_definition: Definition, | |
_definitions: &mut BTreeMap<Declaration, Definition>, | |
) { | |
todo!("done"); | |
} | |
fn declaration() -> Declaration { | |
todo!("done"); | |
} | |
fn schema_container() -> crate::BorshSchemaContainer { | |
todo!("done"); | |
} | |
} | |
impl BorshSchema for Fields { | |
fn add_definitions_recursively(_definitions: &mut BTreeMap<Declaration, Definition>) { | |
todo!("done"); | |
} | |
fn add_definition( | |
_declaration: Declaration, | |
_definition: Definition, | |
_definitions: &mut BTreeMap<Declaration, Definition>, | |
) { | |
todo!("done"); | |
} | |
fn declaration() -> Declaration { | |
todo!("done"); | |
} | |
fn schema_container() -> crate::BorshSchemaContainer { | |
todo!("done"); | |
} | |
} | |
impl BorshSchema for Definition { | |
fn add_definitions_recursively(_definitions: &mut BTreeMap<Declaration, Definition>) { | |
todo!("done"); | |
} | |
fn add_definition( | |
_declaration: Declaration, | |
_definition: Definition, | |
_definitions: &mut BTreeMap<Declaration, Definition>, | |
) { | |
todo!("done"); | |
} | |
fn declaration() -> Declaration { | |
todo!("done"); | |
} | |
fn schema_container() -> crate::BorshSchemaContainer { | |
todo!("done"); | |
} | |
} | |
macro_rules! impl_tuple { | |
($($name:ident),+) => { | |
impl<$($name),+> BorshSchema for ($($name,)+) | |
where | |
$($name: BorshSchema),+ | |
{ | |
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) { | |
let elements = vec![$($name::declaration()),+]; | |
let definition = Definition::Tuple { elements }; | |
Self::add_definition(Self::declaration(), definition, definitions); | |
$( | |
$name::add_definitions_recursively(definitions); | |
)+ | |
} | |
fn declaration() -> Declaration { | |
let params = vec![$($name::declaration()),+]; | |
format!(r#"Tuple<{}>"#, params.join(", ")) | |
} | |
} | |
}; | |
} | |
impl_tuple!(T0, T1); | |
impl<K, V> BorshSchema for BTreeMap<K, V> | |
where | |
K: BorshSchema, | |
V: BorshSchema, | |
{ | |
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) { | |
let definition = Definition::Sequence { | |
elements: <(K, V)>::declaration(), | |
}; | |
Self::add_definition(Self::declaration(), definition, definitions); | |
<(K, V)>::add_definitions_recursively(definitions); | |
} | |
fn declaration() -> Declaration { | |
format!(r#"BTreeMap<{}, {}>"#, K::declaration(), V::declaration()) | |
} | |
} | |
impl BorshSchema for BorshSchemaContainer | |
where | |
Declaration: BorshSchema, | |
BTreeMap<Declaration, Definition>: BorshSchema, | |
{ | |
fn declaration() -> Declaration { | |
"BorshSchemaContainer".to_string() | |
} | |
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) { | |
let fields = Fields::NamedFields(<[_]>::into_vec(Box::new([ | |
( | |
"declaration".to_string(), | |
<Declaration as BorshSchema>::declaration(), | |
), | |
( | |
"definitions".to_string(), | |
<BTreeMap<Declaration, Definition> as BorshSchema>::declaration(), | |
), | |
]))); | |
let definition = Definition::Struct { fields }; | |
Self::add_definition( | |
<Self as BorshSchema>::declaration(), | |
definition, | |
definitions, | |
); | |
<Declaration as BorshSchema>::add_definitions_recursively(definitions); | |
<BTreeMap<Declaration, Definition> as BorshSchema>::add_definitions_recursively( | |
definitions, | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
there's slight distinction,
<Self as BorshSchema>::declaration()
andSelf::declaration(&self)