Browse Source

Make the new IDL features explicit (#2582)

acheron 2 năm trước cách đây
mục cha
commit
cad868a052
5 tập tin đã thay đổi với 32 bổ sung30 xóa
  1. 1 0
      CHANGELOG.md
  2. 0 1
      cli/src/lib.rs
  3. 8 8
      lang/syn/Cargo.toml
  4. 4 2
      lang/syn/src/idl/mod.rs
  5. 19 19
      lang/syn/src/idl/parse/file.rs

+ 1 - 0
CHANGELOG.md

@@ -31,6 +31,7 @@ The minor version will be incremented upon a breaking change and the patch versi
 ### Breaking
 
 - syn: `idl` feature has been replaced with `idl-build`, `idl-parse` and `idl-types` features ([#2011](https://github.com/coral-xyz/anchor/pull/2011)).
+- syn: IDL `parse` method now returns `Result<Idl>` instead of `Result<Option<Idl>>` ([#2582](https://github.com/coral-xyz/anchor/pull/2582)).
 
 ## [0.28.0] - 2023-06-09
 

+ 0 - 1
cli/src/lib.rs

@@ -2292,7 +2292,6 @@ fn generate_idl_parse(
     safety_checks: bool,
 ) -> Result<Idl> {
     anchor_syn::idl::parse::file::parse(path, version, seeds_feature, no_docs, safety_checks)
-        .and_then(|maybe_idl| maybe_idl.ok_or_else(|| anyhow!("Failed to parse IDL")))
 }
 
 /// Generate IDL with the build method.

+ 8 - 8
lang/syn/Cargo.toml

@@ -9,22 +9,22 @@ rust-version = "1.60"
 edition = "2021"
 
 [features]
-allow-missing-optionals = []
-init-if-needed = []
-idl-build = []
-idl-parse = []
-idl-types = []
-hash = []
 default = []
+allow-missing-optionals = []
 anchor-debug = []
-seeds = []
 event-cpi = []
+hash = []
+idl-build = ["idl-parse", "idl-types"]
+idl-parse = ["idl-types"]
+idl-types = []
+init-if-needed = []
+seeds = []
 
 [dependencies]
 anyhow = "1"
 bs58 = "0.5"
 heck = "0.3"
-proc-macro2 = { version = "1", features=["span-locations"]}
+proc-macro2 = { version = "1", features = ["span-locations"] }
 quote = "1"
 serde = { version = "1", features = ["derive"] }
 serde_json = "1"

+ 4 - 2
lang/syn/src/idl/mod.rs

@@ -1,6 +1,8 @@
 #[cfg(feature = "idl-build")]
 pub mod build;
-#[cfg(any(feature = "idl-parse", feature = "idl-build"))]
+
+#[cfg(feature = "idl-parse")]
 pub mod parse;
-#[cfg(any(feature = "idl-types", feature = "idl-build", feature = "idl-parse"))]
+
+#[cfg(feature = "idl-types")]
 pub mod types;

+ 19 - 19
lang/syn/src/idl/parse/file.rs

@@ -3,6 +3,7 @@ use crate::parser::context::CrateContext;
 use crate::parser::{self, accounts, docs, error, program};
 use crate::Ty;
 use crate::{AccountField, AccountsStruct};
+use anyhow::anyhow;
 use anyhow::Result;
 use heck::MixedCase;
 use quote::ToTokens;
@@ -19,28 +20,25 @@ const DERIVE_NAME: &str = "Accounts";
 // TODO: share this with `anchor_lang` crate.
 const ERROR_CODE_OFFSET: u32 = 6000;
 
-// Parse an entire interface file.
+/// Parse an entire interface file.
 pub fn parse(
     path: impl AsRef<Path>,
     version: String,
     seeds_feature: bool,
     no_docs: bool,
     safety_checks: bool,
-) -> Result<Option<Idl>> {
+) -> Result<Idl> {
     let ctx = CrateContext::parse(path)?;
     if safety_checks {
         ctx.safety_checks()?;
     }
 
-    let program_mod = match parse_program_mod(&ctx) {
-        None => return Ok(None),
-        Some(m) => m,
-    };
-    let mut p = program::parse(program_mod)?;
+    let program_mod = parse_program_mod(&ctx)?;
+    let mut program = program::parse(program_mod)?;
 
     if no_docs {
-        p.docs = None;
-        for ix in &mut p.ixs {
+        program.docs = None;
+        for ix in &mut program.ixs {
             ix.docs = None;
         }
     }
@@ -59,7 +57,7 @@ pub fn parse(
             .collect::<Vec<IdlErrorCode>>()
     });
 
-    let instructions = p
+    let instructions = program
         .ixs
         .iter()
         .map(|ix| {
@@ -157,10 +155,10 @@ pub fn parse(
         .map(|c: &&syn::ItemConst| to_idl_const(c))
         .collect::<Vec<IdlConst>>();
 
-    Ok(Some(Idl {
+    Ok(Idl {
         version,
-        name: p.name.to_string(),
-        docs: p.docs.clone(),
+        name: program.name.to_string(),
+        docs: program.docs.clone(),
         instructions,
         types,
         accounts,
@@ -172,11 +170,11 @@ pub fn parse(
         errors: error_codes,
         metadata: None,
         constants,
-    }))
+    })
 }
 
-// Parse the main program mod.
-fn parse_program_mod(ctx: &CrateContext) -> Option<syn::ItemMod> {
+/// Parse the main program mod.
+fn parse_program_mod(ctx: &CrateContext) -> Result<syn::ItemMod> {
     let root = ctx.root_module();
     let mods = root
         .items()
@@ -195,10 +193,12 @@ fn parse_program_mod(ctx: &CrateContext) -> Option<syn::ItemMod> {
             _ => None,
         })
         .collect::<Vec<_>>();
-    if mods.len() != 1 {
-        return None;
+
+    match mods.len() {
+        0 => Err(anyhow!("Program module not found")),
+        1 => Ok(mods[0].clone()),
+        _ => Err(anyhow!("Multiple program modules are not allowed")),
     }
-    Some(mods[0].clone())
 }
 
 fn parse_error_enum(ctx: &CrateContext) -> Option<syn::ItemEnum> {