-
Notifications
You must be signed in to change notification settings - Fork 251
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
impl NearSchema derive macro #891
Conversation
One question though. Do we want to proxy attr macros like |
Hmm, does this mean that all inner values have to implement both |
schemars actually respects many |
using a derive macro, unfortunately yes. Best we can do is leave |
Maybe we could derive JsonSchema by default and add something like this for borsh? #[derive(NearAbi)]
#[abi(borsh)] // makes NearAbi derive `BorshSchema` instead of `JsonSchema`
struct Value {
field: InnerValue
} Does not seem like there is a great solution for this either way. |
I agree with Daniyar, both should not be expected. Would require all inner types to have both implemented. Unclear if it would be better to have one derive with attributes or just two different derives. My intuition is that the latter seems more natural, but that is very weakly held. The issue with your example, Daniyar, is that it limits the ability to derive both types. Yes, a very niche use case, but might be a bit of a footgun |
I actually think this might be possible, tested a small example, and it seems to work. Here's the syntax I'm working with: #[derive(NearAbi)]
#[abi(json, borsh)]
struct Value {
field: InnerValue
} And omitting the attribute entirely defaults to I'll go ahead to implement this, I'll report here if I hit any blockers. An alternative to the attribute syntax might be (if you prefer being explicit):#[derive(NearAbi)]
#[abi(schema = "json")]
#[abi(schema = "borsh")]
struct Value {
field: InnerValue
} |
Done. So, I went with the first syntax. #[derive(NearAbi)]
#[abi(json, borsh)]
struct Value {
field: InnerValue
}
This already proxies In the meantime, let me know what you think. |
Also would be cool to add some use cases of this macro to |
near-sdk-macros/src/lib.rs
Outdated
TokenStream::from(quote! { | ||
#[cfg(not(target_arch = "wasm32"))] | ||
const _: () = { | ||
mod __near_abi_private { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does putting this in a mod do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NearSchema
's expansion effectively adds derives to a clone of the structure.
#[derive(NearSchema)]
struct Value {
field: InnerValue
}
expands into
struct Value {
field: InnerValue
}
const _: () = {
mod __near_abi_private {
#[derive(schemars::JsonSchema)]
struct Value {
field: InnerValue
}
impl schemars::JsonSchema for super::Value { ... }
// ^^^^^
// disambiguates the cloned structure from the original one
}
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, I see, so you want to avoid the type name being something different from the original for the purposes of schemars, which uses the type name or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, borsh also uses the type name. Honestly, it's mostly because of Borsh. Depending on the structure, borsh uses the name quite extensively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bump on this. super::*
requires the type to exist in a module. And would fail in this case.
mod x {
fn a() {
#[derive(NearSchema)]
pub struct MyType;
}
}
super::MyType
from the injected __near_abi_private
module would reference x::MyType
, which is nonexistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved to expanding to this instead:
struct Value {
field: InnerValue
}
const _: () = {
type Value__NEAR_SCHEMA_PROXY = Value;
{
#[derive(schemars::JsonSchema)]
struct Value {
field: InnerValue
}
impl schemars::JsonSchema for Value__NEAR_SCHEMA_PROXY { ... }
}
};
near-sdk/src/lib.rs
Outdated
@@ -5,6 +5,8 @@ | |||
#[cfg(test)] | |||
extern crate quickcheck; | |||
|
|||
#[cfg(feature = "abi")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we put this export under unstable as well for now? Doesn't seem clear this will be more intuitive than deriving the traits directly yet and the internal semantics aren't tested yet.
Effectively translates into
When compiled targeting WASM, this is a no-op.