Просмотр исходного кода

[clap-v3-utils] Add functions to directly parse from `SignerSource` (#1062)

* add `try_get_keypair` and `try_get_keypairs`

* add `try_get_signer` and `try_get_signers`

* add `try_get_pubkey` and `try_get_pubkeys`

* add `try_resolve`
samkim-crypto 1 год назад
Родитель
Сommit
12d009ecec
1 измененных файлов с 108 добавлено и 1 удалено
  1. 108 1
      clap-v3-utils/src/input_parsers/signer.rs

+ 108 - 1
clap-v3-utils/src/input_parsers/signer.rs

@@ -1,6 +1,7 @@
 use {
     crate::keypair::{
-        keypair_from_seed_phrase, pubkey_from_path, resolve_signer_from_path, signer_from_path,
+        keypair_from_seed_phrase, keypair_from_source, pubkey_from_path, pubkey_from_source,
+        resolve_signer_from_path, resolve_signer_from_source, signer_from_path, signer_from_source,
         ASK_KEYWORD, SKIP_SEED_PHRASE_VALIDATION_ARG,
     },
     clap::{builder::ValueParser, ArgMatches},
@@ -89,6 +90,112 @@ impl SignerSource {
         }
     }
 
+    pub fn try_get_keypair(
+        matches: &ArgMatches,
+        name: &str,
+    ) -> Result<Option<Keypair>, Box<dyn error::Error>> {
+        let source = matches.try_get_one::<Self>(name)?;
+        if let Some(source) = source {
+            keypair_from_source(matches, source, name, true).map(Some)
+        } else {
+            Ok(None)
+        }
+    }
+
+    pub fn try_get_keypairs(
+        matches: &ArgMatches,
+        name: &str,
+    ) -> Result<Option<Vec<Keypair>>, Box<dyn error::Error>> {
+        let sources = matches.try_get_many::<Self>(name)?;
+        if let Some(sources) = sources {
+            let keypairs = sources
+                .filter_map(|source| keypair_from_source(matches, source, name, true).ok())
+                .collect();
+            Ok(Some(keypairs))
+        } else {
+            Ok(None)
+        }
+    }
+
+    #[allow(clippy::type_complexity)]
+    pub fn try_get_signer(
+        matches: &ArgMatches,
+        name: &str,
+        wallet_manager: &mut Option<Rc<RemoteWalletManager>>,
+    ) -> Result<Option<(Box<dyn Signer>, Pubkey)>, Box<dyn error::Error>> {
+        let source = matches.try_get_one::<Self>(name)?;
+        if let Some(source) = source {
+            let signer = signer_from_source(matches, source, name, wallet_manager)?;
+            let signer_pubkey = signer.pubkey();
+            Ok(Some((signer, signer_pubkey)))
+        } else {
+            Ok(None)
+        }
+    }
+
+    #[allow(clippy::type_complexity)]
+    pub fn try_get_signers(
+        matches: &ArgMatches,
+        name: &str,
+        wallet_manager: &mut Option<Rc<RemoteWalletManager>>,
+    ) -> Result<Option<Vec<(Box<dyn Signer>, Pubkey)>>, Box<dyn error::Error>> {
+        let sources = matches.try_get_many::<Self>(name)?;
+        if let Some(sources) = sources {
+            let signers = sources
+                .filter_map(|source| {
+                    let signer = signer_from_source(matches, source, name, wallet_manager).ok()?;
+                    let signer_pubkey = signer.pubkey();
+                    Some((signer, signer_pubkey))
+                })
+                .collect();
+            Ok(Some(signers))
+        } else {
+            Ok(None)
+        }
+    }
+
+    pub fn try_get_pubkey(
+        matches: &ArgMatches,
+        name: &str,
+        wallet_manager: &mut Option<Rc<RemoteWalletManager>>,
+    ) -> Result<Option<Pubkey>, Box<dyn error::Error>> {
+        let source = matches.try_get_one::<Self>(name)?;
+        if let Some(source) = source {
+            pubkey_from_source(matches, source, name, wallet_manager).map(Some)
+        } else {
+            Ok(None)
+        }
+    }
+
+    pub fn try_get_pubkeys(
+        matches: &ArgMatches,
+        name: &str,
+        wallet_manager: &mut Option<Rc<RemoteWalletManager>>,
+    ) -> Result<Option<Vec<Pubkey>>, Box<dyn std::error::Error>> {
+        let sources = matches.try_get_many::<Self>(name)?;
+        if let Some(sources) = sources {
+            let pubkeys = sources
+                .filter_map(|source| pubkey_from_source(matches, source, name, wallet_manager).ok())
+                .collect();
+            Ok(Some(pubkeys))
+        } else {
+            Ok(None)
+        }
+    }
+
+    pub fn try_resolve(
+        matches: &ArgMatches,
+        name: &str,
+        wallet_manager: &mut Option<Rc<RemoteWalletManager>>,
+    ) -> Result<Option<String>, Box<dyn std::error::Error>> {
+        let source = matches.try_get_one::<Self>(name)?;
+        if let Some(source) = source {
+            resolve_signer_from_source(matches, source, name, wallet_manager)
+        } else {
+            Ok(None)
+        }
+    }
+
     pub fn parse<S: AsRef<str>>(source: S) -> Result<Self, SignerSourceError> {
         let source = source.as_ref();
         let source = {