Skip to content

Commit ff34f73

Browse files
authored
feat: relax schema_container_of target requirement with ?Sized to allow slices (#245)
1 parent 4ef9d00 commit ff34f73

File tree

3 files changed

+74
-4
lines changed

3 files changed

+74
-4
lines changed

borsh/src/schema.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ impl BorshSchemaContainer {
169169
}
170170

171171
/// generate [BorshSchemaContainer] for type `T`
172-
pub fn for_type<T: BorshSchema>() -> Self {
172+
pub fn for_type<T: BorshSchema + ?Sized>() -> Self {
173173
let mut definitions = Default::default();
174174
T::add_definitions_recursively(&mut definitions);
175175
Self::new(T::declaration(), definitions)

borsh/src/schema_helpers.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ pub fn try_from_slice_with_schema<T: BorshDeserialize + BorshSchema>(v: &[u8]) -
2020

2121
/// Serialize object into a vector of bytes and prefix with the schema serialized as vector of
2222
/// bytes in Borsh format.
23-
pub fn try_to_vec_with_schema<T: BorshSerialize + BorshSchema>(value: &T) -> Result<Vec<u8>> {
23+
pub fn try_to_vec_with_schema<T: BorshSerialize + BorshSchema + ?Sized>(
24+
value: &T,
25+
) -> Result<Vec<u8>> {
2426
let schema = schema_container_of::<T>();
2527
let mut res = crate::to_vec(&schema)?;
2628
value.serialize(&mut res)?;
@@ -30,7 +32,7 @@ pub fn try_to_vec_with_schema<T: BorshSerialize + BorshSchema>(value: &T) -> Res
3032
/// generate [BorshSchemaContainer] for type `T`
3133
///
3234
/// this is an alias of [BorshSchemaContainer::for_type]
33-
pub fn schema_container_of<T: BorshSchema>() -> BorshSchemaContainer {
35+
pub fn schema_container_of<T: BorshSchema + ?Sized>() -> BorshSchemaContainer {
3436
BorshSchemaContainer::for_type::<T>()
3537
}
3638

@@ -44,7 +46,7 @@ pub fn schema_container_of<T: BorshSchema>() -> BorshSchemaContainer {
4446
///
4547
/// assert_eq!(Ok(8), borsh::max_serialized_size::<usize>());
4648
/// ```
47-
pub fn max_serialized_size<T: BorshSchema>(
49+
pub fn max_serialized_size<T: BorshSchema + ?Sized>(
4850
) -> core::result::Result<usize, SchemaMaxSerializedSizeError> {
4951
let schema = BorshSchemaContainer::for_type::<T>();
5052
schema.max_serialized_size()

borsh/tests/test_schema_vec.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#![cfg_attr(not(feature = "std"), no_std)]
2+
#![cfg(hash_collections)]
3+
#![cfg(feature = "unstable__schema")]
4+
5+
#[cfg(feature = "std")]
6+
use std::collections::BTreeMap;
7+
8+
#[cfg(not(feature = "std"))]
9+
extern crate alloc;
10+
#[cfg(not(feature = "std"))]
11+
use alloc::{collections::BTreeMap, string::ToString};
12+
13+
use borsh::{schema::*, schema_container_of};
14+
15+
macro_rules! map(
16+
() => { BTreeMap::new() };
17+
{ $($key:expr => $value:expr),+ } => {
18+
{
19+
let mut m = BTreeMap::new();
20+
$(
21+
m.insert($key.to_string(), $value);
22+
)+
23+
m
24+
}
25+
};
26+
);
27+
28+
#[test]
29+
fn slice_schema_container() {
30+
let schema = schema_container_of::<[i64]>();
31+
32+
assert_eq!(
33+
schema,
34+
BorshSchemaContainer::new(
35+
"Vec<i64>".to_string(),
36+
map! {
37+
"Vec<i64>" => Definition::Sequence {
38+
length_width: Definition::DEFAULT_LENGTH_WIDTH,
39+
length_range: Definition::DEFAULT_LENGTH_RANGE,
40+
elements: "i64".to_string(),
41+
},
42+
"i64" => Definition::Primitive(8)
43+
44+
}
45+
)
46+
)
47+
}
48+
49+
#[test]
50+
fn vec_schema_container() {
51+
let schema = schema_container_of::<Vec<i64>>();
52+
53+
assert_eq!(
54+
schema,
55+
BorshSchemaContainer::new(
56+
"Vec<i64>".to_string(),
57+
map! {
58+
"Vec<i64>" => Definition::Sequence {
59+
length_width: Definition::DEFAULT_LENGTH_WIDTH,
60+
length_range: Definition::DEFAULT_LENGTH_RANGE,
61+
elements: "i64".to_string(),
62+
},
63+
"i64" => Definition::Primitive(8)
64+
65+
}
66+
)
67+
)
68+
}

0 commit comments

Comments
 (0)