2021-05-30 12:59:33 -07:00
|
|
|
use codegen::accounts as accounts_codegen;
|
|
|
|
use codegen::program as program_codegen;
|
|
|
|
use parser::accounts as accounts_parser;
|
|
|
|
use parser::program as program_parser;
|
|
|
|
use proc_macro2::{Span, TokenStream};
|
|
|
|
use quote::ToTokens;
|
|
|
|
use std::ops::Deref;
|
2021-06-09 13:02:50 -07:00
|
|
|
use syn::ext::IdentExt;
|
|
|
|
use syn::parse::{Error as ParseError, Parse, ParseStream, Result as ParseResult};
|
2021-05-30 12:59:33 -07:00
|
|
|
use syn::punctuated::Punctuated;
|
|
|
|
use syn::spanned::Spanned;
|
|
|
|
use syn::{
|
|
|
|
Expr, Generics, Ident, ImplItemMethod, ItemEnum, ItemFn, ItemImpl, ItemMod, ItemStruct, LitInt,
|
|
|
|
LitStr, PatType, Token,
|
|
|
|
};
|
2021-01-14 22:35:50 -08:00
|
|
|
|
2020-12-31 15:48:06 -08:00
|
|
|
pub mod codegen;
|
2021-02-05 03:17:40 -08:00
|
|
|
#[cfg(feature = "hash")]
|
|
|
|
pub mod hash;
|
2021-02-06 00:28:33 -08:00
|
|
|
#[cfg(not(feature = "hash"))]
|
|
|
|
pub(crate) mod hash;
|
2021-01-01 19:07:26 -08:00
|
|
|
#[cfg(feature = "idl")]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub mod idl;
|
|
|
|
pub mod parser;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Program {
|
2021-01-22 03:35:57 -08:00
|
|
|
pub state: Option<State>,
|
2021-02-10 22:35:23 -08:00
|
|
|
pub ixs: Vec<Ix>,
|
2021-05-30 12:59:33 -07:00
|
|
|
pub name: Ident,
|
|
|
|
pub program_mod: ItemMod,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Parse for Program {
|
|
|
|
fn parse(input: ParseStream) -> ParseResult<Self> {
|
|
|
|
let program_mod = <ItemMod as Parse>::parse(input)?;
|
|
|
|
program_parser::parse(program_mod)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&Program> for TokenStream {
|
|
|
|
fn from(program: &Program) -> Self {
|
|
|
|
program_codegen::generate(program)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToTokens for Program {
|
|
|
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
|
|
tokens.extend::<TokenStream>(self.into());
|
|
|
|
}
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-01-22 03:35:57 -08:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct State {
|
|
|
|
pub name: String,
|
2021-05-30 12:59:33 -07:00
|
|
|
pub strct: ItemStruct,
|
|
|
|
pub ctor_and_anchor: Option<(ImplItemMethod, Ident)>,
|
|
|
|
pub impl_block_and_methods: Option<(ItemImpl, Vec<StateIx>)>,
|
2021-02-09 06:25:23 -08:00
|
|
|
pub interfaces: Option<Vec<StateInterface>>,
|
2021-04-18 09:54:18 -07:00
|
|
|
pub is_zero_copy: bool,
|
2021-01-23 00:18:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2021-02-10 22:35:23 -08:00
|
|
|
pub struct StateIx {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub raw_method: ImplItemMethod,
|
|
|
|
pub ident: Ident,
|
2021-02-10 22:35:23 -08:00
|
|
|
pub args: Vec<IxArg>,
|
2021-05-30 12:59:33 -07:00
|
|
|
pub anchor_ident: Ident,
|
2021-02-07 07:45:10 -08:00
|
|
|
// True if there exists a &self on the method.
|
|
|
|
pub has_receiver: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct StateInterface {
|
|
|
|
pub trait_name: String,
|
2021-02-10 22:35:23 -08:00
|
|
|
pub methods: Vec<StateIx>,
|
2021-01-22 03:35:57 -08:00
|
|
|
}
|
|
|
|
|
2020-12-31 15:48:06 -08:00
|
|
|
#[derive(Debug)]
|
2021-02-10 22:35:23 -08:00
|
|
|
pub struct Ix {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub raw_method: ItemFn,
|
|
|
|
pub ident: Ident,
|
2021-02-10 22:35:23 -08:00
|
|
|
pub args: Vec<IxArg>,
|
2021-01-14 15:16:27 -08:00
|
|
|
// The ident for the struct deriving Accounts.
|
2021-05-30 12:59:33 -07:00
|
|
|
pub anchor_ident: Ident,
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2021-02-10 22:35:23 -08:00
|
|
|
pub struct IxArg {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub name: Ident,
|
|
|
|
pub raw_arg: PatType,
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-01-14 22:35:50 -08:00
|
|
|
#[derive(Debug)]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub struct AccountsStruct {
|
|
|
|
// Name of the accounts struct.
|
2021-05-30 12:59:33 -07:00
|
|
|
pub ident: Ident,
|
2020-12-31 15:48:06 -08:00
|
|
|
// Generics + lifetimes on the accounts struct.
|
2021-05-30 12:59:33 -07:00
|
|
|
pub generics: Generics,
|
2020-12-31 15:48:06 -08:00
|
|
|
// Fields on the accounts struct.
|
2021-01-14 22:35:50 -08:00
|
|
|
pub fields: Vec<AccountField>,
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
impl Parse for AccountsStruct {
|
|
|
|
fn parse(input: ParseStream) -> ParseResult<Self> {
|
|
|
|
let strct = <ItemStruct as Parse>::parse(input)?;
|
|
|
|
accounts_parser::parse(&strct)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&AccountsStruct> for TokenStream {
|
|
|
|
fn from(accounts: &AccountsStruct) -> Self {
|
|
|
|
accounts_codegen::generate(accounts)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToTokens for AccountsStruct {
|
|
|
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
|
|
tokens.extend::<TokenStream>(self.into());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-31 15:48:06 -08:00
|
|
|
impl AccountsStruct {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub fn new(strct: ItemStruct, fields: Vec<AccountField>) -> Self {
|
2020-12-31 15:48:06 -08:00
|
|
|
let ident = strct.ident.clone();
|
2021-02-15 21:52:54 -08:00
|
|
|
let generics = strct.generics;
|
2020-12-31 15:48:06 -08:00
|
|
|
Self {
|
|
|
|
ident,
|
|
|
|
generics,
|
|
|
|
fields,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-14 22:35:50 -08:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum AccountField {
|
2021-05-30 12:59:33 -07:00
|
|
|
Field(Field),
|
|
|
|
CompositeField(CompositeField),
|
2021-01-14 22:35:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2021-05-30 12:59:33 -07:00
|
|
|
pub struct Field {
|
|
|
|
pub ident: Ident,
|
|
|
|
pub constraints: ConstraintGroup,
|
|
|
|
pub ty: Ty,
|
2021-01-14 22:35:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2021-05-30 12:59:33 -07:00
|
|
|
pub struct CompositeField {
|
|
|
|
pub ident: Ident,
|
|
|
|
pub constraints: ConstraintGroup,
|
|
|
|
pub symbol: String,
|
|
|
|
pub raw_field: syn::Field,
|
2021-01-14 22:35:50 -08:00
|
|
|
}
|
|
|
|
|
2020-12-31 15:48:06 -08:00
|
|
|
// A type of an account field.
|
2021-01-14 22:35:50 -08:00
|
|
|
#[derive(Debug, PartialEq)]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub enum Ty {
|
|
|
|
AccountInfo,
|
2021-01-22 03:35:57 -08:00
|
|
|
ProgramState(ProgramStateTy),
|
2021-04-11 17:23:43 -07:00
|
|
|
CpiState(CpiStateTy),
|
2020-12-31 15:48:06 -08:00
|
|
|
ProgramAccount(ProgramAccountTy),
|
2021-04-17 12:07:48 -07:00
|
|
|
Loader(LoaderTy),
|
2021-01-14 15:16:27 -08:00
|
|
|
CpiAccount(CpiAccountTy),
|
2021-01-14 22:35:50 -08:00
|
|
|
Sysvar(SysvarTy),
|
2021-01-11 09:22:25 -08:00
|
|
|
}
|
|
|
|
|
2021-01-14 22:35:50 -08:00
|
|
|
#[derive(Debug, PartialEq)]
|
2021-01-11 09:22:25 -08:00
|
|
|
pub enum SysvarTy {
|
|
|
|
Clock,
|
|
|
|
Rent,
|
|
|
|
EpochSchedule,
|
|
|
|
Fees,
|
2021-05-21 22:22:54 -07:00
|
|
|
RecentBlockhashes,
|
2021-01-11 09:22:25 -08:00
|
|
|
SlotHashes,
|
|
|
|
SlotHistory,
|
|
|
|
StakeHistory,
|
|
|
|
Instructions,
|
|
|
|
Rewards,
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-01-22 03:35:57 -08:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct ProgramStateTy {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub account_ident: Ident,
|
2021-01-22 03:35:57 -08:00
|
|
|
}
|
|
|
|
|
2021-04-11 17:23:43 -07:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct CpiStateTy {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub account_ident: Ident,
|
2021-04-11 17:23:43 -07:00
|
|
|
}
|
|
|
|
|
2021-01-14 22:35:50 -08:00
|
|
|
#[derive(Debug, PartialEq)]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub struct ProgramAccountTy {
|
|
|
|
// The struct type of the account.
|
2021-05-30 12:59:33 -07:00
|
|
|
pub account_ident: Ident,
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-01-14 22:35:50 -08:00
|
|
|
#[derive(Debug, PartialEq)]
|
2021-01-14 15:16:27 -08:00
|
|
|
pub struct CpiAccountTy {
|
|
|
|
// The struct type of the account.
|
2021-05-30 12:59:33 -07:00
|
|
|
pub account_ident: Ident,
|
2021-01-14 15:16:27 -08:00
|
|
|
}
|
|
|
|
|
2021-04-17 12:07:48 -07:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct LoaderTy {
|
|
|
|
// The struct type of the account.
|
2021-05-30 12:59:33 -07:00
|
|
|
pub account_ident: Ident,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Error {
|
|
|
|
pub name: String,
|
|
|
|
pub raw_enum: ItemEnum,
|
|
|
|
pub ident: Ident,
|
|
|
|
pub codes: Vec<ErrorCode>,
|
2021-06-09 13:02:50 -07:00
|
|
|
pub args: Option<ErrorArgs>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ErrorArgs {
|
|
|
|
pub offset: LitInt,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Parse for ErrorArgs {
|
|
|
|
fn parse(stream: ParseStream) -> ParseResult<Self> {
|
|
|
|
let offset_span = stream.span();
|
|
|
|
let offset = stream.call(Ident::parse_any)?;
|
|
|
|
if offset.to_string().as_str() != "offset" {
|
|
|
|
return Err(ParseError::new(offset_span, "expected keyword offset"));
|
|
|
|
}
|
|
|
|
stream.parse::<Token![=]>()?;
|
|
|
|
Ok(ErrorArgs {
|
|
|
|
offset: stream.parse()?,
|
|
|
|
})
|
|
|
|
}
|
2021-04-17 12:07:48 -07:00
|
|
|
}
|
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ErrorCode {
|
|
|
|
pub id: u32,
|
|
|
|
pub ident: Ident,
|
|
|
|
pub msg: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
// All well formed constraints on a single `Accounts` field.
|
|
|
|
#[derive(Debug, Default, Clone)]
|
|
|
|
pub struct ConstraintGroup {
|
|
|
|
init: Option<ConstraintInit>,
|
|
|
|
mutable: Option<ConstraintMut>,
|
|
|
|
signer: Option<ConstraintSigner>,
|
|
|
|
owner: Option<ConstraintOwner>,
|
|
|
|
rent_exempt: Option<ConstraintRentExempt>,
|
|
|
|
seeds: Option<ConstraintSeeds>,
|
|
|
|
executable: Option<ConstraintExecutable>,
|
|
|
|
state: Option<ConstraintState>,
|
|
|
|
associated: Option<ConstraintAssociatedGroup>,
|
|
|
|
belongs_to: Vec<ConstraintBelongsTo>,
|
|
|
|
literal: Vec<ConstraintLiteral>,
|
|
|
|
raw: Vec<ConstraintRaw>,
|
2021-06-09 15:40:43 -07:00
|
|
|
close: Option<ConstraintClose>,
|
2021-05-30 12:59:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ConstraintGroup {
|
|
|
|
pub fn is_init(&self) -> bool {
|
|
|
|
self.init.is_some()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_mutable(&self) -> bool {
|
|
|
|
self.mutable.is_some()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_signer(&self) -> bool {
|
|
|
|
self.signer.is_some()
|
|
|
|
}
|
2021-06-09 15:40:43 -07:00
|
|
|
|
|
|
|
pub fn is_close(&self) -> bool {
|
|
|
|
self.close.is_some()
|
|
|
|
}
|
2021-05-30 12:59:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// A single account constraint *after* merging all tokens into a well formed
|
|
|
|
// constraint. Some constraints like "associated" are defined by multiple
|
|
|
|
// tokens, so a merging phase is required.
|
2021-01-14 22:35:50 -08:00
|
|
|
#[derive(Debug)]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub enum Constraint {
|
2021-05-30 12:59:33 -07:00
|
|
|
Init(ConstraintInit),
|
|
|
|
Mut(ConstraintMut),
|
2020-12-31 15:48:06 -08:00
|
|
|
Signer(ConstraintSigner),
|
|
|
|
BelongsTo(ConstraintBelongsTo),
|
|
|
|
Literal(ConstraintLiteral),
|
2021-05-30 12:59:33 -07:00
|
|
|
Raw(ConstraintRaw),
|
2020-12-31 15:48:06 -08:00
|
|
|
Owner(ConstraintOwner),
|
2021-01-11 12:00:18 -08:00
|
|
|
RentExempt(ConstraintRentExempt),
|
2021-01-20 17:13:02 -08:00
|
|
|
Seeds(ConstraintSeeds),
|
2021-04-03 15:13:12 -07:00
|
|
|
Executable(ConstraintExecutable),
|
2021-04-11 17:23:43 -07:00
|
|
|
State(ConstraintState),
|
2021-05-30 12:59:33 -07:00
|
|
|
AssociatedGroup(ConstraintAssociatedGroup),
|
2021-06-09 15:40:43 -07:00
|
|
|
Close(ConstraintClose),
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
// Constraint token is a single keyword in a `#[account(<TOKEN>)]` attribute.
|
2021-01-14 22:35:50 -08:00
|
|
|
#[derive(Debug)]
|
2021-05-30 12:59:33 -07:00
|
|
|
pub enum ConstraintToken {
|
|
|
|
Init(Context<ConstraintInit>),
|
|
|
|
Mut(Context<ConstraintMut>),
|
|
|
|
Signer(Context<ConstraintSigner>),
|
|
|
|
BelongsTo(Context<ConstraintBelongsTo>),
|
|
|
|
Literal(Context<ConstraintLiteral>),
|
|
|
|
Raw(Context<ConstraintRaw>),
|
|
|
|
Owner(Context<ConstraintOwner>),
|
|
|
|
RentExempt(Context<ConstraintRentExempt>),
|
|
|
|
Seeds(Context<ConstraintSeeds>),
|
|
|
|
Executable(Context<ConstraintExecutable>),
|
|
|
|
State(Context<ConstraintState>),
|
2021-06-09 15:40:43 -07:00
|
|
|
Close(Context<ConstraintClose>),
|
2021-05-30 12:59:33 -07:00
|
|
|
Associated(Context<ConstraintAssociated>),
|
|
|
|
AssociatedPayer(Context<ConstraintAssociatedPayer>),
|
|
|
|
AssociatedSpace(Context<ConstraintAssociatedSpace>),
|
|
|
|
AssociatedWith(Context<ConstraintAssociatedWith>),
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
impl Parse for ConstraintToken {
|
|
|
|
fn parse(stream: ParseStream) -> ParseResult<Self> {
|
|
|
|
accounts_parser::constraints::parse_token(stream)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct ConstraintInit {}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct ConstraintMut {}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub struct ConstraintSigner {}
|
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct ConstraintBelongsTo {
|
|
|
|
pub join_target: Ident,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub struct ConstraintLiteral {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub lit: LitStr,
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct ConstraintRaw {
|
|
|
|
pub raw: Expr,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
2021-04-11 21:54:35 -07:00
|
|
|
pub struct ConstraintOwner {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub owner_target: Ident,
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
2021-01-11 12:00:18 -08:00
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
#[derive(Debug, Clone)]
|
2021-01-11 12:00:18 -08:00
|
|
|
pub enum ConstraintRentExempt {
|
|
|
|
Enforce,
|
|
|
|
Skip,
|
|
|
|
}
|
2021-01-15 23:05:26 -08:00
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
#[derive(Debug, Clone)]
|
2021-01-20 17:13:02 -08:00
|
|
|
pub struct ConstraintSeeds {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub seeds: Punctuated<Expr, Token![,]>,
|
2021-01-20 17:13:02 -08:00
|
|
|
}
|
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
#[derive(Debug, Clone)]
|
2021-04-03 15:13:12 -07:00
|
|
|
pub struct ConstraintExecutable {}
|
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
#[derive(Debug, Clone)]
|
2021-04-11 17:23:43 -07:00
|
|
|
pub struct ConstraintState {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub program_target: Ident,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct ConstraintAssociatedGroup {
|
|
|
|
pub is_init: bool,
|
|
|
|
pub associated_target: Ident,
|
|
|
|
pub associated_seeds: Vec<Ident>,
|
|
|
|
pub payer: Option<Ident>,
|
|
|
|
pub space: Option<LitInt>,
|
2021-04-11 17:23:43 -07:00
|
|
|
}
|
|
|
|
|
2021-04-13 11:47:54 -07:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ConstraintAssociated {
|
2021-05-30 12:59:33 -07:00
|
|
|
pub target: Ident,
|
2021-04-13 11:47:54 -07:00
|
|
|
}
|
|
|
|
|
2021-01-15 23:05:26 -08:00
|
|
|
#[derive(Debug)]
|
2021-05-30 12:59:33 -07:00
|
|
|
pub struct ConstraintAssociatedPayer {
|
|
|
|
pub target: Ident,
|
2021-01-15 23:05:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2021-05-30 12:59:33 -07:00
|
|
|
pub struct ConstraintAssociatedWith {
|
|
|
|
pub target: Ident,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ConstraintAssociatedSpace {
|
|
|
|
pub space: LitInt,
|
|
|
|
}
|
|
|
|
|
2021-06-09 15:40:43 -07:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct ConstraintClose {
|
|
|
|
pub sol_dest: Ident,
|
|
|
|
}
|
|
|
|
|
2021-05-30 12:59:33 -07:00
|
|
|
// Syntaxt context object for preserving metadata about the inner item.
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct Context<T> {
|
|
|
|
span: Span,
|
|
|
|
inner: T,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Context<T> {
|
|
|
|
pub fn new(span: Span, inner: T) -> Self {
|
|
|
|
Self { span, inner }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn into_inner(self) -> T {
|
|
|
|
self.inner
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Deref for Context<T> {
|
|
|
|
type Target = T;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.inner
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Spanned for Context<T> {
|
|
|
|
fn span(&self) -> Span {
|
|
|
|
self.span
|
|
|
|
}
|
2021-01-15 23:05:26 -08:00
|
|
|
}
|