idl.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. use serde::{Deserialize, Serialize};
  2. #[derive(Debug, Clone, Serialize, Deserialize)]
  3. pub struct Idl {
  4. pub version: String,
  5. pub name: String,
  6. pub instructions: Vec<IdlInstruction>,
  7. #[serde(skip_serializing_if = "Option::is_none", default)]
  8. pub state: Option<IdlState>,
  9. #[serde(skip_serializing_if = "Vec::is_empty", default)]
  10. pub accounts: Vec<IdlTypeDef>,
  11. #[serde(skip_serializing_if = "Vec::is_empty", default)]
  12. pub types: Vec<IdlTypeDef>,
  13. #[serde(skip_serializing_if = "Option::is_none", default)]
  14. pub errors: Option<Vec<IdlErrorCode>>,
  15. #[serde(skip_serializing_if = "Option::is_none", default)]
  16. pub metadata: Option<serde_json::Value>,
  17. }
  18. #[derive(Debug, Clone, Serialize, Deserialize)]
  19. pub struct IdlState {
  20. #[serde(rename = "struct")]
  21. pub strct: IdlTypeDef,
  22. pub methods: Vec<IdlStateMethod>,
  23. }
  24. pub type IdlStateMethod = IdlInstruction;
  25. #[derive(Debug, Clone, Serialize, Deserialize)]
  26. pub struct IdlInstruction {
  27. pub name: String,
  28. pub accounts: Vec<IdlAccountItem>,
  29. pub args: Vec<IdlField>,
  30. }
  31. // A single struct deriving `Accounts`.
  32. #[derive(Debug, Clone, Serialize, Deserialize)]
  33. #[serde(rename_all = "camelCase")]
  34. pub struct IdlAccounts {
  35. pub name: String,
  36. pub accounts: Vec<IdlAccountItem>,
  37. }
  38. #[derive(Debug, Clone, Serialize, Deserialize)]
  39. #[serde(untagged)]
  40. pub enum IdlAccountItem {
  41. IdlAccount(IdlAccount),
  42. IdlAccounts(IdlAccounts),
  43. }
  44. // A single field in the accounts struct.
  45. #[derive(Debug, Clone, Serialize, Deserialize)]
  46. #[serde(rename_all = "camelCase")]
  47. pub struct IdlAccount {
  48. pub name: String,
  49. pub is_mut: bool,
  50. pub is_signer: bool,
  51. }
  52. #[derive(Debug, Clone, Serialize, Deserialize)]
  53. pub struct IdlField {
  54. pub name: String,
  55. #[serde(rename = "type")]
  56. pub ty: IdlType,
  57. }
  58. #[derive(Debug, Clone, Serialize, Deserialize)]
  59. pub struct IdlTypeDef {
  60. pub name: String,
  61. #[serde(rename = "type")]
  62. pub ty: IdlTypeDefTy,
  63. }
  64. #[derive(Debug, Clone, Serialize, Deserialize)]
  65. #[serde(rename_all = "lowercase", tag = "kind")]
  66. pub enum IdlTypeDefTy {
  67. Struct { fields: Vec<IdlField> },
  68. Enum { variants: Vec<EnumVariant> },
  69. }
  70. #[derive(Debug, Clone, Serialize, Deserialize)]
  71. pub struct EnumVariant {
  72. pub name: String,
  73. #[serde(skip_serializing_if = "Option::is_none", default)]
  74. pub fields: Option<EnumFields>,
  75. }
  76. #[derive(Debug, Clone, Serialize, Deserialize)]
  77. #[serde(untagged)]
  78. pub enum EnumFields {
  79. Named(Vec<IdlField>),
  80. Tuple(Vec<IdlType>),
  81. }
  82. #[derive(Debug, Clone, Serialize, Deserialize)]
  83. #[serde(rename_all = "camelCase")]
  84. pub enum IdlType {
  85. Bool,
  86. U8,
  87. I8,
  88. U16,
  89. I16,
  90. U32,
  91. I32,
  92. U64,
  93. I64,
  94. U128,
  95. I128,
  96. Bytes,
  97. String,
  98. PublicKey,
  99. Defined(String),
  100. Option(Box<IdlType>),
  101. Vec(Box<IdlType>),
  102. }
  103. #[derive(Debug, Clone, Serialize, Deserialize)]
  104. pub struct IdlTypePublicKey;
  105. impl std::str::FromStr for IdlType {
  106. type Err = anyhow::Error;
  107. fn from_str(s: &str) -> Result<Self, Self::Err> {
  108. // Eliminate whitespace.
  109. let mut s = s.to_string();
  110. s.retain(|c| !c.is_whitespace());
  111. let r = match s.as_str() {
  112. "bool" => IdlType::Bool,
  113. "u8" => IdlType::U8,
  114. "i8" => IdlType::I8,
  115. "u16" => IdlType::U16,
  116. "i16" => IdlType::I16,
  117. "u32" => IdlType::U32,
  118. "i32" => IdlType::I32,
  119. "u64" => IdlType::U64,
  120. "i64" => IdlType::I64,
  121. "u128" => IdlType::U128,
  122. "i128" => IdlType::I128,
  123. "Vec<u8>" => IdlType::Bytes,
  124. "String" => IdlType::String,
  125. "Pubkey" => IdlType::PublicKey,
  126. _ => match s.to_string().strip_prefix("Option<") {
  127. None => match s.to_string().strip_prefix("Vec<") {
  128. None => IdlType::Defined(s.to_string()),
  129. Some(inner) => {
  130. let inner_ty = Self::from_str(
  131. inner
  132. .strip_suffix(">")
  133. .ok_or(anyhow::anyhow!("Invalid option"))?,
  134. )?;
  135. IdlType::Vec(Box::new(inner_ty))
  136. }
  137. },
  138. Some(inner) => {
  139. let inner_ty = Self::from_str(
  140. inner
  141. .strip_suffix(">")
  142. .ok_or(anyhow::anyhow!("Invalid option"))?,
  143. )?;
  144. IdlType::Option(Box::new(inner_ty))
  145. }
  146. },
  147. };
  148. Ok(r)
  149. }
  150. }
  151. #[derive(Debug, Clone, Serialize, Deserialize)]
  152. pub struct IdlErrorCode {
  153. pub code: u32,
  154. pub name: String,
  155. #[serde(skip_serializing_if = "Option::is_none", default)]
  156. pub msg: Option<String>,
  157. }