-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathlib.rs
More file actions
134 lines (127 loc) · 3.79 KB
/
lib.rs
File metadata and controls
134 lines (127 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
extern crate proc_macro;
mod declare_program;
use declare_program::DeclareProgram;
use quote::ToTokens;
use syn::parse_macro_input;
/// The `#[program]` attribute defines the module containing all instruction
/// handlers defining all entries into a Solana program.
#[proc_macro_attribute]
pub fn program(
_args: proc_macro::TokenStream,
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let program = parse_macro_input!(input as anchor_syn::Program);
let program_tokens = program.to_token_stream();
#[cfg(feature = "idl-build")]
{
use anchor_syn::idl::gen_idl_print_fn_program;
let idl_tokens = gen_idl_print_fn_program(&program);
return proc_macro::TokenStream::from(quote::quote! {
#program_tokens
#idl_tokens
});
}
#[allow(unreachable_code)]
proc_macro::TokenStream::from(program_tokens)
}
/// Declare an external program based on its IDL.
///
/// The IDL of the program must exist in a directory named `idls`. This directory can be at any
/// depth, e.g. both inside the program's directory (`<PROGRAM_DIR>/idls`) and inside Anchor
/// workspace root directory (`<PROGRAM_DIR>/../../idls`) are valid.
///
/// # Usage
///
/// ```rs
/// declare_program!(program_name);
/// ```
///
/// This generates a module named `program_name` that can be used to interact with the program
/// without having to add the program's crate as a dependency.
///
/// Both on-chain and off-chain usage is supported.
///
/// Use `cargo doc --open` to see the generated modules and their documentation.
///
/// # Note
///
/// Re-defining the same program to use the same definitions should be avoided since this results
/// in a larger binary size.
///
/// A program should only be defined once. If you have multiple programs that depend on the same
/// definition, you should consider creating a separate crate for the external program definition
/// and reusing it in your programs.
///
/// # Off-chain usage
///
/// When using in off-chain environments, for example via `anchor_client`, you must have
/// `anchor_lang` in scope:
///
/// ```ignore
/// use anchor_client::anchor_lang;
///
/// # fn main() {}
/// ```
///
/// # Example
///
/// A full on-chain CPI usage example can be found [here].
///
/// [here]: https://github.com/coral-xyz/anchor/tree/v0.32.1/tests/declare-program
#[proc_macro]
pub fn declare_program(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
parse_macro_input!(input as DeclareProgram)
.to_token_stream()
.into()
}
/// This attribute is used to override the Anchor defaults of program instructions.
///
/// # Arguments
///
/// - `discriminator`: Override the default 8-byte discriminator
///
/// **Usage:** `discriminator = <CONST_EXPR>`
///
/// All constant expressions are supported.
///
/// **Examples:**
///
/// - `discriminator = 1` (shortcut for `[1]`)
/// - `discriminator = [1, 2, 3, 4]`
/// - `discriminator = b"hi"`
/// - `discriminator = MY_DISC`
/// - `discriminator = get_disc(...)`
///
/// # Example
///
/// ```ignore
/// use anchor_lang::prelude::*;
///
/// declare_id!("CustomDiscriminator111111111111111111111111");
///
/// #[program]
/// pub mod custom_discriminator {
/// use super::*;
///
/// #[instruction(discriminator = [1, 2, 3, 4])]
/// pub fn my_ix(_ctx: Context<MyIx>) -> Result<()> {
/// Ok(())
/// }
/// }
///
/// #[derive(Accounts)]
/// pub struct MyIx<'info> {
/// pub signer: Signer<'info>,
/// }
///
/// # fn main() {}
/// ```
#[proc_macro_attribute]
pub fn instruction(
_args: proc_macro::TokenStream,
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
// This macro itself is a no-op, but the `#[program]` macro will detect this attribute and use
// the arguments to transform the instruction.
input
}