mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-22 17:18:01 +00:00
CLI Tool: Allow using --file - to read metadata from stdin (#1336)
* allow using --file - to read from stdin * add test for path and url parsing --------- Co-authored-by: James Wilson <james@jsdw.me>
This commit is contained in:
+98
-18
@@ -21,7 +21,7 @@ pub struct FileOrUrl {
|
||||
pub url: Option<Url>,
|
||||
/// The path to the encoded metadata file.
|
||||
#[clap(long, value_parser)]
|
||||
pub file: Option<PathBuf>,
|
||||
pub file: Option<PathOrStdIn>,
|
||||
/// Specify the metadata version.
|
||||
///
|
||||
/// - "latest": Use the latest stable version available.
|
||||
@@ -33,6 +33,54 @@ pub struct FileOrUrl {
|
||||
pub version: Option<MetadataVersion>,
|
||||
}
|
||||
|
||||
impl FromStr for FileOrUrl {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if let Ok(path) = PathOrStdIn::from_str(s) {
|
||||
Ok(FileOrUrl {
|
||||
url: None,
|
||||
file: Some(path),
|
||||
version: None,
|
||||
})
|
||||
} else {
|
||||
Url::parse(s)
|
||||
.map_err(|_| "Parsing Path or Uri failed.")
|
||||
.map(|uri| FileOrUrl {
|
||||
url: Some(uri),
|
||||
file: None,
|
||||
version: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If `--path -` is provided, read bytes for metadata from stdin
|
||||
const STDIN_PATH_NAME: &str = "-";
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PathOrStdIn {
|
||||
Path(PathBuf),
|
||||
StdIn,
|
||||
}
|
||||
|
||||
impl FromStr for PathOrStdIn {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let s = s.trim();
|
||||
if s == STDIN_PATH_NAME {
|
||||
Ok(PathOrStdIn::StdIn)
|
||||
} else {
|
||||
let path = std::path::Path::new(s);
|
||||
if path.exists() {
|
||||
Ok(PathOrStdIn::Path(PathBuf::from(path)))
|
||||
} else {
|
||||
Err("Path does not exist.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FileOrUrl {
|
||||
/// Fetch the metadata bytes.
|
||||
pub async fn fetch(&self) -> color_eyre::Result<Vec<u8>> {
|
||||
@@ -42,12 +90,20 @@ impl FileOrUrl {
|
||||
eyre::bail!("specify one of `--url` or `--file` but not both")
|
||||
}
|
||||
// Load from --file path
|
||||
(Some(path), None, None) => {
|
||||
(Some(PathOrStdIn::Path(path)), None, None) => {
|
||||
let mut file = fs::File::open(path)?;
|
||||
let mut bytes = Vec::new();
|
||||
file.read_to_end(&mut bytes)?;
|
||||
Ok(bytes)
|
||||
}
|
||||
(Some(PathOrStdIn::StdIn), None, None) => {
|
||||
let res = std::io::stdin().bytes().collect::<Result<Vec<u8>, _>>();
|
||||
|
||||
match res {
|
||||
Ok(bytes) => Ok(bytes),
|
||||
Err(err) => eyre::bail!("reading bytes from stdin (`--file -`) failed: {err}"),
|
||||
}
|
||||
}
|
||||
// Cannot load the metadata from the file and specify a version to fetch.
|
||||
(Some(_), None, Some(_)) => {
|
||||
// Note: we could provide the ability to convert between metadata versions
|
||||
@@ -88,25 +144,49 @@ pub fn with_indent(s: String, indent: usize) -> String {
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
impl FromStr for FileOrUrl {
|
||||
type Err = &'static str;
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::utils::{FileOrUrl, PathOrStdIn};
|
||||
use std::str::FromStr;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let path = std::path::Path::new(s);
|
||||
if path.exists() {
|
||||
#[test]
|
||||
fn parsing() {
|
||||
assert!(matches!(
|
||||
FileOrUrl::from_str("-"),
|
||||
Ok(FileOrUrl {
|
||||
url: None,
|
||||
file: Some(PathBuf::from(s)),
|
||||
version: None,
|
||||
file: Some(PathOrStdIn::StdIn),
|
||||
version: None
|
||||
})
|
||||
} else {
|
||||
Url::parse(s)
|
||||
.map_err(|_| "no path or uri could be crated")
|
||||
.map(|uri| FileOrUrl {
|
||||
url: Some(uri),
|
||||
file: None,
|
||||
version: None,
|
||||
})
|
||||
}
|
||||
),);
|
||||
|
||||
assert!(matches!(
|
||||
FileOrUrl::from_str(" - "),
|
||||
Ok(FileOrUrl {
|
||||
url: None,
|
||||
file: Some(PathOrStdIn::StdIn),
|
||||
version: None
|
||||
})
|
||||
),);
|
||||
|
||||
assert!(matches!(
|
||||
FileOrUrl::from_str("./src/main.rs"),
|
||||
Ok(FileOrUrl {
|
||||
url: None,
|
||||
file: Some(PathOrStdIn::Path(_)),
|
||||
version: None
|
||||
})
|
||||
),);
|
||||
|
||||
assert!(FileOrUrl::from_str("./src/i_dont_exist.rs").is_err());
|
||||
|
||||
assert!(matches!(
|
||||
FileOrUrl::from_str("https://github.com/paritytech/subxt"),
|
||||
Ok(FileOrUrl {
|
||||
url: Some(_),
|
||||
file: None,
|
||||
version: None
|
||||
})
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user