lib.rs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  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. }
  189. impl Field {
  190. pub fn typed_ident(&self) -> proc_macro2::TokenStream {
  191. let name = &self.ident;
  192. let ty_decl = self.ty_decl();
  193. quote! {
  194. #name: #ty_decl
  195. }
  196. }
  197. pub fn ty_decl(&self) -> proc_macro2::TokenStream {
  198. let account_ty = self.account_ty();
  199. let container_ty = self.container_ty();
  200. match &self.ty {
  201. Ty::AccountInfo => quote! {
  202. AccountInfo
  203. },
  204. Ty::UncheckedAccount => quote! {
  205. UncheckedAccount
  206. },
  207. Ty::Signer => quote! {
  208. Signer
  209. },
  210. Ty::ProgramData => quote! {
  211. ProgramData
  212. },
  213. Ty::SystemAccount => quote! {
  214. SystemAccount
  215. },
  216. Ty::Account(AccountTy { boxed, .. }) => {
  217. if *boxed {
  218. quote! {
  219. Box<#container_ty<#account_ty>>
  220. }
  221. } else {
  222. quote! {
  223. #container_ty<#account_ty>
  224. }
  225. }
  226. }
  227. Ty::Sysvar(ty) => {
  228. let account = match ty {
  229. SysvarTy::Clock => quote! {Clock},
  230. SysvarTy::Rent => quote! {Rent},
  231. SysvarTy::EpochSchedule => quote! {EpochSchedule},
  232. SysvarTy::Fees => quote! {Fees},
  233. SysvarTy::RecentBlockhashes => quote! {RecentBlockhashes},
  234. SysvarTy::SlotHashes => quote! {SlotHashes},
  235. SysvarTy::SlotHistory => quote! {SlotHistory},
  236. SysvarTy::StakeHistory => quote! {StakeHistory},
  237. SysvarTy::Instructions => quote! {Instructions},
  238. SysvarTy::Rewards => quote! {Rewards},
  239. };
  240. quote! {
  241. Sysvar<#account>
  242. }
  243. }
  244. _ => quote! {
  245. #container_ty<#account_ty>
  246. },
  247. }
  248. }
  249. // TODO: remove the option once `CpiAccount` is completely removed (not
  250. // just deprecated).
  251. pub fn from_account_info_unchecked(&self, kind: Option<&InitKind>) -> proc_macro2::TokenStream {
  252. let field = &self.ident;
  253. let container_ty = self.container_ty();
  254. match &self.ty {
  255. Ty::AccountInfo => quote! { #field.to_account_info() },
  256. Ty::UncheckedAccount => {
  257. quote! { UncheckedAccount::try_from(#field.to_account_info()) }
  258. }
  259. Ty::Account(AccountTy { boxed, .. }) => {
  260. if *boxed {
  261. quote! {
  262. Box::new(#container_ty::try_from_unchecked(
  263. &#field,
  264. )?)
  265. }
  266. } else {
  267. quote! {
  268. #container_ty::try_from_unchecked(
  269. &#field,
  270. )?
  271. }
  272. }
  273. }
  274. Ty::CpiAccount(_) => {
  275. quote! {
  276. #container_ty::try_from_unchecked(
  277. &#field,
  278. )?
  279. }
  280. }
  281. _ => {
  282. let owner_addr = match &kind {
  283. None => quote! { program_id },
  284. Some(InitKind::Program { .. }) => quote! {
  285. program_id
  286. },
  287. _ => quote! {
  288. &anchor_spl::token::ID
  289. },
  290. };
  291. quote! {
  292. #container_ty::try_from_unchecked(
  293. #owner_addr,
  294. &#field,
  295. )?
  296. }
  297. }
  298. }
  299. }
  300. pub fn container_ty(&self) -> proc_macro2::TokenStream {
  301. match &self.ty {
  302. Ty::ProgramAccount(_) => quote! {
  303. anchor_lang::accounts::program_account::ProgramAccount
  304. },
  305. Ty::Account(_) => quote! {
  306. anchor_lang::accounts::account::Account
  307. },
  308. Ty::AccountLoader(_) => quote! {
  309. anchor_lang::accounts::account_loader::AccountLoader
  310. },
  311. Ty::Loader(_) => quote! {
  312. anchor_lang::accounts::loader::Loader
  313. },
  314. Ty::CpiAccount(_) => quote! {
  315. anchor_lang::accounts::cpi_account::CpiAccount
  316. },
  317. Ty::Sysvar(_) => quote! { anchor_lang::accounts::sysvar::Sysvar },
  318. Ty::CpiState(_) => quote! { anchor_lang::accounts::cpi_state::CpiState },
  319. Ty::ProgramState(_) => quote! { anchor_lang::accounts::state::ProgramState },
  320. Ty::Program(_) => quote! { anchor_lang::accounts::program::Program },
  321. Ty::AccountInfo => quote! {},
  322. Ty::UncheckedAccount => quote! {},
  323. Ty::Signer => quote! {},
  324. Ty::SystemAccount => quote! {},
  325. Ty::ProgramData => quote! {},
  326. }
  327. }
  328. // Returns the inner account struct type.
  329. pub fn account_ty(&self) -> proc_macro2::TokenStream {
  330. match &self.ty {
  331. Ty::AccountInfo => quote! {
  332. AccountInfo
  333. },
  334. Ty::UncheckedAccount => quote! {
  335. UncheckedAccount
  336. },
  337. Ty::Signer => quote! {
  338. Signer
  339. },
  340. Ty::SystemAccount => quote! {
  341. SystemAccount
  342. },
  343. Ty::ProgramData => quote! {
  344. ProgramData
  345. },
  346. Ty::ProgramAccount(ty) => {
  347. let ident = &ty.account_type_path;
  348. quote! {
  349. #ident
  350. }
  351. }
  352. Ty::Account(ty) => {
  353. let ident = &ty.account_type_path;
  354. quote! {
  355. #ident
  356. }
  357. }
  358. Ty::AccountLoader(ty) => {
  359. let ident = &ty.account_type_path;
  360. quote! {
  361. #ident
  362. }
  363. }
  364. Ty::Loader(ty) => {
  365. let ident = &ty.account_type_path;
  366. quote! {
  367. #ident
  368. }
  369. }
  370. Ty::CpiAccount(ty) => {
  371. let ident = &ty.account_type_path;
  372. quote! {
  373. #ident
  374. }
  375. }
  376. Ty::ProgramState(ty) => {
  377. let account = &ty.account_type_path;
  378. quote! {
  379. #account
  380. }
  381. }
  382. Ty::CpiState(ty) => {
  383. let account = &ty.account_type_path;
  384. quote! {
  385. #account
  386. }
  387. }
  388. Ty::Sysvar(ty) => match ty {
  389. SysvarTy::Clock => quote! {Clock},
  390. SysvarTy::Rent => quote! {Rent},
  391. SysvarTy::EpochSchedule => quote! {EpochSchedule},
  392. SysvarTy::Fees => quote! {Fees},
  393. SysvarTy::RecentBlockhashes => quote! {RecentBlockhashes},
  394. SysvarTy::SlotHashes => quote! {SlotHashes},
  395. SysvarTy::SlotHistory => quote! {SlotHistory},
  396. SysvarTy::StakeHistory => quote! {StakeHistory},
  397. SysvarTy::Instructions => quote! {Instructions},
  398. SysvarTy::Rewards => quote! {Rewards},
  399. },
  400. Ty::Program(ty) => {
  401. let program = &ty.account_type_path;
  402. quote! {
  403. #program
  404. }
  405. }
  406. }
  407. }
  408. }
  409. #[derive(Debug)]
  410. pub struct CompositeField {
  411. pub ident: Ident,
  412. pub constraints: ConstraintGroup,
  413. pub instruction_constraints: ConstraintGroup,
  414. pub symbol: String,
  415. pub raw_field: syn::Field,
  416. }
  417. // A type of an account field.
  418. #[derive(Debug, PartialEq)]
  419. pub enum Ty {
  420. AccountInfo,
  421. UncheckedAccount,
  422. ProgramState(ProgramStateTy),
  423. CpiState(CpiStateTy),
  424. ProgramAccount(ProgramAccountTy),
  425. Loader(LoaderTy),
  426. AccountLoader(AccountLoaderTy),
  427. CpiAccount(CpiAccountTy),
  428. Sysvar(SysvarTy),
  429. Account(AccountTy),
  430. Program(ProgramTy),
  431. Signer,
  432. SystemAccount,
  433. ProgramData,
  434. }
  435. #[derive(Debug, PartialEq)]
  436. pub enum SysvarTy {
  437. Clock,
  438. Rent,
  439. EpochSchedule,
  440. Fees,
  441. RecentBlockhashes,
  442. SlotHashes,
  443. SlotHistory,
  444. StakeHistory,
  445. Instructions,
  446. Rewards,
  447. }
  448. #[derive(Debug, PartialEq)]
  449. pub struct ProgramStateTy {
  450. pub account_type_path: TypePath,
  451. }
  452. #[derive(Debug, PartialEq)]
  453. pub struct CpiStateTy {
  454. pub account_type_path: TypePath,
  455. }
  456. #[derive(Debug, PartialEq)]
  457. pub struct ProgramAccountTy {
  458. // The struct type of the account.
  459. pub account_type_path: TypePath,
  460. }
  461. #[derive(Debug, PartialEq)]
  462. pub struct CpiAccountTy {
  463. // The struct type of the account.
  464. pub account_type_path: TypePath,
  465. }
  466. #[derive(Debug, PartialEq)]
  467. pub struct AccountLoaderTy {
  468. // The struct type of the account.
  469. pub account_type_path: TypePath,
  470. }
  471. #[derive(Debug, PartialEq)]
  472. pub struct LoaderTy {
  473. // The struct type of the account.
  474. pub account_type_path: TypePath,
  475. }
  476. #[derive(Debug, PartialEq)]
  477. pub struct AccountTy {
  478. // The struct type of the account.
  479. pub account_type_path: TypePath,
  480. // True if the account has been boxed via `Box<T>`.
  481. pub boxed: bool,
  482. }
  483. #[derive(Debug, PartialEq)]
  484. pub struct ProgramTy {
  485. // The struct type of the account.
  486. pub account_type_path: TypePath,
  487. }
  488. #[derive(Debug)]
  489. pub struct Error {
  490. pub name: String,
  491. pub raw_enum: ItemEnum,
  492. pub ident: Ident,
  493. pub codes: Vec<ErrorCode>,
  494. pub args: Option<ErrorArgs>,
  495. }
  496. #[derive(Debug)]
  497. pub struct ErrorArgs {
  498. pub offset: LitInt,
  499. }
  500. impl Parse for ErrorArgs {
  501. fn parse(stream: ParseStream) -> ParseResult<Self> {
  502. let offset_span = stream.span();
  503. let offset = stream.call(Ident::parse_any)?;
  504. if offset.to_string().as_str() != "offset" {
  505. return Err(ParseError::new(offset_span, "expected keyword offset"));
  506. }
  507. stream.parse::<Token![=]>()?;
  508. Ok(ErrorArgs {
  509. offset: stream.parse()?,
  510. })
  511. }
  512. }
  513. #[derive(Debug)]
  514. pub struct ErrorCode {
  515. pub id: u32,
  516. pub ident: Ident,
  517. pub msg: Option<String>,
  518. }
  519. // All well formed constraints on a single `Accounts` field.
  520. #[derive(Debug, Default, Clone)]
  521. pub struct ConstraintGroup {
  522. init: Option<ConstraintInitGroup>,
  523. zeroed: Option<ConstraintZeroed>,
  524. mutable: Option<ConstraintMut>,
  525. signer: Option<ConstraintSigner>,
  526. owner: Option<ConstraintOwner>,
  527. rent_exempt: Option<ConstraintRentExempt>,
  528. seeds: Option<ConstraintSeedsGroup>,
  529. executable: Option<ConstraintExecutable>,
  530. state: Option<ConstraintState>,
  531. has_one: Vec<ConstraintHasOne>,
  532. literal: Vec<ConstraintLiteral>,
  533. raw: Vec<ConstraintRaw>,
  534. close: Option<ConstraintClose>,
  535. address: Option<ConstraintAddress>,
  536. associated_token: Option<ConstraintAssociatedToken>,
  537. }
  538. impl ConstraintGroup {
  539. pub fn is_zeroed(&self) -> bool {
  540. self.zeroed.is_some()
  541. }
  542. pub fn is_mutable(&self) -> bool {
  543. self.mutable.is_some()
  544. }
  545. pub fn is_signer(&self) -> bool {
  546. self.signer.is_some()
  547. }
  548. pub fn is_close(&self) -> bool {
  549. self.close.is_some()
  550. }
  551. }
  552. // A single account constraint *after* merging all tokens into a well formed
  553. // constraint. Some constraints like "seeds" are defined by multiple
  554. // tokens, so a merging phase is required.
  555. #[allow(clippy::large_enum_variant)]
  556. #[derive(Debug)]
  557. pub enum Constraint {
  558. Init(ConstraintInitGroup),
  559. Zeroed(ConstraintZeroed),
  560. Mut(ConstraintMut),
  561. Signer(ConstraintSigner),
  562. HasOne(ConstraintHasOne),
  563. Literal(ConstraintLiteral),
  564. Raw(ConstraintRaw),
  565. Owner(ConstraintOwner),
  566. RentExempt(ConstraintRentExempt),
  567. Seeds(ConstraintSeedsGroup),
  568. AssociatedToken(ConstraintAssociatedToken),
  569. Executable(ConstraintExecutable),
  570. State(ConstraintState),
  571. Close(ConstraintClose),
  572. Address(ConstraintAddress),
  573. }
  574. // Constraint token is a single keyword in a `#[account(<TOKEN>)]` attribute.
  575. #[allow(clippy::large_enum_variant)]
  576. #[derive(Debug)]
  577. pub enum ConstraintToken {
  578. Init(Context<ConstraintInit>),
  579. Zeroed(Context<ConstraintZeroed>),
  580. Mut(Context<ConstraintMut>),
  581. Signer(Context<ConstraintSigner>),
  582. HasOne(Context<ConstraintHasOne>),
  583. Literal(Context<ConstraintLiteral>),
  584. Raw(Context<ConstraintRaw>),
  585. Owner(Context<ConstraintOwner>),
  586. RentExempt(Context<ConstraintRentExempt>),
  587. Seeds(Context<ConstraintSeeds>),
  588. Executable(Context<ConstraintExecutable>),
  589. State(Context<ConstraintState>),
  590. Close(Context<ConstraintClose>),
  591. Payer(Context<ConstraintPayer>),
  592. Space(Context<ConstraintSpace>),
  593. Address(Context<ConstraintAddress>),
  594. TokenMint(Context<ConstraintTokenMint>),
  595. TokenAuthority(Context<ConstraintTokenAuthority>),
  596. AssociatedTokenMint(Context<ConstraintTokenMint>),
  597. AssociatedTokenAuthority(Context<ConstraintTokenAuthority>),
  598. MintAuthority(Context<ConstraintMintAuthority>),
  599. MintFreezeAuthority(Context<ConstraintMintFreezeAuthority>),
  600. MintDecimals(Context<ConstraintMintDecimals>),
  601. Bump(Context<ConstraintTokenBump>),
  602. ProgramSeed(Context<ConstraintProgramSeed>),
  603. }
  604. impl Parse for ConstraintToken {
  605. fn parse(stream: ParseStream) -> ParseResult<Self> {
  606. accounts_parser::constraints::parse_token(stream)
  607. }
  608. }
  609. #[derive(Debug, Clone)]
  610. pub struct ConstraintInit {
  611. pub if_needed: bool,
  612. }
  613. #[derive(Debug, Clone)]
  614. pub struct ConstraintInitIfNeeded {}
  615. #[derive(Debug, Clone)]
  616. pub struct ConstraintZeroed {}
  617. #[derive(Debug, Clone)]
  618. pub struct ConstraintMut {
  619. pub error: Option<Expr>,
  620. }
  621. #[derive(Debug, Clone)]
  622. pub struct ConstraintSigner {
  623. pub error: Option<Expr>,
  624. }
  625. #[derive(Debug, Clone)]
  626. pub struct ConstraintHasOne {
  627. pub join_target: Expr,
  628. pub error: Option<Expr>,
  629. }
  630. #[derive(Debug, Clone)]
  631. pub struct ConstraintLiteral {
  632. pub lit: LitStr,
  633. }
  634. #[derive(Debug, Clone)]
  635. pub struct ConstraintRaw {
  636. pub raw: Expr,
  637. pub error: Option<Expr>,
  638. }
  639. #[derive(Debug, Clone)]
  640. pub struct ConstraintOwner {
  641. pub owner_address: Expr,
  642. pub error: Option<Expr>,
  643. }
  644. #[derive(Debug, Clone)]
  645. pub struct ConstraintAddress {
  646. pub address: Expr,
  647. pub error: Option<Expr>,
  648. }
  649. #[derive(Debug, Clone)]
  650. pub enum ConstraintRentExempt {
  651. Enforce,
  652. Skip,
  653. }
  654. #[derive(Debug, Clone)]
  655. pub struct ConstraintInitGroup {
  656. pub if_needed: bool,
  657. pub seeds: Option<ConstraintSeedsGroup>,
  658. pub payer: Option<Expr>,
  659. pub space: Option<Expr>,
  660. pub kind: InitKind,
  661. }
  662. #[derive(Debug, Clone)]
  663. pub struct ConstraintSeedsGroup {
  664. pub is_init: bool,
  665. pub seeds: Punctuated<Expr, Token![,]>,
  666. pub bump: Option<Expr>, // None => bump was given without a target.
  667. pub program_seed: Option<Expr>, // None => use the current program's program_id.
  668. }
  669. #[derive(Debug, Clone)]
  670. pub struct ConstraintSeeds {
  671. pub seeds: Punctuated<Expr, Token![,]>,
  672. }
  673. #[derive(Debug, Clone)]
  674. pub struct ConstraintExecutable {}
  675. #[derive(Debug, Clone)]
  676. pub struct ConstraintState {
  677. pub program_target: Ident,
  678. }
  679. #[derive(Debug, Clone)]
  680. pub struct ConstraintPayer {
  681. pub target: Expr,
  682. }
  683. #[derive(Debug, Clone)]
  684. pub struct ConstraintSpace {
  685. pub space: Expr,
  686. }
  687. #[derive(Debug, Clone)]
  688. #[allow(clippy::large_enum_variant)]
  689. pub enum InitKind {
  690. Program {
  691. owner: Option<Expr>,
  692. },
  693. // Owner for token and mint represents the authority. Not to be confused
  694. // with the owner of the AccountInfo.
  695. Token {
  696. owner: Expr,
  697. mint: Expr,
  698. },
  699. AssociatedToken {
  700. owner: Expr,
  701. mint: Expr,
  702. },
  703. Mint {
  704. owner: Expr,
  705. freeze_authority: Option<Expr>,
  706. decimals: Expr,
  707. },
  708. }
  709. #[derive(Debug, Clone)]
  710. pub struct ConstraintClose {
  711. pub sol_dest: Ident,
  712. }
  713. #[derive(Debug, Clone)]
  714. pub struct ConstraintTokenMint {
  715. mint: Expr,
  716. }
  717. #[derive(Debug, Clone)]
  718. pub struct ConstraintTokenAuthority {
  719. auth: Expr,
  720. }
  721. #[derive(Debug, Clone)]
  722. pub struct ConstraintMintAuthority {
  723. mint_auth: Expr,
  724. }
  725. #[derive(Debug, Clone)]
  726. pub struct ConstraintMintFreezeAuthority {
  727. mint_freeze_auth: Expr,
  728. }
  729. #[derive(Debug, Clone)]
  730. pub struct ConstraintMintDecimals {
  731. decimals: Expr,
  732. }
  733. #[derive(Debug, Clone)]
  734. pub struct ConstraintTokenBump {
  735. bump: Option<Expr>,
  736. }
  737. #[derive(Debug, Clone)]
  738. pub struct ConstraintProgramSeed {
  739. program_seed: Expr,
  740. }
  741. #[derive(Debug, Clone)]
  742. pub struct ConstraintAssociatedToken {
  743. pub wallet: Expr,
  744. pub mint: Expr,
  745. }
  746. // Syntaxt context object for preserving metadata about the inner item.
  747. #[derive(Debug, Clone)]
  748. pub struct Context<T> {
  749. span: Span,
  750. inner: T,
  751. }
  752. impl<T> Context<T> {
  753. pub fn new(span: Span, inner: T) -> Self {
  754. Self { span, inner }
  755. }
  756. pub fn into_inner(self) -> T {
  757. self.inner
  758. }
  759. }
  760. impl<T> Deref for Context<T> {
  761. type Target = T;
  762. fn deref(&self) -> &Self::Target {
  763. &self.inner
  764. }
  765. }
  766. impl<T> Spanned for Context<T> {
  767. fn span(&self) -> Span {
  768. self.span
  769. }
  770. }