2020-12-31 15:48:06 -08:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub struct Idl {
|
|
|
|
pub version: String,
|
|
|
|
pub name: String,
|
2021-01-01 13:58:20 -08:00
|
|
|
pub instructions: Vec<IdlInstruction>,
|
2021-01-22 03:35:57 -08:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
|
|
|
pub state: Option<IdlState>,
|
2020-12-31 15:48:06 -08:00
|
|
|
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
|
|
|
pub accounts: Vec<IdlTypeDef>,
|
|
|
|
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
|
|
|
pub types: Vec<IdlTypeDef>,
|
2021-01-02 22:40:17 -08:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
2021-01-15 23:05:26 -08:00
|
|
|
pub errors: Option<Vec<IdlErrorCode>>,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
2021-01-02 22:40:17 -08:00
|
|
|
pub metadata: Option<serde_json::Value>,
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2021-01-22 03:35:57 -08:00
|
|
|
pub struct IdlState {
|
|
|
|
#[serde(rename = "struct")]
|
|
|
|
pub strct: IdlTypeDef,
|
|
|
|
pub methods: Vec<IdlStateMethod>,
|
|
|
|
}
|
|
|
|
|
2021-01-23 00:18:50 -08:00
|
|
|
pub type IdlStateMethod = IdlInstruction;
|
2021-01-22 03:35:57 -08:00
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2021-01-01 13:58:20 -08:00
|
|
|
pub struct IdlInstruction {
|
2020-12-31 15:48:06 -08:00
|
|
|
pub name: String,
|
2021-01-20 17:13:02 -08:00
|
|
|
pub accounts: Vec<IdlAccountItem>,
|
2020-12-31 15:48:06 -08:00
|
|
|
pub args: Vec<IdlField>,
|
|
|
|
}
|
|
|
|
|
2021-01-20 17:13:02 -08:00
|
|
|
// A single struct deriving `Accounts`.
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2021-01-20 17:13:02 -08:00
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
pub struct IdlAccounts {
|
|
|
|
pub name: String,
|
|
|
|
pub accounts: Vec<IdlAccountItem>,
|
|
|
|
}
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2021-01-20 17:13:02 -08:00
|
|
|
#[serde(untagged)]
|
|
|
|
pub enum IdlAccountItem {
|
|
|
|
IdlAccount(IdlAccount),
|
|
|
|
IdlAccounts(IdlAccounts),
|
|
|
|
}
|
|
|
|
|
|
|
|
// A single field in the accounts struct.
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2021-01-01 13:58:20 -08:00
|
|
|
#[serde(rename_all = "camelCase")]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub struct IdlAccount {
|
|
|
|
pub name: String,
|
|
|
|
pub is_mut: bool,
|
|
|
|
pub is_signer: bool,
|
|
|
|
}
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub struct IdlField {
|
|
|
|
pub name: String,
|
|
|
|
#[serde(rename = "type")]
|
|
|
|
pub ty: IdlType,
|
|
|
|
}
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2021-01-01 13:58:20 -08:00
|
|
|
pub struct IdlTypeDef {
|
|
|
|
pub name: String,
|
|
|
|
#[serde(rename = "type")]
|
|
|
|
pub ty: IdlTypeDefTy,
|
|
|
|
}
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2021-01-01 13:58:20 -08:00
|
|
|
#[serde(rename_all = "lowercase", tag = "kind")]
|
|
|
|
pub enum IdlTypeDefTy {
|
|
|
|
Struct { fields: Vec<IdlField> },
|
|
|
|
Enum { variants: Vec<EnumVariant> },
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2020-12-31 15:48:06 -08:00
|
|
|
pub struct EnumVariant {
|
|
|
|
pub name: String,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
|
|
|
pub fields: Option<EnumFields>,
|
|
|
|
}
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2020-12-31 15:48:06 -08:00
|
|
|
#[serde(untagged)]
|
|
|
|
pub enum EnumFields {
|
|
|
|
Named(Vec<IdlField>),
|
|
|
|
Tuple(Vec<IdlType>),
|
|
|
|
}
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2020-12-31 15:48:06 -08:00
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
pub enum IdlType {
|
|
|
|
Bool,
|
|
|
|
U8,
|
|
|
|
I8,
|
|
|
|
U16,
|
|
|
|
I16,
|
|
|
|
U32,
|
|
|
|
I32,
|
|
|
|
U64,
|
|
|
|
I64,
|
|
|
|
Bytes,
|
|
|
|
String,
|
|
|
|
PublicKey,
|
|
|
|
Defined(String),
|
2021-01-01 13:58:20 -08:00
|
|
|
Option(Box<IdlType>),
|
2021-01-14 22:35:50 -08:00
|
|
|
Vec(Box<IdlType>),
|
2020-12-31 15:48:06 -08:00
|
|
|
}
|
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2021-01-01 13:58:20 -08:00
|
|
|
pub struct IdlTypePublicKey;
|
|
|
|
|
2020-12-31 15:48:06 -08:00
|
|
|
impl std::str::FromStr for IdlType {
|
|
|
|
type Err = anyhow::Error;
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
2021-01-01 13:58:20 -08:00
|
|
|
// Eliminate whitespace.
|
|
|
|
let mut s = s.to_string();
|
|
|
|
s.retain(|c| !c.is_whitespace());
|
|
|
|
|
|
|
|
let r = match s.as_str() {
|
2020-12-31 15:48:06 -08:00
|
|
|
"bool" => IdlType::Bool,
|
|
|
|
"u8" => IdlType::U8,
|
|
|
|
"i8" => IdlType::I8,
|
|
|
|
"u16" => IdlType::U16,
|
|
|
|
"i16" => IdlType::I16,
|
|
|
|
"u32" => IdlType::U32,
|
2021-01-01 13:58:20 -08:00
|
|
|
"i32" => IdlType::I32,
|
2020-12-31 15:48:06 -08:00
|
|
|
"u64" => IdlType::U64,
|
|
|
|
"i64" => IdlType::I64,
|
|
|
|
"Vec<u8>" => IdlType::Bytes,
|
|
|
|
"String" => IdlType::String,
|
|
|
|
"Pubkey" => IdlType::PublicKey,
|
2021-01-01 13:58:20 -08:00
|
|
|
_ => match s.to_string().strip_prefix("Option<") {
|
2021-01-14 22:35:50 -08:00
|
|
|
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(anyhow::anyhow!("Invalid option"))?,
|
|
|
|
)?;
|
|
|
|
IdlType::Vec(Box::new(inner_ty))
|
|
|
|
}
|
|
|
|
},
|
2021-01-01 13:58:20 -08:00
|
|
|
Some(inner) => {
|
|
|
|
let inner_ty = Self::from_str(
|
|
|
|
inner
|
|
|
|
.strip_suffix(">")
|
|
|
|
.ok_or(anyhow::anyhow!("Invalid option"))?,
|
|
|
|
)?;
|
|
|
|
IdlType::Option(Box::new(inner_ty))
|
|
|
|
}
|
|
|
|
},
|
2020-12-31 15:48:06 -08:00
|
|
|
};
|
|
|
|
Ok(r)
|
|
|
|
}
|
|
|
|
}
|
2021-01-15 23:05:26 -08:00
|
|
|
|
2021-01-29 06:19:00 -08:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2021-01-15 23:05:26 -08:00
|
|
|
pub struct IdlErrorCode {
|
|
|
|
pub code: u32,
|
|
|
|
pub name: String,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
|
|
|
pub msg: Option<String>,
|
|
|
|
}
|