-
Notifications
You must be signed in to change notification settings - Fork 253
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
Impr docs #1262
Open
PolyProgrammist
wants to merge
33
commits into
near:master
Choose a base branch
from
PolyProgrammist:impr-docs
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Impr docs #1262
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
7d18cd0
tmp
PolyProgrammist 3803218
tmp
PolyProgrammist d1015f0
nearschema
PolyProgrammist 245c1c9
link for store crate, neargas and neartoken types
PolyProgrammist 34d774f
promises in env
PolyProgrammist 5f0aeb1
fmt and env intro
PolyProgrammist ed0bdef
promise_index and promise structs
PolyProgrammist 589d61c
storage and functionerror
PolyProgrammist 1911c50
small
PolyProgrammist b6951e7
denbite review
PolyProgrammist 3b1ce54
Merge branch 'master' into impr-docs
PolyProgrammist feaa181
comments from PR 1259
PolyProgrammist 8d178bd
fmt
PolyProgrammist aef8c14
clippy
PolyProgrammist 49bc57b
fmt
PolyProgrammist f29575c
docs test fix
PolyProgrammist 48ccae6
fix doc
PolyProgrammist 4d92375
fix docs
PolyProgrammist 63b8b0a
fix docs
PolyProgrammist d46cd16
fix
PolyProgrammist 9bbd19a
fix
PolyProgrammist 08dd4ff
Merge branch 'master' into impr-docs
PolyProgrammist 99c7e13
fix ci test
PolyProgrammist e1c6c57
Merge branch 'master' into impr-docs
PolyProgrammist 22e4098
fmt
PolyProgrammist c63918d
ignore to no_run
PolyProgrammist c2732a2
remove unnecessary near-primitives and near-vm-runner for docs
PolyProgrammist f0c05da
fix no-run tests
PolyProgrammist 8e16e83
fmt
PolyProgrammist 916e81d
fix tests
PolyProgrammist 3d5cb4e
fmt
PolyProgrammist bc34ace
fix tests
PolyProgrammist b1b185f
checkj
PolyProgrammist File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,57 +43,140 @@ struct NearMacroArgs { | |
inside_nearsdk: Option<bool>, | ||
} | ||
|
||
/// This attribute macro is used to enhance the near_bindgen macro. | ||
/// It is used to add Borsh and Serde derives for serialization and deserialization. | ||
/// It also adds `BorshSchema` and `JsonSchema` if needed | ||
/// | ||
/// If you would like to add Borsh or Serde serialization and deserialization to your contract, | ||
/// you can use the abi attribute and pass in the serializers you would like to use. | ||
/// This attribute macro is used on a struct and its implementations | ||
/// to generate the necessary code to expose `pub` methods from the contract as well | ||
/// as generating the glue code to be a valid NEAR contract. | ||
/// | ||
/// # Example | ||
/// ## Example | ||
/// | ||
/// ```ignore | ||
/// #[near(serializers=[borsh, json])] | ||
/// struct MyStruct { | ||
/// pub name: String, | ||
/// } | ||
/// ``` | ||
/// effectively becomes: | ||
/// | ||
/// This macro will generate code to load and deserialize state if the `self` parameter is included | ||
/// as well as saving it back to state if `&mut self` is used. | ||
/// | ||
/// # Parameter and result serialization | ||
/// If the macro is used with Impl section, for parameter serialization, this macro will generate a struct with all of the parameters as | ||
/// fields and derive deserialization for it. By default this will be JSON deserialized with `serde` | ||
/// but can be overwritten by using `#[serializer(borsh)]`: | ||
/// ```ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add rust tag |
||
/// use borsh::{BorshSerialize, BorshDeserialize}; | ||
/// use serde::{Serialize, Deserialize}; | ||
/// use near_sdk_macro::NearSchema; | ||
/// #[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, NearSchema)] | ||
/// #[borsh(crate = "near_sdk::borsh")] | ||
/// #[serde(crate = "near_sdk::serde")] | ||
/// struct MyStruct { | ||
/// pub name: String, | ||
/// #[near] | ||
/// impl Adder { | ||
/// #[result_serializer(borsh)] | ||
/// pub fn borsh_parameters(&self, #[serializer(borsh)] a: Pair, #[serializer(borsh)] b: Pair) -> Pair { | ||
/// /// ... | ||
/// } | ||
/// } | ||
/// ``` | ||
/// | ||
/// `#[near]` will also handle serializing and setting the return value of the | ||
/// function execution based on what type is returned by the function. By default, this will be | ||
/// done through `serde` serialized as JSON, but this can be overwritten using | ||
/// `#[result_serializer(borsh)]`: | ||
/// ```ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rust |
||
/// #[near] | ||
/// impl Adder { | ||
/// #[result_serializer(borsh)] | ||
/// pub fn borsh_parameters(&self) -> Pair { | ||
/// /// ... | ||
/// } | ||
/// } | ||
/// ``` | ||
/// Please note that `BorshSchema` and `JsonSchema` are added inside NearSchema whenever you use near macro for struct or enum. | ||
/// By default, if no serializers are passed, Borsh is used. | ||
/// | ||
/// If you want this struct to be a contract state, you can pass in the contract_state argument. | ||
/// # Usage for enum / struct | ||
/// | ||
/// If the macro is used with struct or enum, it will make the struct or enum serializable with either | ||
/// Borsh or Json depending on serializers passed. Use `#[near(serializers=[borsh])]` to make it serializable with Borsh. | ||
/// Or use `#[near(serializers=[json])]` to make it serializable with Json. By default, borsh is used. | ||
/// You can also specify both and none. BorshSchema or JsonSchema are always generated. | ||
/// | ||
/// # Example | ||
/// If you want the struct to be a contract state, you can pass in the contract_state argument. | ||
/// | ||
/// ## Example | ||
/// ```ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same |
||
/// use near_sdk::near; | ||
/// | ||
/// #[near(contract_state)] | ||
/// struct MyStruct { | ||
/// pub name: String, | ||
/// pub struct Contract { | ||
/// data: i8, | ||
/// } | ||
/// | ||
/// #[near] | ||
/// impl Contract { | ||
/// pub fn some_function(&self) {} | ||
/// } | ||
/// ``` | ||
/// becomes: | ||
/// As well, the macro supports arguments like `event_json` and `contract_metadata`. | ||
/// | ||
/// # Events Standard: | ||
/// | ||
/// By passing `event_json` as an argument `near_bindgen` will generate the relevant code to format events | ||
/// according to NEP-297 | ||
/// | ||
/// For parameter serialization, this macro will generate a wrapper struct to include the NEP-297 standard fields `standard` and `version | ||
/// as well as include serialization reformatting to include the `event` and `data` fields automatically. | ||
/// The `standard` and `version` values must be included in the enum and variant declaration (see example below). | ||
/// By default this will be JSON deserialized with `serde` | ||
/// | ||
/// | ||
/// ## Examples | ||
/// | ||
/// ```ignore | ||
/// #[near_bindgen] | ||
/// #[derive(BorshSerialize, BorshDeserialize, NearSchema)] | ||
/// #[borsh(crate = "near_sdk::borsh")] | ||
/// struct MyStruct { | ||
/// pub name: String, | ||
/// use near_sdk::near; | ||
/// | ||
/// #[near(event_json(standard = "nepXXX"))] | ||
/// pub enum MyEvents { | ||
/// #[event_version("1.0.0")] | ||
/// Swap { token_in: AccountId, token_out: AccountId, amount_in: u128, amount_out: u128 }, | ||
/// | ||
/// #[event_version("2.0.0")] | ||
/// StringEvent(String), | ||
/// | ||
/// #[event_version("3.0.0")] | ||
/// EmptyEvent | ||
/// } | ||
/// | ||
/// #[near] | ||
/// impl Contract { | ||
/// pub fn some_function(&self) { | ||
/// MyEvents::StringEvent( | ||
/// String::from("some_string") | ||
/// ).emit(); | ||
/// } | ||
/// | ||
/// } | ||
/// ``` | ||
/// | ||
/// As well, the macro supports arguments like `event_json` and `contract_metadata`. | ||
/// # Contract Source Metadata Standard: | ||
/// | ||
/// By using `contract_metadata` as an argument `near` will populate the contract metadata | ||
/// according to [`NEP-330`](<https://github.com/near/NEPs/blob/master/neps/nep-0330.md>) standard. This still applies even when `#[near]` is used without | ||
/// any arguments. | ||
/// | ||
/// All fields(version, link, standard) are optional and will be populated with defaults from the Cargo.toml file if not specified. | ||
/// | ||
/// The `contract_source_metadata()` view function will be added and can be used to retrieve the source metadata. | ||
/// Also, the source metadata will be stored as a constant, `CONTRACT_SOURCE_METADATA`, in the contract code. | ||
/// | ||
/// ## Examples | ||
/// ```ignore | ||
/// use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize}; | ||
/// use near_sdk::near; | ||
/// | ||
/// #[derive(Default, BorshSerialize, BorshDeserialize)] | ||
/// #[near(contract_metadata( | ||
/// version = "39f2d2646f2f60e18ab53337501370dc02a5661c", | ||
/// link = "https://github.com/near-examples/nft-tutorial", | ||
/// standard(standard = "nep330", version = "1.1.0"), | ||
/// standard(standard = "nep171", version = "1.0.0"), | ||
/// standard(standard = "nep177", version = "2.0.0"), | ||
/// ))] | ||
/// struct Contract {} | ||
/// ``` | ||
#[proc_macro_attribute] | ||
pub fn near(attr: TokenStream, item: TokenStream) -> TokenStream { | ||
if attr.to_string().contains("event_json") { | ||
|
@@ -235,103 +318,23 @@ pub fn near(attr: TokenStream, item: TokenStream) -> TokenStream { | |
TokenStream::from(expanded) | ||
} | ||
|
||
/// This attribute macro is used on a struct and its implementations | ||
/// to generate the necessary code to expose `pub` methods from the contract as well | ||
/// as generating the glue code to be a valid NEAR contract. | ||
/// | ||
/// This macro will generate code to load and deserialize state if the `self` parameter is included | ||
/// as well as saving it back to state if `&mut self` is used. | ||
/// | ||
/// For parameter serialization, this macro will generate a struct with all of the parameters as | ||
/// fields and derive deserialization for it. By default this will be JSON deserialized with `serde` | ||
/// but can be overwritten by using `#[serializer(borsh)]`. | ||
/// | ||
/// `#[near_bindgen]` will also handle serializing and setting the return value of the | ||
/// function execution based on what type is returned by the function. By default, this will be | ||
/// done through `serde` serialized as JSON, but this can be overwritten using | ||
/// `#[result_serializer(borsh)]`. | ||
/// | ||
/// # Examples | ||
/// | ||
/// This macro is deprecated. Use [#\[near\]](./attr.near.html) instead. The difference between #\[near\] and #\[near_bindgen\] is that | ||
/// with #\[near_bindgen\] you have to manually add boilerplate code for structs and enums so that they become Json- and Borsh-serializable: | ||
/// ```ignore | ||
/// use near_sdk::near_bindgen; | ||
/// | ||
/// #[near_bindgen] | ||
/// pub struct Contract { | ||
/// data: i8, | ||
/// } | ||
/// | ||
/// #[near_bindgen] | ||
/// impl Contract { | ||
/// pub fn some_function(&self) {} | ||
/// #[derive(BorshSerialize, BorshDeserialize, NearSchema)] | ||
/// #[borsh(crate = "near_sdk::borsh")] | ||
/// struct MyStruct { | ||
/// pub name: String, | ||
/// } | ||
/// ``` | ||
/// | ||
/// Events Standard: | ||
/// | ||
/// By passing `event_json` as an argument `near_bindgen` will generate the relevant code to format events | ||
/// according to NEP-297 | ||
/// | ||
/// For parameter serialization, this macro will generate a wrapper struct to include the NEP-297 standard fields `standard` and `version | ||
/// as well as include serialization reformatting to include the `event` and `data` fields automatically. | ||
/// The `standard` and `version` values must be included in the enum and variant declaration (see example below). | ||
/// By default this will be JSON deserialized with `serde` | ||
/// | ||
/// | ||
/// # Examples | ||
/// | ||
/// Instead of: | ||
/// ```ignore | ||
/// use near_sdk::near_bindgen; | ||
/// | ||
/// #[near_bindgen(event_json(standard = "nepXXX"))] | ||
/// pub enum MyEvents { | ||
/// #[event_version("1.0.0")] | ||
/// Swap { token_in: AccountId, token_out: AccountId, amount_in: u128, amount_out: u128 }, | ||
/// | ||
/// #[event_version("2.0.0")] | ||
/// StringEvent(String), | ||
/// | ||
/// #[event_version("3.0.0")] | ||
/// EmptyEvent | ||
/// } | ||
/// | ||
/// #[near_bindgen] | ||
/// impl Contract { | ||
/// pub fn some_function(&self) { | ||
/// MyEvents::StringEvent( | ||
/// String::from("some_string") | ||
/// ).emit(); | ||
/// } | ||
/// | ||
/// #[near] | ||
/// struct MyStruct { | ||
/// pub name: String, | ||
/// } | ||
/// ``` | ||
/// | ||
/// Contract Source Metadata Standard: | ||
/// | ||
/// By using `contract_metadata` as an argument `near_bindgen` will populate the contract metadata | ||
/// according to [`NEP-330`](<https://github.com/near/NEPs/blob/master/neps/nep-0330.md>) standard. This still applies even when `#[near_bindgen]` is used without | ||
/// any arguments. | ||
/// | ||
/// All fields(version, link, standard) are optional and will be populated with defaults from the Cargo.toml file if not specified. | ||
/// | ||
/// The `contract_source_metadata()` view function will be added and can be used to retrieve the source metadata. | ||
/// Also, the source metadata will be stored as a constant, `CONTRACT_SOURCE_METADATA`, in the contract code. | ||
/// | ||
/// # Examples | ||
/// ```ignore | ||
/// use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize}; | ||
/// use near_sdk::near_bindgen; | ||
/// | ||
/// #[derive(Default, BorshSerialize, BorshDeserialize)] | ||
/// #[near_bindgen(contract_metadata( | ||
/// version = "39f2d2646f2f60e18ab53337501370dc02a5661c", | ||
/// link = "https://github.com/near-examples/nft-tutorial", | ||
/// standard(standard = "nep330", version = "1.1.0"), | ||
/// standard(standard = "nep171", version = "1.0.0"), | ||
/// standard(standard = "nep177", version = "2.0.0"), | ||
/// ))] | ||
/// struct Contract {} | ||
/// ``` | ||
#[proc_macro_attribute] | ||
pub fn near_bindgen(attr: TokenStream, item: TokenStream) -> TokenStream { | ||
if attr.to_string().contains("event_json") { | ||
|
@@ -459,7 +462,7 @@ fn process_impl_block( | |
/// Each of these static methods takes positional arguments defined by the Trait, | ||
/// then the receiver_id, the attached deposit and the amount of gas and returns a new Promise. | ||
/// | ||
/// # Examples | ||
/// ## Examples | ||
/// | ||
/// ```ignore | ||
/// use near_sdk::ext_contract; | ||
|
@@ -469,7 +472,19 @@ fn process_impl_block( | |
/// fn mult(&self, a: u64, b: u64) -> u128; | ||
/// fn sum(&self, a: u128, b: u128) -> u128; | ||
/// } | ||
/// | ||
/// #[near] | ||
/// impl Contract { | ||
/// pub fn multiply_by_five(&mut self, number: u64) -> Promise { | ||
/// ext_calculator::ext(self.calculator_account.clone()) | ||
/// .with_static_gas(Gas::from_tgas(5)) | ||
/// .mult(number, 5) | ||
/// } | ||
/// } | ||
/// | ||
/// ``` | ||
/// | ||
/// See more information about role of ext_contract in [NEAR documentation](https://docs.near.org/build/smart-contracts/anatomy/crosscontract) | ||
PolyProgrammist marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#[proc_macro_attribute] | ||
pub fn ext_contract(attr: TokenStream, item: TokenStream) -> TokenStream { | ||
if let Ok(mut input) = syn::parse::<ItemTrait>(item) { | ||
|
@@ -553,6 +568,18 @@ struct DeriveNearSchema { | |
borsh: Option<bool>, | ||
} | ||
|
||
/// `NearSchema` is a derive macro that generates `BorshSchema` and / or `JsonSchema` implementations. | ||
/// Use `#[abi(json)]` attribute to generate code for `JsonSchema`. And `#[abi(borsh)]` for `BorshSchema`. | ||
PolyProgrammist marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// You can use both and none as well. | ||
/// ## Example | ||
/// ```ignore | ||
/// #[derive(NearSchema)] | ||
/// #[abi(borsh)] | ||
/// struct Value { | ||
/// field: InnerValue, | ||
/// } | ||
/// ``` | ||
/// In this example, BorshSchema will be generated for `Value` struct. | ||
#[proc_macro_derive(NearSchema, attributes(abi, serde, borsh, schemars, validate, inside_nearsdk))] | ||
pub fn derive_near_schema(#[allow(unused)] input: TokenStream) -> TokenStream { | ||
#[cfg(not(feature = "abi"))] | ||
|
@@ -787,6 +814,31 @@ pub fn derive_no_default(item: TokenStream) -> TokenStream { | |
/// `BorshStorageKey` generates implementation for `BorshIntoStorageKey` trait. | ||
/// It allows the type to be passed as a unique prefix for persistent collections. | ||
/// The type should also implement or derive `BorshSerialize` trait. | ||
/// | ||
/// More information about storage keys in [NEAR documentation](https://docs.near.org/build/smart-contracts/anatomy/storage) | ||
PolyProgrammist marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// ## Example | ||
/// ```ignore | ||
/// #[derive(BorshSerialize, BorshDeserialize, BorshStorageKey)] | ||
/// #[borsh(crate = "near_sdk::borsh")] | ||
/// pub enum StorageKey { | ||
/// Messages, | ||
/// } | ||
/// | ||
/// // Define the contract structure | ||
/// #[near(contract_state)] | ||
/// pub struct Contract { | ||
/// messages: Vector<String> | ||
/// } | ||
/// | ||
/// // Define the default, which automatically initializes the contract | ||
/// impl Default for Contract { | ||
/// fn default() -> Self { | ||
/// Self { | ||
/// messages: Vector::new(StorageKey::Messages) | ||
/// } | ||
/// } | ||
/// } | ||
/// ``` | ||
#[proc_macro_derive(BorshStorageKey)] | ||
pub fn borsh_storage_key(item: TokenStream) -> TokenStream { | ||
let (name, generics) = if let Ok(input) = syn::parse::<ItemEnum>(item.clone()) { | ||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
rust tag
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.
this is probably not possible as is,
doing
results in
this is why #1288 was suggested
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.
alternatively to #1288, a circular
[dev-dependency]
appears to allow this too:not sure if this entails additional problems, but this looks a one-liner compared to moving larger blocks of code.
And near-sdk kind of re-exports all of its dependencies it uses for derive macros (does it?)
Please leave a comment on #1288, if you decide to try a circular
[dev-dependency]
insteadThere 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.
To be honest, I agree that it's better to document on near sdk level. I doubt that a lot of people will go in the macro crate at all...
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.
the doc will be re-exported from near-sdk-macros anyway, as it is now
Another example/explanation: doc at https://docs.rs/borsh/1.5.4/borsh/derive.BorshSerialize.html gets concatenated of 2 pieces: one at doc-comment at site of re-export, one at original doc-comment site:
the only subtlety i see , is that if one does
then
near-sdk/__abi-generate
=>near-sdk-macros/__abi-generate
feature becomes implicitly enabledwhen anyone runs
cargo test
fornear-sdk-macros
crate (which wouldn't be otherwise enabled) , but i think it's kind of ok here.so it looks like trying a one-liner is simpler, than moving a few blocks of code.
Anyway, @akorchyn should make a final call for the pr here, as he owns the review here
(i'm pro #1288 approach , doc at reexport in near-sdk should describe how to use the macros,
doc in near-sdk-macros of various non-public items might explain how the macros work internally, if someone wants to understand/extend them, the latter is only possible when documenting private items is enabled for proc-macro crates)
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.
I like the #1288 approach more, to be honest.