use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Idl { pub version: String, pub name: String, pub instructions: Vec, #[serde(skip_serializing_if = "Option::is_none", default)] pub state: Option, #[serde(skip_serializing_if = "Vec::is_empty", default)] pub accounts: Vec, #[serde(skip_serializing_if = "Vec::is_empty", default)] pub types: Vec, #[serde(skip_serializing_if = "Option::is_none", default)] pub events: Option>, #[serde(skip_serializing_if = "Option::is_none", default)] pub errors: Option>, #[serde(skip_serializing_if = "Option::is_none", default)] pub metadata: Option, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct IdlState { #[serde(rename = "struct")] pub strct: IdlTypeDef, pub methods: Vec, } pub type IdlStateMethod = IdlIx; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct IdlIx { pub name: String, pub accounts: Vec, pub args: Vec, } // A single struct deriving `Accounts`. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct IdlAccounts { pub name: String, pub accounts: Vec, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(untagged)] pub enum IdlAccountItem { IdlAccount(IdlAccount), IdlAccounts(IdlAccounts), } // A single field in the accounts struct. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct IdlAccount { pub name: String, pub is_mut: bool, pub is_signer: bool, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct IdlField { pub name: String, #[serde(rename = "type")] pub ty: IdlType, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct IdlEvent { pub name: String, pub fields: Vec, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct IdlEventField { pub name: String, #[serde(rename = "type")] pub ty: IdlType, pub index: bool, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct IdlTypeDef { pub name: String, #[serde(rename = "type")] pub ty: IdlTypeDefTy, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "lowercase", tag = "kind")] pub enum IdlTypeDefTy { Struct { fields: Vec }, Enum { variants: Vec }, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct EnumVariant { pub name: String, #[serde(skip_serializing_if = "Option::is_none", default)] pub fields: Option, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(untagged)] pub enum EnumFields { Named(Vec), Tuple(Vec), } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub enum IdlType { Bool, U8, I8, U16, I16, U32, I32, U64, I64, U128, I128, Bytes, String, PublicKey, Defined(String), Option(Box), Vec(Box), } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct IdlTypePublicKey; impl std::str::FromStr for IdlType { type Err = anyhow::Error; fn from_str(s: &str) -> Result { // Eliminate whitespace. let mut s = s.to_string(); s.retain(|c| !c.is_whitespace()); let r = match s.as_str() { "bool" => IdlType::Bool, "u8" => IdlType::U8, "i8" => IdlType::I8, "u16" => IdlType::U16, "i16" => IdlType::I16, "u32" => IdlType::U32, "i32" => IdlType::I32, "u64" => IdlType::U64, "i64" => IdlType::I64, "u128" => IdlType::U128, "i128" => IdlType::I128, "Vec" => IdlType::Bytes, "String" => IdlType::String, "Pubkey" => IdlType::PublicKey, _ => match s.to_string().strip_prefix("Option<") { None => match s.to_string().strip_prefix("Vec<") { None => IdlType::Defined(s.to_string()), Some(inner) => { let inner_ty = Self::from_str( inner .strip_suffix(">") .ok_or_else(|| anyhow::anyhow!("Invalid option"))?, )?; IdlType::Vec(Box::new(inner_ty)) } }, Some(inner) => { let inner_ty = Self::from_str( inner .strip_suffix(">") .ok_or_else(|| anyhow::anyhow!("Invalid option"))?, )?; IdlType::Option(Box::new(inner_ty)) } }, }; Ok(r) } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct IdlErrorCode { pub code: u32, pub name: String, #[serde(skip_serializing_if = "Option::is_none", default)] pub msg: Option, }