idl.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. use serde::{Deserialize, Serialize};
  2. #[derive(Debug, Serialize, Deserialize)]
  3. pub struct Idl {
  4. pub version: String,
  5. pub name: String,
  6. pub instructions: Vec<IdlInstruction>,
  7. #[serde(skip_serializing_if = "Vec::is_empty", default)]
  8. pub accounts: Vec<IdlTypeDef>,
  9. #[serde(skip_serializing_if = "Vec::is_empty", default)]
  10. pub types: Vec<IdlTypeDef>,
  11. #[serde(skip_serializing_if = "Option::is_none", default)]
  12. pub metadata: Option<serde_json::Value>,
  13. }
  14. #[derive(Debug, Serialize, Deserialize)]
  15. pub struct IdlInstruction {
  16. pub name: String,
  17. pub accounts: Vec<IdlAccount>,
  18. pub args: Vec<IdlField>,
  19. }
  20. #[derive(Debug, Serialize, Deserialize)]
  21. #[serde(rename_all = "camelCase")]
  22. pub struct IdlAccount {
  23. pub name: String,
  24. pub is_mut: bool,
  25. pub is_signer: bool,
  26. }
  27. #[derive(Debug, Serialize, Deserialize)]
  28. pub struct IdlField {
  29. pub name: String,
  30. #[serde(rename = "type")]
  31. pub ty: IdlType,
  32. }
  33. #[derive(Debug, Serialize, Deserialize)]
  34. pub struct IdlTypeDef {
  35. pub name: String,
  36. #[serde(rename = "type")]
  37. pub ty: IdlTypeDefTy,
  38. }
  39. #[derive(Debug, Serialize, Deserialize)]
  40. #[serde(rename_all = "lowercase", tag = "kind")]
  41. pub enum IdlTypeDefTy {
  42. Struct { fields: Vec<IdlField> },
  43. Enum { variants: Vec<EnumVariant> },
  44. }
  45. #[derive(Debug, Serialize, Deserialize)]
  46. pub struct EnumVariant {
  47. pub name: String,
  48. #[serde(skip_serializing_if = "Option::is_none", default)]
  49. pub fields: Option<EnumFields>,
  50. }
  51. #[derive(Debug, Serialize, Deserialize)]
  52. #[serde(untagged)]
  53. pub enum EnumFields {
  54. Named(Vec<IdlField>),
  55. Tuple(Vec<IdlType>),
  56. }
  57. #[derive(Debug, Serialize, Deserialize)]
  58. #[serde(rename_all = "camelCase")]
  59. pub enum IdlType {
  60. Bool,
  61. U8,
  62. I8,
  63. U16,
  64. I16,
  65. U32,
  66. I32,
  67. U64,
  68. I64,
  69. Bytes,
  70. String,
  71. PublicKey,
  72. Defined(String),
  73. Option(Box<IdlType>),
  74. }
  75. #[derive(Debug, Serialize, Deserialize)]
  76. pub struct IdlTypePublicKey;
  77. impl std::str::FromStr for IdlType {
  78. type Err = anyhow::Error;
  79. fn from_str(s: &str) -> Result<Self, Self::Err> {
  80. // Eliminate whitespace.
  81. let mut s = s.to_string();
  82. s.retain(|c| !c.is_whitespace());
  83. let r = match s.as_str() {
  84. "bool" => IdlType::Bool,
  85. "u8" => IdlType::U8,
  86. "i8" => IdlType::I8,
  87. "u16" => IdlType::U16,
  88. "i16" => IdlType::I16,
  89. "u32" => IdlType::U32,
  90. "i32" => IdlType::I32,
  91. "u64" => IdlType::U64,
  92. "i64" => IdlType::I64,
  93. "Vec<u8>" => IdlType::Bytes,
  94. "String" => IdlType::String,
  95. "Pubkey" => IdlType::PublicKey,
  96. _ => match s.to_string().strip_prefix("Option<") {
  97. None => IdlType::Defined(s.to_string()),
  98. Some(inner) => {
  99. let inner_ty = Self::from_str(
  100. inner
  101. .strip_suffix(">")
  102. .ok_or(anyhow::anyhow!("Invalid option"))?,
  103. )?;
  104. IdlType::Option(Box::new(inner_ty))
  105. }
  106. },
  107. };
  108. Ok(r)
  109. }
  110. }