Closed dj8yfo closed 1 month ago
similarly
#[derive(BorshSchema)]
enum A {
Bacon(Vec<i64>),
Eggs,
}
from schema_full_path_crate results in
{
"Vec<i64>": Sequence {
length_width: 4,
length_range: 0..=4294967295,
elements: "i64",
},
"i64": Primitive(
8,
),
"schema_full_path_crate::A": Enum {
tag_width: 1,
variants: [
(
0,
"Bacon",
"schema_full_path_crate::___ABacon",
),
(
1,
"Eggs",
"schema_full_path_crate::___AEggs",
),
],
},
"schema_full_path_crate::___ABacon": Struct {
fields: UnnamedFields(
[
"Vec<i64>",
],
),
},
"schema_full_path_crate::___AEggs": Struct {
fields: Empty,
},
}
and then,
use schema_full_path_crate::A as AForeign;
#[derive(BorshSchema)]
struct B {
x: A,
y: AForeign,
}
from sample_schema_two_crates results in
BorshSchemaContainer {
declaration: "sample_schema_two_crates::B",
definitions: {
"Vec<i64>": Sequence {
length_width: 4,
length_range: 0..=4294967295,
elements: "i64",
},
"i64": Primitive(
8,
),
"sample_schema_two_crates::A": Enum {
tag_width: 1,
variants: [
(
0,
"UnitVariant",
"sample_schema_two_crates::___AUnitVariant",
),
],
},
"sample_schema_two_crates::B": Struct {
fields: NamedFields(
[
(
"x",
"sample_schema_two_crates::A",
),
(
"y",
"schema_full_path_crate::A",
),
],
),
},
"sample_schema_two_crates::___AUnitVariant": Struct {
fields: Empty,
},
"schema_full_path_crate::A": Enum {
tag_width: 1,
variants: [
(
0,
"Bacon",
"schema_full_path_crate::___ABacon",
),
(
1,
"Eggs",
"schema_full_path_crate::___AEggs",
),
],
},
"schema_full_path_crate::___ABacon": Struct {
fields: UnnamedFields(
[
"Vec<i64>",
],
),
},
"schema_full_path_crate::___AEggs": Struct {
fields: Empty,
},
},
}
Seems only this solution will work with 3rd party crates. In my crate I have solutions to rename or use type alias, so not a problem.
Question,
what would be in case of reexport of exactly same data structure by two crates? Two separate declaration with same definitions I assume? What would be with when I use std::Vec
and alloc::Vec
for example?
Should be schema Rust based expression(syn parseable alike?) or readable by more people(TS?) ? Proposed naming for variants is schema_full_path_crate::___ABacon
, but should it be just schema_full_path_crate::A::Bacon
? Assuming mod name is not allowed to conflict to variant name in Rust.
@dzmitry-lahoda
Two separate declaration with same definitions I assume?
Yes. But if the types use semantically identical types from their respective crates as their fields, then they will technically have different definitions as well, because they will be comprised of similar types but with different Declarations, due to crate+mod prefix.
Should be schema Rust based expression(syn parseable alike?) or readable by more people(TS?) ?
The triple underscore prefix (___
) for enum helper structs can be removed to improve readability, as 1. it leaks implementation details outside, 2. it's not that big of a problem to arrange to avoid conflicts in a single module.
But then, crate+mod prefix leaks implementation detail outside as well, so this pr most likely won't be merged.
when I use
std::vec::Vec
andalloc::vec::Vec
for example?
It's the same type
@dzmitry-lahoda , also, conflict detection of names as of now cannot be made perfect, at least because recursive types were allowed, so someone can accidentally or in an intentfull way replace or "shadow" someone else's declaration, if many crates are involved and very complex schemas are constructed. Automatically adding crate+mod prefix can help with accidental cases, but can do little in cases if it's done purposefully. It should be the same for identical source code versions, so at least that's a great relief.
sketch of possible solution to #92, both the original issue and the widened perspective
this results in
=>
this may have very weak interoperability with borsh-js due to being specific to rust