lib.rs 22 KB

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