Skip to content

Commit

Permalink
Sylvia: Describe forwarding attributes to message fields
Browse files Browse the repository at this point in the history
  • Loading branch information
jawoznia committed Aug 1, 2024
1 parent 3696850 commit 94a08a7
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 16 deletions.
27 changes: 14 additions & 13 deletions src/pages/sylvia/basics/contract-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,18 @@ In the first two lines, we see the usage of two macros:
point collision.

- [`contract`](../macros/contract) - Parses every method inside the `impl` block marked with the
`[sv::msg(...)]` attribute and create proper messages and utilities like helpers for
[`MultiTest`](../../cw-multi-test).
[`[sv::msg(...)]`](../attributes/msg) attribute and create proper messages and utilities like
helpers for [`MultiTest`](../../cw-multi-test).

This simple example also has the `sv::msg(...)` attributes. Sylvia macros distinguish the if message
should be generated from the marked method and of what type.
This simple example also has the [`sv::msg(...)`](../attributes/msg) attributes. Sylvia macros
distinguish the if message should be generated from the marked method and of what type.

CosmWasm contract requires the `instantiate` message, and it is mandatory to specify it for the
`contract` macro. We have to provide it with the proper context type:
[`contract`](../macros/contract) macro. We have to provide it with the proper context type:
[`InstantiateCtx`](https://docs.rs/sylvia/latest/sylvia/types/struct.InstantiateCtx.html). Another
mandatory method is the `new`, as contract fields are out of scope for the `contract` macro, and
otherwise we wouldn't be able to create the contract object in message dispatching.
mandatory method is the `new`, as contract fields are out of scope for the
[`contract`](../macros/contract) macro, and otherwise we wouldn't be able to create the contract
object in message dispatching.

Context gives us access to the blockchain state, information about our contract, and the sender of
the message. We return the
Expand All @@ -85,16 +86,16 @@ standard CosmWasm error
[`Response`](https://docs.rs/cosmwasm-std/latest/cosmwasm_std/struct.Response.html).

The template contract also contains a query and an exec messages. Each type of message in CosmWasm
supports different contexts. F.e. the
[`QueryCtx`](https://docs.rs/sylvia/latest/sylvia/types/struct.QueryCtx.html) exposes to the user an
supports different contexts. F.e. the [`QueryCtx`](../types/context) exposes to the user an
immutable [`Deps`](https://docs.rs/cosmwasm-std/latest/cosmwasm_std/struct.Deps.html) as by design,
queries should never mutate the state. This is not the case for the
[`ExecCtx`](https://docs.rs/sylvia/latest/sylvia/types/struct.ExecCtx.html) and `InstantiateCtx`
which exposes the [`DepsMut`](https://docs.rs/cosmwasm-std/latest/cosmwasm_std/struct.DepsMut.html).
queries should never mutate the state. This is not the case for the [`ExecCtx`](../types/context)
and `InstantiateCtx` which exposes the
[`DepsMut`](https://docs.rs/cosmwasm-std/latest/cosmwasm_std/struct.DepsMut.html).

Fell free expanding the macro now and seeing what Sylvia generates. It might be overwhelming, as
there will be a lot of things generated that seem not relevant to our code, so for the bare minimum,
check the `InstantiateMsg` and its `impl` block.
check the [`InstantiateMsg`](../macros/generated-types/message-types#contract-messages) and its
`impl` block.

Sylvia doesn't generate anything magical, but regular CosmWasm contract types customized based on
the provided methods and attributes. This means that the Sylvia contract is fully interoperational
Expand Down
36 changes: 33 additions & 3 deletions src/pages/sylvia/macros/contract.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ import { Callout } from "nextra/components";

# Contract

Use the `contract` macro to generate contract messages
Use the [`contract`](https://docs.rs/sylvia/latest/sylvia/attr.contract.html) macro to generate
contract messages

<Callout>Use `contract` macro only on top of struct impl blocks</Callout>
<Callout>
Use [`contract`](https://docs.rs/sylvia/latest/sylvia/attr.contract.html) macro only on top of
struct impl blocks
</Callout>

## Attributes

List of attributes supported by `contract` macro:
List of attributes supported by
[`contract`](https://docs.rs/sylvia/latest/sylvia/attr.contract.html) macro:

- [`custom`](../attributes/custom)
- [`error`](../attributes/error)
Expand Down Expand Up @@ -142,6 +147,31 @@ This is a standard way to create generic structs in Rust. Two important things t
fulfill their trait bounds. In most cases it's enough to add the
`sylvia::types::CustomMsg + \'static` bounds.

## Forwarding attributes to fields

The [`contract`](https://docs.rs/sylvia/latest/sylvia/attr.contract.html) macro can forward
attributes to the fields of the messages.

```rust {5}
#[sv::msg(instantiate)]
fn instantiate(
&self,
ctx: InstantiateCtx,
#[serde(default)] value: String,
) -> StdResult<Response> {
Ok(Response::new())
}
```

The output of the above code will be:

```rust {2}
pub struct InstantiateMsg {
#[serde(default)]
pub value: String,
}
```

## Good practices

### Prefer generic custom types
Expand Down
25 changes: 25 additions & 0 deletions src/pages/sylvia/macros/interface.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,28 @@ pub trait Interface {
fn interface_exec(&self, ctx: ExecCtx, param: Self::MyType) -> StdResult<Response>;
}
```

## Forwarding attributes to fields

The [`interface`](https://docs.rs/sylvia/latest/sylvia/attr.interface.html) macro can forward
attributes to the fields of the messages.

```rust {5}
#[sv::msg(exec)]
fn exec(
&self,
ctx: ExecCtx,
#[serde(default)] value: String,
) -> Result<Response, Self::Error>;
```

The output of the above code will be:

```rust {2}
pub enum MyInterfaceExecMsg {
Exec {
#[serde(default)]
value: String,
},
}
```

0 comments on commit 94a08a7

Please sign in to comment.