use rpki::ccr::dump::dump_content_info_json_value; #[derive(Debug, Default, PartialEq, Eq)] struct Args { ccr_path: Option, } fn usage() -> &'static str { "Usage: ccr_dump --ccr " } fn parse_args(argv: &[String]) -> Result { let mut args = Args::default(); let mut i = 1usize; while i < argv.len() { match argv[i].as_str() { "--help" | "-h" => return Err(usage().to_string()), "--ccr" => { i += 1; let v = argv.get(i).ok_or("--ccr requires a value")?; args.ccr_path = Some(v.into()); } other => return Err(format!("unknown argument: {other}\n{}", usage())), } i += 1; } if args.ccr_path.is_none() { return Err(format!("--ccr is required\n{}", usage())); } Ok(args) } fn main() -> Result<(), String> { let args = parse_args(&std::env::args().collect::>())?; let ccr_path = args.ccr_path.as_ref().unwrap(); let bytes = std::fs::read(ccr_path) .map_err(|e| format!("read ccr failed: {}: {e}", ccr_path.display()))?; let json = dump_content_info_json_value(&bytes).map_err(|e| e.to_string())?; println!( "{}", serde_json::to_string_pretty(&json).map_err(|e| e.to_string())? ); Ok(()) } #[cfg(test)] mod tests { use super::*; #[test] fn parse_args_accepts_ccr_path() { let argv = vec![ "ccr_dump".to_string(), "--ccr".to_string(), "a.ccr".to_string(), ]; let args = parse_args(&argv).expect("parse"); assert_eq!( args.ccr_path.as_deref(), Some(std::path::Path::new("a.ccr")) ); } #[test] fn parse_args_rejects_missing_required_ccr() { let argv = vec!["ccr_dump".to_string()]; let err = parse_args(&argv).unwrap_err(); assert!(err.contains("--ccr is required"), "{err}"); } }