123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- //! DSL syntax tokens.
- #[cfg(feature = "idl")]
- use crate::idl::{IdlAccount, IdlAccountItem, IdlAccounts};
- use anyhow::Result;
- #[cfg(feature = "idl")]
- use heck::MixedCase;
- use quote::quote;
- use std::collections::HashMap;
- pub mod codegen;
- #[cfg(feature = "idl")]
- pub mod idl;
- pub mod parser;
- #[derive(Debug)]
- pub struct Program {
- pub rpcs: Vec<Rpc>,
- pub name: syn::Ident,
- pub program_mod: syn::ItemMod,
- }
- #[derive(Debug)]
- pub struct Rpc {
- pub raw_method: syn::ItemFn,
- pub ident: syn::Ident,
- pub args: Vec<RpcArg>,
- // The ident for the struct deriving Accounts.
- pub anchor_ident: syn::Ident,
- }
- #[derive(Debug)]
- pub struct RpcArg {
- pub name: proc_macro2::Ident,
- pub raw_arg: syn::PatType,
- }
- #[derive(Debug)]
- pub struct AccountsStruct {
- // Name of the accounts struct.
- pub ident: syn::Ident,
- // Generics + lifetimes on the accounts struct.
- pub generics: syn::Generics,
- // Fields on the accounts struct.
- pub fields: Vec<AccountField>,
- }
- impl AccountsStruct {
- pub fn new(strct: syn::ItemStruct, fields: Vec<AccountField>) -> Self {
- let ident = strct.ident.clone();
- let generics = strct.generics.clone();
- Self {
- ident,
- generics,
- fields,
- }
- }
- // Returns all program owned accounts in the Accounts struct.
- //
- // `global_accs` is given to "link" account types that are embedded
- // in each other.
- pub fn account_tys(
- &self,
- global_accs: &HashMap<String, AccountsStruct>,
- ) -> Result<Vec<String>> {
- let mut tys = vec![];
- for f in &self.fields {
- match f {
- AccountField::Field(f) => {
- if let Ty::ProgramAccount(pty) = &f.ty {
- tys.push(pty.account_ident.to_string());
- }
- }
- AccountField::AccountsStruct(comp_f) => {
- let accs = global_accs.get(&comp_f.symbol).ok_or(anyhow::format_err!(
- "Invalid account type: {}",
- comp_f.symbol
- ))?;
- tys.extend(accs.account_tys(global_accs)?);
- }
- }
- }
- Ok(tys)
- }
- #[cfg(feature = "idl")]
- pub fn idl_accounts(
- &self,
- global_accs: &HashMap<String, AccountsStruct>,
- ) -> Vec<IdlAccountItem> {
- self.fields
- .iter()
- .map(|acc: &AccountField| match acc {
- AccountField::AccountsStruct(comp_f) => {
- let accs_strct = global_accs
- .get(&comp_f.symbol)
- .expect("Could not reslve Accounts symbol");
- let accounts = accs_strct.idl_accounts(global_accs);
- IdlAccountItem::IdlAccounts(IdlAccounts {
- name: comp_f.ident.to_string().to_mixed_case(),
- accounts,
- })
- }
- AccountField::Field(acc) => IdlAccountItem::IdlAccount(IdlAccount {
- name: acc.ident.to_string().to_mixed_case(),
- is_mut: acc.is_mut,
- is_signer: acc.is_signer,
- }),
- })
- .collect::<Vec<_>>()
- }
- }
- #[derive(Debug)]
- pub enum AccountField {
- // Use a `String` instead of the `AccountsStruct` because all
- // accounts structs aren't visible to a single derive macro.
- //
- // When we need the global context, we fill in the String with the
- // appropriate values. See, `account_tys` as an example.
- AccountsStruct(CompositeField), // Composite
- Field(Field), // Primitive
- }
- #[derive(Debug)]
- pub struct CompositeField {
- pub ident: syn::Ident,
- pub symbol: String,
- pub constraints: Vec<Constraint>,
- pub raw_field: syn::Field,
- }
- // An account in the accounts struct.
- #[derive(Debug)]
- pub struct Field {
- pub ident: syn::Ident,
- pub ty: Ty,
- pub constraints: Vec<Constraint>,
- pub is_mut: bool,
- pub is_signer: bool,
- pub is_init: bool,
- }
- impl Field {
- pub fn typed_ident(&self) -> proc_macro2::TokenStream {
- let name = &self.ident;
- let ty = match &self.ty {
- Ty::AccountInfo => quote! { AccountInfo },
- Ty::ProgramAccount(ty) => {
- let account = &ty.account_ident;
- quote! {
- ProgramAccount<#account>
- }
- }
- Ty::CpiAccount(ty) => {
- let account = &ty.account_ident;
- quote! {
- CpiAccount<#account>
- }
- }
- Ty::Sysvar(ty) => {
- let account = match ty {
- SysvarTy::Clock => quote! {Clock},
- SysvarTy::Rent => quote! {Rent},
- SysvarTy::EpochSchedule => quote! {EpochSchedule},
- SysvarTy::Fees => quote! {Fees},
- SysvarTy::RecentBlockHashes => quote! {RecentBlockHashes},
- SysvarTy::SlotHashes => quote! {SlotHashes},
- SysvarTy::SlotHistory => quote! {SlotHistory},
- SysvarTy::StakeHistory => quote! {StakeHistory},
- SysvarTy::Instructions => quote! {Instructions},
- SysvarTy::Rewards => quote! {Rewards},
- };
- quote! {
- Sysvar<#account>
- }
- }
- };
- quote! {
- #name: #ty
- }
- }
- }
- // A type of an account field.
- #[derive(Debug, PartialEq)]
- pub enum Ty {
- AccountInfo,
- ProgramAccount(ProgramAccountTy),
- CpiAccount(CpiAccountTy),
- Sysvar(SysvarTy),
- }
- #[derive(Debug, PartialEq)]
- pub enum SysvarTy {
- Clock,
- Rent,
- EpochSchedule,
- Fees,
- RecentBlockHashes,
- SlotHashes,
- SlotHistory,
- StakeHistory,
- Instructions,
- Rewards,
- }
- #[derive(Debug, PartialEq)]
- pub struct ProgramAccountTy {
- // The struct type of the account.
- pub account_ident: syn::Ident,
- }
- #[derive(Debug, PartialEq)]
- pub struct CpiAccountTy {
- // The struct type of the account.
- pub account_ident: syn::Ident,
- }
- // An access control constraint for an account.
- #[derive(Debug)]
- pub enum Constraint {
- Signer(ConstraintSigner),
- BelongsTo(ConstraintBelongsTo),
- Literal(ConstraintLiteral),
- Owner(ConstraintOwner),
- RentExempt(ConstraintRentExempt),
- Seeds(ConstraintSeeds),
- }
- #[derive(Debug)]
- pub struct ConstraintBelongsTo {
- pub join_target: proc_macro2::Ident,
- }
- #[derive(Debug)]
- pub struct ConstraintSigner {}
- #[derive(Debug)]
- pub struct ConstraintLiteral {
- pub tokens: proc_macro2::TokenStream,
- }
- #[derive(Debug)]
- pub enum ConstraintOwner {
- Program,
- Skip,
- }
- #[derive(Debug)]
- pub enum ConstraintRentExempt {
- Enforce,
- Skip,
- }
- #[derive(Debug)]
- pub struct ConstraintSeeds {
- pub seeds: proc_macro2::Group,
- }
- #[derive(Debug)]
- pub struct Error {
- pub name: String,
- pub raw_enum: syn::ItemEnum,
- pub ident: syn::Ident,
- pub codes: Vec<ErrorCode>,
- }
- #[derive(Debug)]
- pub struct ErrorCode {
- pub id: u32,
- pub ident: syn::Ident,
- pub msg: Option<String>,
- }
|