idl.rs 3.0 KB

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