Skip to content
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

doc: moved annotations to the near macro documentation. #1299

Merged
merged 14 commits into from
Feb 6, 2025
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

**Release notes and unreleased changes can be found in the [CHANGELOG](https://github.com/near/near-sdk-rs/blob/master/CHANGELOG.md)**

## Example
## Example. For more information, see the [near](https://docs.rs/near-sdk/latest/near_sdk/attr.near.html) documentation

Wrap a struct in `#[near]` and it generates a smart contract compatible with the NEAR blockchain:
```rust
Expand Down
267 changes: 231 additions & 36 deletions near-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
//! near-sdk = "5.6.0"
//! ```
//!
//! ### Example: Counter Smart Contract. For more information, see the [macro@near] documentation.
//! ### Example: Counter Smart Contract. For more information, see the [near] documentation.
//!
//! Below is an example of a simple counter contract that increments and retrieves a value:
//!
Expand Down Expand Up @@ -102,26 +102,172 @@ extern crate quickcheck;
/// 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.
///
/// The macro is a syntactic sugar for [macro@near_bindgen] and expands to the [macro@near_bindgen] macro invocations.
/// The macro is a syntactic sugar for [near_bindgen] and expands to the [near_bindgen] macro invocations.
///
/// ## Example
/// # Sub-attributes
///
/// ## `#[near(contract_state)]` (annotates structs/enums)
///
/// The macro sub-attribute prepares a struct/enum to be a contract state.
///
/// 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.
///
/// ### Basic example
/// ```rust
/// use near_sdk::near;
///
/// #[near(contract_state)]
/// pub struct Contract {
/// data: i8,
/// }
///
/// #[near]
/// impl Contract {
/// pub fn some_function(&self) {}
/// }
/// ```
///
/// ## `#[near(serializers=[...])` (annotates structs/enums)
///
/// The macro sub-attribute makes the struct or enum serializable with either json or borsh. By default, borsh is used.
///
/// ### Make struct/enum serializable with borsh
///
/// ```rust
/// use near_sdk::near;
///
/// #[near(serializers=[borsh])]
/// pub enum MyEnum {
/// Variant1,
/// }
///
/// #[near(serializers=[borsh])]
/// pub struct MyStruct {
/// pub name: String,
/// }
/// ```
///
/// ### Make struct/enum serializable with json
///
/// ```rust
/// use near_sdk::near;
/// #[near(serializers=[json])]
/// pub enum MyEnum {
/// Variant1,
/// }
///
/// #[near(serializers=[json])]
/// pub struct MyStruct {
/// pub name: String,
/// }
/// ```
///
/// ### Make struct/enum serializable with both borsh and json
///
/// ```rust
/// use near_sdk::near;
/// #[near(serializers=[borsh, json])]
/// struct MyStruct {
/// pub name: String,
/// pub enum MyEnum {
/// Variant1,
/// }
///
/// #[near(serializers=[borsh, json])]
/// pub struct MyStruct {
/// pub name: String,
/// }
/// ```
///
/// 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.
/// ## `#[init]` (annotates methods of a type in its `impl` block)
///
/// Contract initialization method annotation. More details can be found [here](https://docs.near.org/build/smart-contracts/anatomy/storage#initializing-the-state)
///
/// By default, the `Default::default()` implementation of a contract will be used to initialize a contract.
/// There can be a custom initialization function which takes parameters or performs custom logic with the following `#[init]` annotation.
///
/// You can provide several initialization functions.
///
/// ### Basic example
///
/// ```rust
/// use near_sdk::{log, near};
///
/// #[near(contract_state)]
/// #[derive(Default)]
/// pub struct Counter {
/// value: u64,
/// }
///
/// #[near]
/// impl Counter {
/// #[init]
/// pub fn new(value: u64) -> Self {
/// log!("Custom counter initialization!");
/// Self { value }
/// }
/// }
/// ```
///
/// ## `#[payable]` (annotates methods of a type in its `impl` block)
///
/// Specifies that the method can accept NEAR tokens. More details can be found [here](https://docs.near.org/build/smart-contracts/anatomy/functions#payable-functions)
///
/// Methods can be annotated with `#[payable]` to allow tokens to be transferred with the method invocation. For more information, see payable methods.
///
/// To declare a function as payable, use the `#[payable]` annotation as follows:
///
/// ### Basic example
///
/// ```rust
///use near_sdk::near;
///
/// #[near(contract_state)]
/// #[derive(Default)]
/// pub struct Counter {
/// val: i8,
/// }
///
/// #[near]
/// impl Counter {
/// #[payable]
/// pub fn my_method(&mut self) {
/// //...
/// }
/// }
/// ```
///
/// ## `#[private]` (annotates methods of a type in its `impl` block)]
///
/// The macro sub-attribute forbids to call the method except from within the contract.
/// This is useful for internal methods that should not be called from outside the contract.
///
/// More details can be found [here](https://docs.near.org/build/smart-contracts/anatomy/functions#private-functions)
///
/// ### Basic example
///
/// ```rust
/// use near_sdk::near;
///
/// #[near(contract_state)]
/// #[derive(Default)]
/// pub struct Counter {
/// val: u64,
/// }
///
/// #[near]
/// impl Counter {
/// #[private]
/// pub fn my_method(&mut self) {
/// // ...
/// }
/// }
/// ```
///
/// ## `#[result_serializer(...)]` (annotates methods of a type in its `impl` block)
///
/// The macro sub-attribute defines the serializer for function return serialization.
/// Only one of `borsh` or `json` can be specified.
///
/// # 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)]`:
/// ```rust
/// use near_sdk::near;
///
Expand All @@ -139,10 +285,13 @@ extern crate quickcheck;
/// }
/// ```
///
/// `#[near]` will also handle serializing and setting the return value of the
/// `#[near]` will 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you mind

  1. removing this example from this sub-heading?
  2. moving example to a separate sub-heading ( with #[result_serializer(borsh)] annotation removed):
## `#[serializer(...)]` (annotates arguments of methods of a type in its `impl` block)
  1. adding it to near-sdk/src/near_annotations.rs index as serializer entry/function name (which will be distinct from serializers one 🤦‍♂️ )
  2. this could be at least renamed to arg_serializer in 6.0.0, and serializers -> to type_serializers just to have them a bit more distinct

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not resolved

/// done through `serde` serialized as JSON, but this can be overridden using
/// `#[result_serializer(borsh)]`:
///
/// ### Basic example
///
/// ```rust
/// use near_sdk::near;
///
Expand All @@ -160,43 +309,91 @@ extern crate quickcheck;
/// }
/// ```
///
/// # Usage for enum / struct
/// ## `#[handle_result]` (annotates methods of a type in its `impl` block)
///
/// 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 if respective serializer is toggled on.
/// Have `#[handle_result]` to Support Result types regardless of how they're referred to
/// Function marked with `#[handle_result]` should return `Result<T, E>` (where E implements [FunctionError]).
/// If you're trying to use a type alias for `Result`, try `#[handle_result(aliased)]`
///
/// If you want the struct/enum to be a contract state, you can pass in the contract_state argument.
/// ### Basic error handling example
///
/// This example shows how to use error handling in a contract when the types are defined in the contract.
/// This way the contract can utilize result types and panic with the type using its [ToString] implementation
///
/// ## Example
/// ```rust
/// use near_sdk::near;
/// use near_sdk::{near, FunctionError};
///
/// #[derive(FunctionError)]
/// pub enum MyError {
/// SomePanicError,
/// }
///
/// impl std::fmt::Display for MyError {
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// match self {
/// MyError::SomePanicError => write!(f, "Panic error message that would be displayed to the user"),
/// }
/// }
/// }
///
/// #[near(contract_state)]
/// pub struct Contract {
/// data: i8,
/// pub struct MyContract {
/// pub some_value: u64,
/// }
///
/// #[near]
/// impl Contract {
/// pub fn some_function(&self) {}
/// impl MyContract {
/// #[handle_result]
/// pub fn some_function(&self) -> Result<(), MyError> {
/// if self.some_value == 0 {
/// return Err(MyError::SomePanicError);
/// }
/// Ok(())
/// }
/// }
/// ```
///
/// # Events Standard:
/// ### Basic callback function example
///
/// By passing `event_json` as an argument `near_bindgen` will generate the relevant code to format events
/// This examples shows how to create a function that handles the result of a
/// cross-chain call. For more details, see [here](https://docs.near.org/build/smart-contracts/anatomy/crosscontract#callback-function)
///
/// ```rust
/// use near_sdk::{near, AccountId, Promise, PromiseError};
///
/// #[near(contract_state)]
/// #[derive(Default)]
/// pub struct Counter {
/// val: u64,
/// }
///
/// #[near]
/// impl Counter {
/// #[handle_result]
/// pub fn get_result(
/// &self,
/// account_id: AccountId,
/// #[callback_result] set_status_result: Result<(), PromiseError>,
/// ) -> Result<(), &'static str> {
/// // ..
/// Ok(())
/// }
/// }
/// ```
///
/// ## `#[event_json(...)]` (annotates enums)
///
/// By passing `event_json` as an argument `near` will generate the relevant code to format events
/// according to [NEP-297](https://github.com/near/NEPs/blob/master/neps/nep-0297.md)
///
/// For parameter serialization, this macro will generate a wrapper struct to include the NEP-297 standard fields `standard` and `version
/// 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`
///
/// The version is required to allow backward compatibility. The older back-end will use the version field to determine if the event is supported.
///
/// ## Examples
/// ### Basic example
///
/// ```rust
/// use near_sdk::{near, AccountId};
Expand All @@ -205,8 +402,6 @@ extern crate quickcheck;
/// # pub struct Contract {
/// # data: i8,
/// # }
///
///
/// #[near(event_json(standard = "nepXXX"))]
/// pub enum MyEvents {
/// #[event_version("1.0.0")]
Expand All @@ -230,7 +425,7 @@ extern crate quickcheck;
/// }
/// ```
///
/// # Contract Source Metadata Standard:
/// ## `#[near(contract_metadata(...))]` (annotates structs/enums)
///
/// 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
Expand All @@ -244,7 +439,7 @@ extern crate quickcheck;
/// 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
/// ### Basic example
///
/// ```rust
/// use near_sdk::near;
Expand All @@ -259,7 +454,7 @@ extern crate quickcheck;
/// ```
pub use near_sdk_macros::near;

/// This macro is deprecated. Use [macro@near] instead. The difference between `#[near]` and `#[near_bindgen]` is that
/// This macro is deprecated. Use [near] 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:
/// ```rust
/// use near_sdk::{near_bindgen, NearSchema, borsh::{BorshSerialize, BorshDeserialize}};
Expand Down Expand Up @@ -366,7 +561,7 @@ pub use near_sdk_macros::BorshStorageKey;
pub use near_sdk_macros::PanicOnDefault;

/// NOTE: This is an internal implementation for `#[near_bindgen(events(standard = ...))]` attribute.
/// Please use [macro@near] instead.
/// Please use [near] instead.
///
/// This derive macro is used to inject the necessary wrapper and logic to auto format
/// standard event logs and generate the `emit` function, and event version.
Expand All @@ -391,7 +586,7 @@ pub use near_sdk_macros::EventMetadata;
pub use near_sdk_macros::NearSchema;

/// `FunctionError` generates implementation for `near_sdk::FunctionError` trait.
/// It allows contract runtime to panic with the type using its `ToString` implementation
/// It allows contract runtime to panic with the type using its [ToString] implementation
/// as the message.
/// ## Example
/// ```rust
Expand Down Expand Up @@ -461,7 +656,7 @@ pub use crate::utils::storage_key_impl::IntoStorageKey;
pub use crate::utils::*;

#[cfg(feature = "__macro-docs")]
pub mod near;
pub mod near_annotations;

#[cfg(all(feature = "unit-testing", not(target_arch = "wasm32")))]
pub mod test_utils;
Expand Down
Loading
Loading