lib.rs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. use codegen::accounts as accounts_codegen;
  2. use codegen::program as program_codegen;
  3. use parser::accounts as accounts_parser;
  4. use parser::program as program_parser;
  5. use proc_macro2::{Span, TokenStream};
  6. use quote::quote;
  7. use quote::ToTokens;
  8. use std::ops::Deref;
  9. use syn::ext::IdentExt;
  10. use syn::parse::{Error as ParseError, Parse, ParseStream, Result as ParseResult};
  11. use syn::punctuated::Punctuated;
  12. use syn::spanned::Spanned;
  13. use syn::token::Comma;
  14. use syn::{
  15. Expr, Generics, Ident, ImplItemMethod, ItemEnum, ItemFn, ItemImpl, ItemMod, ItemStruct, LitInt,
  16. LitStr, PatType, Token, TypePath,
  17. };
  18. pub mod codegen;
  19. #[cfg(feature = "hash")]
  20. pub mod hash;
  21. #[cfg(not(feature = "hash"))]
  22. pub(crate) mod hash;
  23. #[cfg(feature = "idl")]
  24. pub mod idl;
  25. pub mod parser;
  26. #[derive(Debug)]
  27. pub struct Program {
  28. pub state: Option<State>,
  29. pub ixs: Vec<Ix>,
  30. pub name: Ident,
  31. pub program_mod: ItemMod,
  32. pub fallback_fn: Option<FallbackFn>,
  33. }
  34. impl Parse for Program {
  35. fn parse(input: ParseStream) -> ParseResult<Self> {
  36. let program_mod = <ItemMod as Parse>::parse(input)?;
  37. program_parser::parse(program_mod)
  38. }
  39. }
  40. impl From<&Program> for TokenStream {
  41. fn from(program: &Program) -> Self {
  42. program_codegen::generate(program)
  43. }
  44. }
  45. impl ToTokens for Program {
  46. fn to_tokens(&self, tokens: &mut TokenStream) {
  47. tokens.extend::<TokenStream>(self.into());
  48. }
  49. }
  50. #[derive(Debug)]
  51. pub struct State {
  52. pub name: String,
  53. pub strct: ItemStruct,
  54. pub ctor_and_anchor: Option<(ImplItemMethod, Ident)>,
  55. pub impl_block_and_methods: Option<(ItemImpl, Vec<StateIx>)>,
  56. pub interfaces: Option<Vec<StateInterface>>,
  57. pub is_zero_copy: bool,
  58. }
  59. #[derive(Debug)]
  60. pub struct StateIx {
  61. pub raw_method: ImplItemMethod,
  62. pub ident: Ident,
  63. pub args: Vec<IxArg>,
  64. pub anchor_ident: Ident,
  65. // True if there exists a &self on the method.
  66. pub has_receiver: bool,
  67. }
  68. #[derive(Debug)]
  69. pub struct StateInterface {
  70. pub trait_name: String,
  71. pub methods: Vec<StateIx>,
  72. }
  73. #[derive(Debug)]
  74. pub struct Ix {
  75. pub raw_method: ItemFn,
  76. pub ident: Ident,
  77. pub args: Vec<IxArg>,
  78. // The ident for the struct deriving Accounts.
  79. pub anchor_ident: Ident,
  80. }
  81. #[derive(Debug)]
  82. pub struct IxArg {
  83. pub name: Ident,
  84. pub raw_arg: PatType,
  85. }
  86. #[derive(Debug)]
  87. pub struct FallbackFn {
  88. raw_method: ItemFn,
  89. }
  90. #[derive(Debug)]
  91. pub struct AccountsStruct {
  92. // Name of the accounts struct.
  93. pub ident: Ident,
  94. // Generics + lifetimes on the accounts struct.
  95. pub generics: Generics,
  96. // Fields on the accounts struct.
  97. pub fields: Vec<AccountField>,
  98. // Instruction data api expression.
  99. instruction_api: Option<Punctuated<Expr, Comma>>,
  100. }
  101. impl Parse for AccountsStruct {
  102. fn parse(input: ParseStream) -> ParseResult<Self> {
  103. let strct = <ItemStruct as Parse>::parse(input)?;
  104. accounts_parser::parse(&strct)
  105. }
  106. }
  107. impl From<&AccountsStruct> for TokenStream {
  108. fn from(accounts: &AccountsStruct) -> Self {
  109. accounts_codegen::generate(accounts)
  110. }
  111. }
  112. impl ToTokens for AccountsStruct {
  113. fn to_tokens(&self, tokens: &mut TokenStream) {
  114. tokens.extend::<TokenStream>(self.into());
  115. }
  116. }
  117. impl AccountsStruct {
  118. pub fn new(
  119. strct: ItemStruct,
  120. fields: Vec<AccountField>,
  121. instruction_api: Option<Punctuated<Expr, Comma>>,
  122. ) -> Self {
  123. let ident = strct.ident.clone();
  124. let generics = strct.generics;
  125. Self {
  126. ident,
  127. generics,
  128. fields,
  129. instruction_api,
  130. }
  131. }
  132. }
  133. #[allow(clippy::large_enum_variant)]
  134. #[derive(Debug)]
  135. pub enum AccountField {
  136. Field(Field),
  137. CompositeField(CompositeField),
  138. }
  139. #[derive(Debug)]
  140. pub struct Field {
  141. pub ident: Ident,
  142. pub constraints: ConstraintGroup,
  143. pub instruction_constraints: ConstraintGroup,
  144. pub ty: Ty,
  145. }
  146. impl Field {
  147. pub fn typed_ident(&self) -> proc_macro2::TokenStream {
  148. let name = &self.ident;
  149. let ty_decl = self.ty_decl();
  150. quote! {
  151. #name: #ty_decl
  152. }
  153. }
  154. pub fn ty_decl(&self) -> proc_macro2::TokenStream {
  155. let account_ty = self.account_ty();
  156. let container_ty = self.container_ty();
  157. match &self.ty {
  158. Ty::AccountInfo => quote! {
  159. AccountInfo
  160. },
  161. Ty::UncheckedAccount => quote! {
  162. UncheckedAccount
  163. },
  164. Ty::Signer => quote! {
  165. Signer
  166. },
  167. Ty::Account(AccountTy { boxed, .. }) => {
  168. if *boxed {
  169. quote! {
  170. Box<#container_ty<#account_ty>>
  171. }
  172. } else {
  173. quote! {
  174. #container_ty<#account_ty>
  175. }
  176. }
  177. }
  178. Ty::Sysvar(ty) => {
  179. let account = match ty {
  180. SysvarTy::Clock => quote! {Clock},
  181. SysvarTy::Rent => quote! {Rent},
  182. SysvarTy::EpochSchedule => quote! {EpochSchedule},
  183. SysvarTy::Fees => quote! {Fees},
  184. SysvarTy::RecentBlockhashes => quote! {RecentBlockhashes},
  185. SysvarTy::SlotHashes => quote! {SlotHashes},
  186. SysvarTy::SlotHistory => quote! {SlotHistory},
  187. SysvarTy::StakeHistory => quote! {StakeHistory},
  188. SysvarTy::Instructions => quote! {Instructions},
  189. SysvarTy::Rewards => quote! {Rewards},
  190. };
  191. quote! {
  192. Sysvar<#account>
  193. }
  194. }
  195. _ => quote! {
  196. #container_ty<#account_ty>
  197. },
  198. }
  199. }
  200. // TODO: remove the option once `CpiAccount` is completely removed (not
  201. // just deprecated).
  202. pub fn from_account_info_unchecked(&self, kind: Option<&InitKind>) -> proc_macro2::TokenStream {
  203. let field = &self.ident;
  204. let container_ty = self.container_ty();
  205. match &self.ty {
  206. Ty::AccountInfo => quote! { #field.to_account_info() },
  207. Ty::UncheckedAccount => {
  208. quote! { UncheckedAccount::try_from(#field.to_account_info()) }
  209. }
  210. Ty::Account(AccountTy { boxed, .. }) => {
  211. if *boxed {
  212. quote! {
  213. Box::new(#container_ty::try_from_unchecked(
  214. &#field,
  215. )?)
  216. }
  217. } else {
  218. quote! {
  219. #container_ty::try_from_unchecked(
  220. &#field,
  221. )?
  222. }
  223. }
  224. }
  225. Ty::CpiAccount(_) => {
  226. quote! {
  227. #container_ty::try_from_unchecked(
  228. &#field,
  229. )?
  230. }
  231. }
  232. _ => {
  233. let owner_addr = match &kind {
  234. None => quote! { program_id },
  235. Some(InitKind::Program { .. }) => quote! {
  236. program_id
  237. },
  238. _ => quote! {
  239. &anchor_spl::token::ID
  240. },
  241. };
  242. quote! {
  243. #container_ty::try_from_unchecked(
  244. #owner_addr,
  245. &#field,
  246. )?
  247. }
  248. }
  249. }
  250. }
  251. pub fn container_ty(&self) -> proc_macro2::TokenStream {
  252. match &self.ty {
  253. Ty::ProgramAccount(_) => quote! {
  254. anchor_lang::ProgramAccount
  255. },
  256. Ty::Account(_) => quote! {
  257. anchor_lang::Account
  258. },
  259. Ty::AccountLoader(_) => quote! {
  260. anchor_lang::AccountLoader
  261. },
  262. Ty::Loader(_) => quote! {
  263. anchor_lang::Loader
  264. },
  265. Ty::CpiAccount(_) => quote! {
  266. anchor_lang::CpiAccount
  267. },
  268. Ty::Sysvar(_) => quote! { anchor_lang::Sysvar },
  269. Ty::CpiState(_) => quote! { anchor_lang::CpiState },
  270. Ty::ProgramState(_) => quote! { anchor_lang::ProgramState },
  271. Ty::Program(_) => quote! { anchor_lang::Program },
  272. Ty::AccountInfo => quote! {},
  273. Ty::UncheckedAccount => quote! {},
  274. Ty::Signer => quote! {},
  275. }
  276. }
  277. // Returns the inner account struct type.
  278. pub fn account_ty(&self) -> proc_macro2::TokenStream {
  279. match &self.ty {
  280. Ty::AccountInfo => quote! {
  281. AccountInfo
  282. },
  283. Ty::UncheckedAccount => quote! {
  284. UncheckedAccount
  285. },
  286. Ty::Signer => quote! {
  287. Signer
  288. },
  289. Ty::ProgramAccount(ty) => {
  290. let ident = &ty.account_type_path;
  291. quote! {
  292. #ident
  293. }
  294. }
  295. Ty::Account(ty) => {
  296. let ident = &ty.account_type_path;
  297. quote! {
  298. #ident
  299. }
  300. }
  301. Ty::AccountLoader(ty) => {
  302. let ident = &ty.account_type_path;
  303. quote! {
  304. #ident
  305. }
  306. }
  307. Ty::Loader(ty) => {
  308. let ident = &ty.account_type_path;
  309. quote! {
  310. #ident
  311. }
  312. }
  313. Ty::CpiAccount(ty) => {
  314. let ident = &ty.account_type_path;
  315. quote! {
  316. #ident
  317. }
  318. }
  319. Ty::ProgramState(ty) => {
  320. let account = &ty.account_type_path;
  321. quote! {
  322. #account
  323. }
  324. }
  325. Ty::CpiState(ty) => {
  326. let account = &ty.account_type_path;
  327. quote! {
  328. #account
  329. }
  330. }
  331. Ty::Sysvar(ty) => match ty {
  332. SysvarTy::Clock => quote! {Clock},
  333. SysvarTy::Rent => quote! {Rent},
  334. SysvarTy::EpochSchedule => quote! {EpochSchedule},
  335. SysvarTy::Fees => quote! {Fees},
  336. SysvarTy::RecentBlockhashes => quote! {RecentBlockhashes},
  337. SysvarTy::SlotHashes => quote! {SlotHashes},
  338. SysvarTy::SlotHistory => quote! {SlotHistory},
  339. SysvarTy::StakeHistory => quote! {StakeHistory},
  340. SysvarTy::Instructions => quote! {Instructions},
  341. SysvarTy::Rewards => quote! {Rewards},
  342. },
  343. Ty::Program(ty) => {
  344. let program = &ty.account_type_path;
  345. quote! {
  346. #program
  347. }
  348. }
  349. }
  350. }
  351. }
  352. #[derive(Debug)]
  353. pub struct CompositeField {
  354. pub ident: Ident,
  355. pub constraints: ConstraintGroup,
  356. pub instruction_constraints: ConstraintGroup,
  357. pub symbol: String,
  358. pub raw_field: syn::Field,
  359. }
  360. // A type of an account field.
  361. #[derive(Debug, PartialEq)]
  362. pub enum Ty {
  363. AccountInfo,
  364. UncheckedAccount,
  365. ProgramState(ProgramStateTy),
  366. CpiState(CpiStateTy),
  367. ProgramAccount(ProgramAccountTy),
  368. Loader(LoaderTy),
  369. AccountLoader(LoaderAccountTy),
  370. CpiAccount(CpiAccountTy),
  371. Sysvar(SysvarTy),
  372. Account(AccountTy),
  373. Program(ProgramTy),
  374. Signer,
  375. }
  376. #[derive(Debug, PartialEq)]
  377. pub enum SysvarTy {
  378. Clock,
  379. Rent,
  380. EpochSchedule,
  381. Fees,
  382. RecentBlockhashes,
  383. SlotHashes,
  384. SlotHistory,
  385. StakeHistory,
  386. Instructions,
  387. Rewards,
  388. }
  389. #[derive(Debug, PartialEq)]
  390. pub struct ProgramStateTy {
  391. pub account_type_path: TypePath,
  392. }
  393. #[derive(Debug, PartialEq)]
  394. pub struct CpiStateTy {
  395. pub account_type_path: TypePath,
  396. }
  397. #[derive(Debug, PartialEq)]
  398. pub struct ProgramAccountTy {
  399. // The struct type of the account.
  400. pub account_type_path: TypePath,
  401. }
  402. #[derive(Debug, PartialEq)]
  403. pub struct CpiAccountTy {
  404. // The struct type of the account.
  405. pub account_type_path: TypePath,
  406. }
  407. #[derive(Debug, PartialEq)]
  408. pub struct LoaderAccountTy {
  409. // The struct type of the account.
  410. pub account_type_path: TypePath,
  411. }
  412. #[derive(Debug, PartialEq)]
  413. pub struct LoaderTy {
  414. // The struct type of the account.
  415. pub account_type_path: TypePath,
  416. }
  417. #[derive(Debug, PartialEq)]
  418. pub struct AccountTy {
  419. // The struct type of the account.
  420. pub account_type_path: TypePath,
  421. // True if the account has been boxed via `Box<T>`.
  422. pub boxed: bool,
  423. }
  424. #[derive(Debug, PartialEq)]
  425. pub struct ProgramTy {
  426. // The struct type of the account.
  427. pub account_type_path: TypePath,
  428. }
  429. #[derive(Debug)]
  430. pub struct Error {
  431. pub name: String,
  432. pub raw_enum: ItemEnum,
  433. pub ident: Ident,
  434. pub codes: Vec<ErrorCode>,
  435. pub args: Option<ErrorArgs>,
  436. }
  437. #[derive(Debug)]
  438. pub struct ErrorArgs {
  439. pub offset: LitInt,
  440. }
  441. impl Parse for ErrorArgs {
  442. fn parse(stream: ParseStream) -> ParseResult<Self> {
  443. let offset_span = stream.span();
  444. let offset = stream.call(Ident::parse_any)?;
  445. if offset.to_string().as_str() != "offset" {
  446. return Err(ParseError::new(offset_span, "expected keyword offset"));
  447. }
  448. stream.parse::<Token![=]>()?;
  449. Ok(ErrorArgs {
  450. offset: stream.parse()?,
  451. })
  452. }
  453. }
  454. #[derive(Debug)]
  455. pub struct ErrorCode {
  456. pub id: u32,
  457. pub ident: Ident,
  458. pub msg: Option<String>,
  459. }
  460. // All well formed constraints on a single `Accounts` field.
  461. #[derive(Debug, Default, Clone)]
  462. pub struct ConstraintGroup {
  463. init: Option<ConstraintInitGroup>,
  464. zeroed: Option<ConstraintZeroed>,
  465. mutable: Option<ConstraintMut>,
  466. signer: Option<ConstraintSigner>,
  467. owner: Option<ConstraintOwner>,
  468. rent_exempt: Option<ConstraintRentExempt>,
  469. seeds: Option<ConstraintSeedsGroup>,
  470. executable: Option<ConstraintExecutable>,
  471. state: Option<ConstraintState>,
  472. has_one: Vec<ConstraintHasOne>,
  473. literal: Vec<ConstraintLiteral>,
  474. raw: Vec<ConstraintRaw>,
  475. close: Option<ConstraintClose>,
  476. address: Option<ConstraintAddress>,
  477. associated_token: Option<ConstraintAssociatedToken>,
  478. }
  479. impl ConstraintGroup {
  480. pub fn is_zeroed(&self) -> bool {
  481. self.zeroed.is_some()
  482. }
  483. pub fn is_mutable(&self) -> bool {
  484. self.mutable.is_some()
  485. }
  486. pub fn is_signer(&self) -> bool {
  487. self.signer.is_some()
  488. }
  489. pub fn is_close(&self) -> bool {
  490. self.close.is_some()
  491. }
  492. }
  493. // A single account constraint *after* merging all tokens into a well formed
  494. // constraint. Some constraints like "seeds" are defined by multiple
  495. // tokens, so a merging phase is required.
  496. #[allow(clippy::large_enum_variant)]
  497. #[derive(Debug)]
  498. pub enum Constraint {
  499. Init(ConstraintInitGroup),
  500. Zeroed(ConstraintZeroed),
  501. Mut(ConstraintMut),
  502. Signer(ConstraintSigner),
  503. HasOne(ConstraintHasOne),
  504. Literal(ConstraintLiteral),
  505. Raw(ConstraintRaw),
  506. Owner(ConstraintOwner),
  507. RentExempt(ConstraintRentExempt),
  508. Seeds(ConstraintSeedsGroup),
  509. AssociatedToken(ConstraintAssociatedToken),
  510. Executable(ConstraintExecutable),
  511. State(ConstraintState),
  512. Close(ConstraintClose),
  513. Address(ConstraintAddress),
  514. }
  515. // Constraint token is a single keyword in a `#[account(<TOKEN>)]` attribute.
  516. #[allow(clippy::large_enum_variant)]
  517. #[derive(Debug)]
  518. pub enum ConstraintToken {
  519. Init(Context<ConstraintInit>),
  520. Zeroed(Context<ConstraintZeroed>),
  521. Mut(Context<ConstraintMut>),
  522. Signer(Context<ConstraintSigner>),
  523. HasOne(Context<ConstraintHasOne>),
  524. Literal(Context<ConstraintLiteral>),
  525. Raw(Context<ConstraintRaw>),
  526. Owner(Context<ConstraintOwner>),
  527. RentExempt(Context<ConstraintRentExempt>),
  528. Seeds(Context<ConstraintSeeds>),
  529. Executable(Context<ConstraintExecutable>),
  530. State(Context<ConstraintState>),
  531. Close(Context<ConstraintClose>),
  532. Payer(Context<ConstraintPayer>),
  533. Space(Context<ConstraintSpace>),
  534. Address(Context<ConstraintAddress>),
  535. TokenMint(Context<ConstraintTokenMint>),
  536. TokenAuthority(Context<ConstraintTokenAuthority>),
  537. AssociatedTokenMint(Context<ConstraintTokenMint>),
  538. AssociatedTokenAuthority(Context<ConstraintTokenAuthority>),
  539. MintAuthority(Context<ConstraintMintAuthority>),
  540. MintFreezeAuthority(Context<ConstraintMintFreezeAuthority>),
  541. MintDecimals(Context<ConstraintMintDecimals>),
  542. Bump(Context<ConstraintTokenBump>),
  543. }
  544. impl Parse for ConstraintToken {
  545. fn parse(stream: ParseStream) -> ParseResult<Self> {
  546. accounts_parser::constraints::parse_token(stream)
  547. }
  548. }
  549. #[derive(Debug, Clone)]
  550. pub struct ConstraintInit {}
  551. #[derive(Debug, Clone)]
  552. pub struct ConstraintZeroed {}
  553. #[derive(Debug, Clone)]
  554. pub struct ConstraintMut {}
  555. #[derive(Debug, Clone)]
  556. pub struct ConstraintSigner {}
  557. #[derive(Debug, Clone)]
  558. pub struct ConstraintHasOne {
  559. pub join_target: Expr,
  560. }
  561. #[derive(Debug, Clone)]
  562. pub struct ConstraintLiteral {
  563. pub lit: LitStr,
  564. }
  565. #[derive(Debug, Clone)]
  566. pub struct ConstraintRaw {
  567. pub raw: Expr,
  568. }
  569. #[derive(Debug, Clone)]
  570. pub struct ConstraintOwner {
  571. pub owner_address: Expr,
  572. }
  573. #[derive(Debug, Clone)]
  574. pub struct ConstraintAddress {
  575. pub address: Expr,
  576. }
  577. #[derive(Debug, Clone)]
  578. pub enum ConstraintRentExempt {
  579. Enforce,
  580. Skip,
  581. }
  582. #[derive(Debug, Clone)]
  583. pub struct ConstraintInitGroup {
  584. pub seeds: Option<ConstraintSeedsGroup>,
  585. pub payer: Option<Expr>,
  586. pub space: Option<Expr>,
  587. pub kind: InitKind,
  588. }
  589. #[derive(Debug, Clone)]
  590. pub struct ConstraintSeedsGroup {
  591. pub is_init: bool,
  592. pub seeds: Punctuated<Expr, Token![,]>,
  593. pub bump: Option<Expr>, // None => bump was given without a target.
  594. }
  595. #[derive(Debug, Clone)]
  596. pub struct ConstraintSeeds {
  597. pub seeds: Punctuated<Expr, Token![,]>,
  598. }
  599. #[derive(Debug, Clone)]
  600. pub struct ConstraintExecutable {}
  601. #[derive(Debug, Clone)]
  602. pub struct ConstraintState {
  603. pub program_target: Ident,
  604. }
  605. #[derive(Debug, Clone)]
  606. pub struct ConstraintPayer {
  607. pub target: Expr,
  608. }
  609. #[derive(Debug, Clone)]
  610. pub struct ConstraintSpace {
  611. pub space: Expr,
  612. }
  613. #[derive(Debug, Clone)]
  614. #[allow(clippy::large_enum_variant)]
  615. pub enum InitKind {
  616. Program {
  617. owner: Option<Expr>,
  618. },
  619. // Owner for token and mint represents the authority. Not to be confused
  620. // with the owner of the AccountInfo.
  621. Token {
  622. owner: Expr,
  623. mint: Expr,
  624. },
  625. AssociatedToken {
  626. owner: Expr,
  627. mint: Expr,
  628. },
  629. Mint {
  630. owner: Expr,
  631. freeze_authority: Option<Expr>,
  632. decimals: Expr,
  633. },
  634. }
  635. #[derive(Debug, Clone)]
  636. pub struct ConstraintClose {
  637. pub sol_dest: Ident,
  638. }
  639. #[derive(Debug, Clone)]
  640. pub struct ConstraintTokenMint {
  641. mint: Expr,
  642. }
  643. #[derive(Debug, Clone)]
  644. pub struct ConstraintTokenAuthority {
  645. auth: Expr,
  646. }
  647. #[derive(Debug, Clone)]
  648. pub struct ConstraintMintAuthority {
  649. mint_auth: Expr,
  650. }
  651. #[derive(Debug, Clone)]
  652. pub struct ConstraintMintFreezeAuthority {
  653. mint_freeze_auth: Expr,
  654. }
  655. #[derive(Debug, Clone)]
  656. pub struct ConstraintMintDecimals {
  657. decimals: Expr,
  658. }
  659. #[derive(Debug, Clone)]
  660. pub struct ConstraintTokenBump {
  661. bump: Option<Expr>,
  662. }
  663. #[derive(Debug, Clone)]
  664. pub struct ConstraintAssociatedToken {
  665. pub wallet: Expr,
  666. pub mint: Expr,
  667. }
  668. // Syntaxt context object for preserving metadata about the inner item.
  669. #[derive(Debug, Clone)]
  670. pub struct Context<T> {
  671. span: Span,
  672. inner: T,
  673. }
  674. impl<T> Context<T> {
  675. pub fn new(span: Span, inner: T) -> Self {
  676. Self { span, inner }
  677. }
  678. pub fn into_inner(self) -> T {
  679. self.inner
  680. }
  681. }
  682. impl<T> Deref for Context<T> {
  683. type Target = T;
  684. fn deref(&self) -> &Self::Target {
  685. &self.inner
  686. }
  687. }
  688. impl<T> Spanned for Context<T> {
  689. fn span(&self) -> Span {
  690. self.span
  691. }
  692. }