diff --git a/clap-utils/src/keypair.rs b/clap-utils/src/keypair.rs index bace2124137725..68a6c9b74f131a 100644 --- a/clap-utils/src/keypair.rs +++ b/clap-utils/src/keypair.rs @@ -211,7 +211,17 @@ pub(crate) fn parse_signer_source>( source: S, ) -> Result { let source = source.as_ref(); - match uriparse::URIReference::try_from(source) { + let source = { + #[cfg(target_family = "windows")] + { + source.replace("\\", "/") + } + #[cfg(not(target_family = "windows"))] + { + source.to_string() + } + }; + match uriparse::URIReference::try_from(source.as_str()) { Err(_) => Err(SignerSourceError::UnrecognizedSource), Ok(uri) => { if let Some(scheme) = uri.scheme() { @@ -231,18 +241,24 @@ pub(crate) fn parse_signer_source>( legacy: false, }), SIGNER_SOURCE_STDIN => Ok(SignerSource::new(SignerSourceKind::Stdin)), - _ => Err(SignerSourceError::UnrecognizedSource), + _ => { + #[cfg(target_family = "windows")] + // On Windows, an absolute path's drive letter will be parsed as the URI + // scheme. Assume a filepath source in case of a single character shceme. + if scheme.len() == 1 { + return Ok(SignerSource::new(SignerSourceKind::Filepath(source))); + } + Err(SignerSourceError::UnrecognizedSource) + } } } else { - match source { + match source.as_str() { "-" => Ok(SignerSource::new(SignerSourceKind::Stdin)), ASK_KEYWORD => Ok(SignerSource::new_legacy(SignerSourceKind::Prompt)), - _ => match Pubkey::from_str(source) { + _ => match Pubkey::from_str(source.as_str()) { Ok(pubkey) => Ok(SignerSource::new(SignerSourceKind::Pubkey(pubkey))), - Err(_) => std::fs::metadata(source) - .map(|_| { - SignerSource::new(SignerSourceKind::Filepath(source.to_string())) - }) + Err(_) => std::fs::metadata(source.as_str()) + .map(|_| SignerSource::new(SignerSourceKind::Filepath(source))) .map_err(|err| err.into()), }, }