constraints.rs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. use crate::*;
  2. use syn::ext::IdentExt;
  3. use syn::parse::{Error as ParseError, Parse, ParseStream, Result as ParseResult};
  4. use syn::punctuated::Punctuated;
  5. use syn::spanned::Spanned;
  6. use syn::token::Comma;
  7. use syn::{bracketed, Expr, Ident, LitStr, Token};
  8. pub fn parse(
  9. f: &syn::Field,
  10. f_ty: Option<&Ty>,
  11. has_instruction_api: bool,
  12. ) -> ParseResult<(ConstraintGroup, ConstraintGroup)> {
  13. let mut constraints = ConstraintGroupBuilder::new(f_ty);
  14. for attr in f.attrs.iter().filter(is_account) {
  15. for c in attr.parse_args_with(Punctuated::<ConstraintToken, Comma>::parse_terminated)? {
  16. constraints.add(c)?;
  17. }
  18. }
  19. let account_constraints = constraints.build()?;
  20. let mut constraints = ConstraintGroupBuilder::new(f_ty);
  21. for attr in f.attrs.iter().filter(is_instruction) {
  22. if !has_instruction_api {
  23. return Err(ParseError::new(
  24. attr.span(),
  25. "an instruction api must be declared",
  26. ));
  27. }
  28. for c in attr.parse_args_with(Punctuated::<ConstraintToken, Comma>::parse_terminated)? {
  29. constraints.add(c)?;
  30. }
  31. }
  32. let instruction_constraints = constraints.build()?;
  33. Ok((account_constraints, instruction_constraints))
  34. }
  35. pub fn is_account(attr: &&syn::Attribute) -> bool {
  36. attr.path
  37. .get_ident()
  38. .map_or(false, |ident| ident == "account")
  39. }
  40. pub fn is_instruction(attr: &&syn::Attribute) -> bool {
  41. attr.path
  42. .get_ident()
  43. .map_or(false, |ident| ident == "instruction")
  44. }
  45. // Parses a single constraint from a parse stream for `#[account(<STREAM>)]`.
  46. pub fn parse_token(stream: ParseStream) -> ParseResult<ConstraintToken> {
  47. let is_lit = stream.peek(LitStr);
  48. if is_lit {
  49. let lit: LitStr = stream.parse()?;
  50. let c = ConstraintToken::Literal(Context::new(lit.span(), ConstraintLiteral { lit }));
  51. return Ok(c);
  52. }
  53. let ident = stream.call(Ident::parse_any)?;
  54. let kw = ident.to_string();
  55. let c = match kw.as_str() {
  56. "init" => ConstraintToken::Init(Context::new(ident.span(), ConstraintInit {})),
  57. "zero" => ConstraintToken::Zeroed(Context::new(ident.span(), ConstraintZeroed {})),
  58. "mut" => ConstraintToken::Mut(Context::new(ident.span(), ConstraintMut {})),
  59. "signer" => ConstraintToken::Signer(Context::new(ident.span(), ConstraintSigner {})),
  60. "executable" => {
  61. ConstraintToken::Executable(Context::new(ident.span(), ConstraintExecutable {}))
  62. }
  63. "mint" => {
  64. stream.parse::<Token![:]>()?;
  65. stream.parse::<Token![:]>()?;
  66. let kw = stream.call(Ident::parse_any)?.to_string();
  67. stream.parse::<Token![=]>()?;
  68. let span = ident
  69. .span()
  70. .join(stream.span())
  71. .unwrap_or_else(|| ident.span());
  72. match kw.as_str() {
  73. "authority" => ConstraintToken::MintAuthority(Context::new(
  74. span,
  75. ConstraintMintAuthority {
  76. mint_auth: stream.parse()?,
  77. },
  78. )),
  79. "decimals" => ConstraintToken::MintDecimals(Context::new(
  80. span,
  81. ConstraintMintDecimals {
  82. decimals: stream.parse()?,
  83. },
  84. )),
  85. _ => return Err(ParseError::new(ident.span(), "Invalid attribute")),
  86. }
  87. }
  88. "token" => {
  89. stream.parse::<Token![:]>()?;
  90. stream.parse::<Token![:]>()?;
  91. let kw = stream.call(Ident::parse_any)?.to_string();
  92. stream.parse::<Token![=]>()?;
  93. let span = ident
  94. .span()
  95. .join(stream.span())
  96. .unwrap_or_else(|| ident.span());
  97. match kw.as_str() {
  98. "mint" => ConstraintToken::TokenMint(Context::new(
  99. span,
  100. ConstraintTokenMint {
  101. mint: stream.parse()?,
  102. },
  103. )),
  104. "authority" => ConstraintToken::TokenAuthority(Context::new(
  105. span,
  106. ConstraintTokenAuthority {
  107. auth: stream.parse()?,
  108. },
  109. )),
  110. _ => return Err(ParseError::new(ident.span(), "Invalid attribute")),
  111. }
  112. }
  113. "associated_token" => {
  114. stream.parse::<Token![:]>()?;
  115. stream.parse::<Token![:]>()?;
  116. let kw = stream.call(Ident::parse_any)?.to_string();
  117. stream.parse::<Token![=]>()?;
  118. let span = ident
  119. .span()
  120. .join(stream.span())
  121. .unwrap_or_else(|| ident.span());
  122. match kw.as_str() {
  123. "mint" => ConstraintToken::AssociatedTokenMint(Context::new(
  124. span,
  125. ConstraintTokenMint {
  126. mint: stream.parse()?,
  127. },
  128. )),
  129. "authority" => ConstraintToken::AssociatedTokenAuthority(Context::new(
  130. span,
  131. ConstraintTokenAuthority {
  132. auth: stream.parse()?,
  133. },
  134. )),
  135. _ => return Err(ParseError::new(ident.span(), "Invalid attribute")),
  136. }
  137. }
  138. "bump" => {
  139. let bump = {
  140. if stream.peek(Token![=]) {
  141. stream.parse::<Token![=]>()?;
  142. Some(stream.parse()?)
  143. } else {
  144. None
  145. }
  146. };
  147. ConstraintToken::Bump(Context::new(ident.span(), ConstraintTokenBump { bump }))
  148. }
  149. _ => {
  150. stream.parse::<Token![=]>()?;
  151. let span = ident
  152. .span()
  153. .join(stream.span())
  154. .unwrap_or_else(|| ident.span());
  155. match kw.as_str() {
  156. // Deprecated since 0.11
  157. "belongs_to" => {
  158. return Err(ParseError::new(
  159. ident.span(),
  160. "belongs_to is deprecated, please use has_one",
  161. ))
  162. }
  163. "has_one" => ConstraintToken::HasOne(Context::new(
  164. span,
  165. ConstraintHasOne {
  166. join_target: stream.parse()?,
  167. },
  168. )),
  169. "owner" => ConstraintToken::Owner(Context::new(
  170. span,
  171. ConstraintOwner {
  172. owner_address: stream.parse()?,
  173. },
  174. )),
  175. "rent_exempt" => ConstraintToken::RentExempt(Context::new(
  176. span,
  177. match stream.parse::<Ident>()?.to_string().as_str() {
  178. "skip" => ConstraintRentExempt::Skip,
  179. "enforce" => ConstraintRentExempt::Enforce,
  180. _ => {
  181. return Err(ParseError::new(
  182. span,
  183. "rent_exempt must be either skip or enforce",
  184. ))
  185. }
  186. },
  187. )),
  188. "state" => ConstraintToken::State(Context::new(
  189. span,
  190. ConstraintState {
  191. program_target: stream.parse()?,
  192. },
  193. )),
  194. "payer" => ConstraintToken::Payer(Context::new(
  195. span,
  196. ConstraintPayer {
  197. target: stream.parse()?,
  198. },
  199. )),
  200. "space" => ConstraintToken::Space(Context::new(
  201. span,
  202. ConstraintSpace {
  203. space: stream.parse()?,
  204. },
  205. )),
  206. "seeds" => {
  207. let seeds;
  208. let bracket = bracketed!(seeds in stream);
  209. ConstraintToken::Seeds(Context::new(
  210. span.join(bracket.span).unwrap_or(span),
  211. ConstraintSeeds {
  212. seeds: seeds.parse_terminated(Expr::parse)?,
  213. },
  214. ))
  215. }
  216. "constraint" => ConstraintToken::Raw(Context::new(
  217. span,
  218. ConstraintRaw {
  219. raw: stream.parse()?,
  220. },
  221. )),
  222. "close" => ConstraintToken::Close(Context::new(
  223. span,
  224. ConstraintClose {
  225. sol_dest: stream.parse()?,
  226. },
  227. )),
  228. "address" => ConstraintToken::Address(Context::new(
  229. span,
  230. ConstraintAddress {
  231. address: stream.parse()?,
  232. },
  233. )),
  234. _ => return Err(ParseError::new(ident.span(), "Invalid attribute")),
  235. }
  236. }
  237. };
  238. Ok(c)
  239. }
  240. #[derive(Default)]
  241. pub struct ConstraintGroupBuilder<'ty> {
  242. pub f_ty: Option<&'ty Ty>,
  243. pub init: Option<Context<ConstraintInit>>,
  244. pub zeroed: Option<Context<ConstraintZeroed>>,
  245. pub mutable: Option<Context<ConstraintMut>>,
  246. pub signer: Option<Context<ConstraintSigner>>,
  247. pub has_one: Vec<Context<ConstraintHasOne>>,
  248. pub literal: Vec<Context<ConstraintLiteral>>,
  249. pub raw: Vec<Context<ConstraintRaw>>,
  250. pub owner: Option<Context<ConstraintOwner>>,
  251. pub rent_exempt: Option<Context<ConstraintRentExempt>>,
  252. pub seeds: Option<Context<ConstraintSeeds>>,
  253. pub executable: Option<Context<ConstraintExecutable>>,
  254. pub state: Option<Context<ConstraintState>>,
  255. pub payer: Option<Context<ConstraintPayer>>,
  256. pub space: Option<Context<ConstraintSpace>>,
  257. pub close: Option<Context<ConstraintClose>>,
  258. pub address: Option<Context<ConstraintAddress>>,
  259. pub token_mint: Option<Context<ConstraintTokenMint>>,
  260. pub token_authority: Option<Context<ConstraintTokenAuthority>>,
  261. pub associated_token_mint: Option<Context<ConstraintTokenMint>>,
  262. pub associated_token_authority: Option<Context<ConstraintTokenAuthority>>,
  263. pub mint_authority: Option<Context<ConstraintMintAuthority>>,
  264. pub mint_decimals: Option<Context<ConstraintMintDecimals>>,
  265. pub bump: Option<Context<ConstraintTokenBump>>,
  266. }
  267. impl<'ty> ConstraintGroupBuilder<'ty> {
  268. pub fn new(f_ty: Option<&'ty Ty>) -> Self {
  269. Self {
  270. f_ty,
  271. init: None,
  272. zeroed: None,
  273. mutable: None,
  274. signer: None,
  275. has_one: Vec::new(),
  276. literal: Vec::new(),
  277. raw: Vec::new(),
  278. owner: None,
  279. rent_exempt: None,
  280. seeds: None,
  281. executable: None,
  282. state: None,
  283. payer: None,
  284. space: None,
  285. close: None,
  286. address: None,
  287. token_mint: None,
  288. token_authority: None,
  289. associated_token_mint: None,
  290. associated_token_authority: None,
  291. mint_authority: None,
  292. mint_decimals: None,
  293. bump: None,
  294. }
  295. }
  296. pub fn build(mut self) -> ParseResult<ConstraintGroup> {
  297. // Init.
  298. if let Some(i) = &self.init {
  299. match self.mutable {
  300. Some(m) => {
  301. return Err(ParseError::new(
  302. m.span(),
  303. "mut cannot be provided with init",
  304. ))
  305. }
  306. None => self
  307. .mutable
  308. .replace(Context::new(i.span(), ConstraintMut {})),
  309. };
  310. // Rent exempt if not explicitly skipped.
  311. if self.rent_exempt.is_none() {
  312. self.rent_exempt
  313. .replace(Context::new(i.span(), ConstraintRentExempt::Enforce));
  314. }
  315. if self.payer.is_none() {
  316. return Err(ParseError::new(
  317. i.span(),
  318. "payer must be provided when initializing an account",
  319. ));
  320. }
  321. // When initializing a non-PDA account, the account being
  322. // initialized must sign to invoke the system program's create
  323. // account instruction.
  324. if self.signer.is_none() && self.seeds.is_none() && self.associated_token_mint.is_none()
  325. {
  326. self.signer
  327. .replace(Context::new(i.span(), ConstraintSigner {}));
  328. }
  329. }
  330. // Zero.
  331. if let Some(z) = &self.zeroed {
  332. match self.mutable {
  333. Some(m) => {
  334. return Err(ParseError::new(
  335. m.span(),
  336. "mut cannot be provided with zeroed",
  337. ))
  338. }
  339. None => self
  340. .mutable
  341. .replace(Context::new(z.span(), ConstraintMut {})),
  342. };
  343. // Rent exempt if not explicitly skipped.
  344. if self.rent_exempt.is_none() {
  345. self.rent_exempt
  346. .replace(Context::new(z.span(), ConstraintRentExempt::Enforce));
  347. }
  348. }
  349. // Seeds.
  350. if let Some(i) = &self.seeds {
  351. if self.init.is_some() && self.payer.is_none() {
  352. return Err(ParseError::new(
  353. i.span(),
  354. "payer must be provided when creating a program derived address",
  355. ));
  356. }
  357. if self.bump.is_none() {
  358. return Err(ParseError::new(
  359. i.span(),
  360. "bump must be provided with seeds",
  361. ));
  362. }
  363. }
  364. // Token.
  365. if let Some(token_mint) = &self.token_mint {
  366. if self.token_authority.is_none() {
  367. return Err(ParseError::new(
  368. token_mint.span(),
  369. "token authority must be provided if token mint is",
  370. ));
  371. }
  372. if self.init.is_none() {
  373. return Err(ParseError::new(
  374. token_mint.span(),
  375. "init is required for a pda token",
  376. ));
  377. }
  378. }
  379. if let Some(token_authority) = &self.token_authority {
  380. if self.token_mint.is_none() {
  381. return Err(ParseError::new(
  382. token_authority.span(),
  383. "token authority must be provided if token mint is",
  384. ));
  385. }
  386. }
  387. // Mint.
  388. if let Some(mint_decimals) = &self.mint_decimals {
  389. if self.mint_authority.is_none() {
  390. return Err(ParseError::new(
  391. mint_decimals.span(),
  392. "mint authority must be provided if mint decimals is",
  393. ));
  394. }
  395. }
  396. if let Some(mint_authority) = &self.mint_authority {
  397. if self.mint_decimals.is_none() {
  398. return Err(ParseError::new(
  399. mint_authority.span(),
  400. "mint decimals must be provided if mint authority is",
  401. ));
  402. }
  403. }
  404. // SPL Space.
  405. if self.init.is_some()
  406. && self.seeds.is_some()
  407. && self.token_mint.is_some()
  408. && (self.mint_authority.is_some() || self.token_authority.is_some())
  409. && self.space.is_some()
  410. {
  411. return Err(ParseError::new(
  412. self.space.as_ref().unwrap().span(),
  413. "space is not required for initializing an spl account",
  414. ));
  415. }
  416. let ConstraintGroupBuilder {
  417. f_ty: _,
  418. init,
  419. zeroed,
  420. mutable,
  421. signer,
  422. has_one,
  423. literal,
  424. raw,
  425. owner,
  426. rent_exempt,
  427. seeds,
  428. executable,
  429. state,
  430. payer,
  431. space,
  432. close,
  433. address,
  434. token_mint,
  435. token_authority,
  436. associated_token_mint,
  437. associated_token_authority,
  438. mint_authority,
  439. mint_decimals,
  440. bump,
  441. } = self;
  442. // Converts Option<Context<T>> -> Option<T>.
  443. macro_rules! into_inner {
  444. ($opt:ident) => {
  445. $opt.map(|c| c.into_inner())
  446. };
  447. ($opt:expr) => {
  448. $opt.map(|c| c.into_inner())
  449. };
  450. }
  451. // Converts Vec<Context<T>> - Vec<T>.
  452. macro_rules! into_inner_vec {
  453. ($opt:ident) => {
  454. $opt.into_iter().map(|c| c.into_inner()).collect()
  455. };
  456. }
  457. let seeds = seeds.map(|c| ConstraintSeedsGroup {
  458. is_init: init.is_some(),
  459. seeds: c.seeds.clone(),
  460. bump: into_inner!(bump)
  461. .map(|b| b.bump)
  462. .expect("bump must be provided with seeds"),
  463. });
  464. Ok(ConstraintGroup {
  465. init: init.as_ref().map(|_| Ok(ConstraintInitGroup {
  466. seeds: seeds.clone(),
  467. payer: into_inner!(payer.clone()).map(|a| a.target),
  468. space: space.clone().map(|s| s.space.clone()),
  469. kind: if let Some(tm) = &token_mint {
  470. InitKind::Token {
  471. mint: tm.clone().into_inner().mint,
  472. owner: match &token_authority {
  473. Some(a) => a.clone().into_inner().auth,
  474. None => return Err(ParseError::new(
  475. tm.span(),
  476. "authority must be provided to initialize a token program derived address"
  477. )),
  478. },
  479. }
  480. } else if let Some(tm) = &associated_token_mint {
  481. InitKind::AssociatedToken {
  482. mint: tm.clone().into_inner().mint,
  483. owner: match &associated_token_authority {
  484. Some(a) => a.clone().into_inner().auth,
  485. None => return Err(ParseError::new(
  486. tm.span(),
  487. "authority must be provided to initialize a token program derived address"
  488. )),
  489. },
  490. }
  491. } else if let Some(d) = &mint_decimals {
  492. InitKind::Mint {
  493. decimals: d.clone().into_inner().decimals,
  494. owner: match &mint_authority {
  495. Some(a) => a.clone().into_inner().mint_auth,
  496. None => return Err(ParseError::new(
  497. d.span(),
  498. "authority must be provided to initialize a mint program derived address"
  499. ))
  500. }
  501. }
  502. } else {
  503. InitKind::Program {
  504. owner: owner.as_ref().map(|o| o.owner_address.clone()),
  505. }
  506. },
  507. })).transpose()?,
  508. zeroed: into_inner!(zeroed),
  509. mutable: into_inner!(mutable),
  510. signer: into_inner!(signer),
  511. has_one: into_inner_vec!(has_one),
  512. literal: into_inner_vec!(literal),
  513. raw: into_inner_vec!(raw),
  514. owner: into_inner!(owner),
  515. rent_exempt: into_inner!(rent_exempt),
  516. executable: into_inner!(executable),
  517. state: into_inner!(state),
  518. close: into_inner!(close),
  519. address: into_inner!(address),
  520. seeds,
  521. })
  522. }
  523. pub fn add(&mut self, c: ConstraintToken) -> ParseResult<()> {
  524. match c {
  525. ConstraintToken::Init(c) => self.add_init(c),
  526. ConstraintToken::Zeroed(c) => self.add_zeroed(c),
  527. ConstraintToken::Mut(c) => self.add_mut(c),
  528. ConstraintToken::Signer(c) => self.add_signer(c),
  529. ConstraintToken::HasOne(c) => self.add_has_one(c),
  530. ConstraintToken::Literal(c) => self.add_literal(c),
  531. ConstraintToken::Raw(c) => self.add_raw(c),
  532. ConstraintToken::Owner(c) => self.add_owner(c),
  533. ConstraintToken::RentExempt(c) => self.add_rent_exempt(c),
  534. ConstraintToken::Seeds(c) => self.add_seeds(c),
  535. ConstraintToken::Executable(c) => self.add_executable(c),
  536. ConstraintToken::State(c) => self.add_state(c),
  537. ConstraintToken::Payer(c) => self.add_payer(c),
  538. ConstraintToken::Space(c) => self.add_space(c),
  539. ConstraintToken::Close(c) => self.add_close(c),
  540. ConstraintToken::Address(c) => self.add_address(c),
  541. ConstraintToken::TokenAuthority(c) => self.add_token_authority(c),
  542. ConstraintToken::TokenMint(c) => self.add_token_mint(c),
  543. ConstraintToken::AssociatedTokenAuthority(c) => self.add_associated_token_authority(c),
  544. ConstraintToken::AssociatedTokenMint(c) => self.add_associated_token_mint(c),
  545. ConstraintToken::MintAuthority(c) => self.add_mint_authority(c),
  546. ConstraintToken::MintDecimals(c) => self.add_mint_decimals(c),
  547. ConstraintToken::Bump(c) => self.add_bump(c),
  548. }
  549. }
  550. fn add_init(&mut self, c: Context<ConstraintInit>) -> ParseResult<()> {
  551. if self.init.is_some() {
  552. return Err(ParseError::new(c.span(), "init already provided"));
  553. }
  554. if self.zeroed.is_some() {
  555. return Err(ParseError::new(c.span(), "zeroed already provided"));
  556. }
  557. self.init.replace(c);
  558. Ok(())
  559. }
  560. fn add_zeroed(&mut self, c: Context<ConstraintZeroed>) -> ParseResult<()> {
  561. if self.zeroed.is_some() {
  562. return Err(ParseError::new(c.span(), "zeroed already provided"));
  563. }
  564. if self.init.is_some() {
  565. return Err(ParseError::new(c.span(), "init already provided"));
  566. }
  567. self.zeroed.replace(c);
  568. Ok(())
  569. }
  570. fn add_close(&mut self, c: Context<ConstraintClose>) -> ParseResult<()> {
  571. if !matches!(self.f_ty, Some(Ty::ProgramAccount(_)))
  572. && !matches!(self.f_ty, Some(Ty::Account(_)))
  573. && !matches!(self.f_ty, Some(Ty::Loader(_)))
  574. {
  575. return Err(ParseError::new(
  576. c.span(),
  577. "close must be on an Account, ProgramAccount, or Loader",
  578. ));
  579. }
  580. if self.mutable.is_none() {
  581. return Err(ParseError::new(
  582. c.span(),
  583. "mut must be provided before close",
  584. ));
  585. }
  586. if self.close.is_some() {
  587. return Err(ParseError::new(c.span(), "close already provided"));
  588. }
  589. self.close.replace(c);
  590. Ok(())
  591. }
  592. fn add_address(&mut self, c: Context<ConstraintAddress>) -> ParseResult<()> {
  593. if self.address.is_some() {
  594. return Err(ParseError::new(c.span(), "address already provided"));
  595. }
  596. self.address.replace(c);
  597. Ok(())
  598. }
  599. fn add_token_mint(&mut self, c: Context<ConstraintTokenMint>) -> ParseResult<()> {
  600. if self.token_mint.is_some() {
  601. return Err(ParseError::new(c.span(), "token mint already provided"));
  602. }
  603. if self.associated_token_mint.is_some() {
  604. return Err(ParseError::new(
  605. c.span(),
  606. "associated token mint already provided",
  607. ));
  608. }
  609. if self.init.is_none() {
  610. return Err(ParseError::new(
  611. c.span(),
  612. "init must be provided before token",
  613. ));
  614. }
  615. self.token_mint.replace(c);
  616. Ok(())
  617. }
  618. fn add_associated_token_mint(&mut self, c: Context<ConstraintTokenMint>) -> ParseResult<()> {
  619. if self.associated_token_mint.is_some() {
  620. return Err(ParseError::new(
  621. c.span(),
  622. "associated token mint already provided",
  623. ));
  624. }
  625. if self.token_mint.is_some() {
  626. return Err(ParseError::new(c.span(), "token mint already provided"));
  627. }
  628. if self.init.is_none() {
  629. return Err(ParseError::new(
  630. c.span(),
  631. "init must be provided before token",
  632. ));
  633. }
  634. self.associated_token_mint.replace(c);
  635. Ok(())
  636. }
  637. fn add_bump(&mut self, c: Context<ConstraintTokenBump>) -> ParseResult<()> {
  638. if self.bump.is_some() {
  639. return Err(ParseError::new(c.span(), "bump already provided"));
  640. }
  641. if self.seeds.is_none() {
  642. return Err(ParseError::new(
  643. c.span(),
  644. "seeds must be provided before bump",
  645. ));
  646. }
  647. self.bump.replace(c);
  648. Ok(())
  649. }
  650. fn add_token_authority(&mut self, c: Context<ConstraintTokenAuthority>) -> ParseResult<()> {
  651. if self.token_authority.is_some() {
  652. return Err(ParseError::new(
  653. c.span(),
  654. "token authority already provided",
  655. ));
  656. }
  657. if self.init.is_none() {
  658. return Err(ParseError::new(
  659. c.span(),
  660. "init must be provided before token authority",
  661. ));
  662. }
  663. self.token_authority.replace(c);
  664. Ok(())
  665. }
  666. fn add_associated_token_authority(
  667. &mut self,
  668. c: Context<ConstraintTokenAuthority>,
  669. ) -> ParseResult<()> {
  670. if self.associated_token_authority.is_some() {
  671. return Err(ParseError::new(
  672. c.span(),
  673. "associated token authority already provided",
  674. ));
  675. }
  676. if self.token_authority.is_some() {
  677. return Err(ParseError::new(
  678. c.span(),
  679. "token authority already provided",
  680. ));
  681. }
  682. if self.init.is_none() {
  683. return Err(ParseError::new(
  684. c.span(),
  685. "init must be provided before token authority",
  686. ));
  687. }
  688. self.associated_token_authority.replace(c);
  689. Ok(())
  690. }
  691. fn add_mint_authority(&mut self, c: Context<ConstraintMintAuthority>) -> ParseResult<()> {
  692. if self.mint_authority.is_some() {
  693. return Err(ParseError::new(c.span(), "mint authority already provided"));
  694. }
  695. if self.init.is_none() {
  696. return Err(ParseError::new(
  697. c.span(),
  698. "init must be provided before mint authority",
  699. ));
  700. }
  701. self.mint_authority.replace(c);
  702. Ok(())
  703. }
  704. fn add_mint_decimals(&mut self, c: Context<ConstraintMintDecimals>) -> ParseResult<()> {
  705. if self.mint_decimals.is_some() {
  706. return Err(ParseError::new(c.span(), "mint decimals already provided"));
  707. }
  708. if self.init.is_none() {
  709. return Err(ParseError::new(
  710. c.span(),
  711. "init must be provided before mint decimals",
  712. ));
  713. }
  714. self.mint_decimals.replace(c);
  715. Ok(())
  716. }
  717. fn add_mut(&mut self, c: Context<ConstraintMut>) -> ParseResult<()> {
  718. if self.mutable.is_some() {
  719. return Err(ParseError::new(c.span(), "mut already provided"));
  720. }
  721. self.mutable.replace(c);
  722. Ok(())
  723. }
  724. fn add_signer(&mut self, c: Context<ConstraintSigner>) -> ParseResult<()> {
  725. if self.signer.is_some() {
  726. return Err(ParseError::new(c.span(), "signer already provided"));
  727. }
  728. self.signer.replace(c);
  729. Ok(())
  730. }
  731. fn add_has_one(&mut self, c: Context<ConstraintHasOne>) -> ParseResult<()> {
  732. if self
  733. .has_one
  734. .iter()
  735. .filter(|item| item.join_target == c.join_target)
  736. .count()
  737. > 0
  738. {
  739. return Err(ParseError::new(c.span(), "has_one target already provided"));
  740. }
  741. self.has_one.push(c);
  742. Ok(())
  743. }
  744. fn add_literal(&mut self, c: Context<ConstraintLiteral>) -> ParseResult<()> {
  745. self.literal.push(c);
  746. Ok(())
  747. }
  748. fn add_raw(&mut self, c: Context<ConstraintRaw>) -> ParseResult<()> {
  749. self.raw.push(c);
  750. Ok(())
  751. }
  752. fn add_owner(&mut self, c: Context<ConstraintOwner>) -> ParseResult<()> {
  753. if self.owner.is_some() {
  754. return Err(ParseError::new(c.span(), "owner already provided"));
  755. }
  756. self.owner.replace(c);
  757. Ok(())
  758. }
  759. fn add_rent_exempt(&mut self, c: Context<ConstraintRentExempt>) -> ParseResult<()> {
  760. if self.rent_exempt.is_some() {
  761. return Err(ParseError::new(c.span(), "rent already provided"));
  762. }
  763. self.rent_exempt.replace(c);
  764. Ok(())
  765. }
  766. fn add_seeds(&mut self, c: Context<ConstraintSeeds>) -> ParseResult<()> {
  767. if self.seeds.is_some() {
  768. return Err(ParseError::new(c.span(), "seeds already provided"));
  769. }
  770. self.seeds.replace(c);
  771. Ok(())
  772. }
  773. fn add_executable(&mut self, c: Context<ConstraintExecutable>) -> ParseResult<()> {
  774. if self.executable.is_some() {
  775. return Err(ParseError::new(c.span(), "executable already provided"));
  776. }
  777. self.executable.replace(c);
  778. Ok(())
  779. }
  780. fn add_state(&mut self, c: Context<ConstraintState>) -> ParseResult<()> {
  781. if self.state.is_some() {
  782. return Err(ParseError::new(c.span(), "state already provided"));
  783. }
  784. self.state.replace(c);
  785. Ok(())
  786. }
  787. fn add_payer(&mut self, c: Context<ConstraintPayer>) -> ParseResult<()> {
  788. if self.init.is_none() {
  789. return Err(ParseError::new(
  790. c.span(),
  791. "init must be provided before payer",
  792. ));
  793. }
  794. if self.payer.is_some() {
  795. return Err(ParseError::new(c.span(), "payer already provided"));
  796. }
  797. self.payer.replace(c);
  798. Ok(())
  799. }
  800. fn add_space(&mut self, c: Context<ConstraintSpace>) -> ParseResult<()> {
  801. if self.init.is_none() {
  802. return Err(ParseError::new(
  803. c.span(),
  804. "init must be provided before space",
  805. ));
  806. }
  807. if self.space.is_some() {
  808. return Err(ParseError::new(c.span(), "space already provided"));
  809. }
  810. self.space.replace(c);
  811. Ok(())
  812. }
  813. }