idl.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. Vec(Box<IdlType>),
  75. }
  76. #[derive(Debug, Serialize, Deserialize)]
  77. pub struct IdlTypePublicKey;
  78. impl std::str::FromStr for IdlType {
  79. type Err = anyhow::Error;
  80. fn from_str(s: &str) -> Result<Self, Self::Err> {
  81. // Eliminate whitespace.
  82. let mut s = s.to_string();
  83. s.retain(|c| !c.is_whitespace());
  84. let r = match s.as_str() {
  85. "bool" => IdlType::Bool,
  86. "u8" => IdlType::U8,
  87. "i8" => IdlType::I8,
  88. "u16" => IdlType::U16,
  89. "i16" => IdlType::I16,
  90. "u32" => IdlType::U32,
  91. "i32" => IdlType::I32,
  92. "u64" => IdlType::U64,
  93. "i64" => IdlType::I64,
  94. "Vec<u8>" => IdlType::Bytes,
  95. "String" => IdlType::String,
  96. "Pubkey" => IdlType::PublicKey,
  97. _ => match s.to_string().strip_prefix("Option<") {
  98. None => match s.to_string().strip_prefix("Vec<") {
  99. None => IdlType::Defined(s.to_string()),
  100. Some(inner) => {
  101. let inner_ty = Self::from_str(
  102. inner
  103. .strip_suffix(">")
  104. .ok_or(anyhow::anyhow!("Invalid option"))?,
  105. )?;
  106. IdlType::Vec(Box::new(inner_ty))
  107. }
  108. },
  109. Some(inner) => {
  110. let inner_ty = Self::from_str(
  111. inner
  112. .strip_suffix(">")
  113. .ok_or(anyhow::anyhow!("Invalid option"))?,
  114. )?;
  115. IdlType::Option(Box::new(inner_ty))
  116. }
  117. },
  118. };
  119. Ok(r)
  120. }
  121. }