diff --git a/examples/load_save.rs b/examples/load_save.rs index dbcc9149..175746f1 100644 --- a/examples/load_save.rs +++ b/examples/load_save.rs @@ -1,3 +1,5 @@ +//! A small program that times the loading and saving of a UFO file. + use std::env; use std::ffi::OsStr; use std::path::PathBuf; @@ -5,49 +7,44 @@ use std::time::{Duration, Instant}; use norad::Font; -fn main() { - let (input, output) = get_path_or_exit(); - - let start_load = Instant::now(); - let mut my_ufo = match Font::load(input) { - Ok(v) => v, - Err(e) => { - eprintln!("Loading the UFO failed: {}", e); - std::process::exit(1); - } - }; - let duration_load = start_load.elapsed(); - let duration_load_str = format_time(duration_load); - - my_ufo.meta.creator = "org.linebender.norad".to_string(); +static HELP: &str = " +USAGE: + open_ufo PATH [OUTPATH] - let start_write = Instant::now(); - my_ufo.save(output).unwrap(); - let duration_write = start_write.elapsed(); - let duration_write_str = format_time(duration_write); +If an OUTPATH is provided, the UFO will be saved after opening. +"; - println!("Loaded UFO in {}, wrote it in {}.", duration_load_str, duration_write_str); +macro_rules! exit_err { + ($($arg:tt)*) => ({ + eprintln!($($arg)*); + eprintln!("{}", HELP); + std::process::exit(1); + }) } -fn get_path_or_exit() -> (PathBuf, PathBuf) { - let mut args = env::args().skip(1); +fn main() { + let args = Args::get_from_env_or_exit(); - let input = match args.next().map(PathBuf::from) { - Some(ref p) if p.exists() && p.extension() == Some(OsStr::new("ufo")) => p.to_owned(), - _ => { - eprintln!("Please supply a path to a UFO to read from"); - std::process::exit(1); - } - }; - let output = match args.next().map(PathBuf::from) { - Some(ref p) if p.extension() == Some(OsStr::new("ufo")) => p.to_owned(), - _ => { - eprintln!("Please supply a path to write the UFO to"); - std::process::exit(1); - } - }; + let start = Instant::now(); + let ufo = Font::load(&args.path).expect("failed to load file"); + + let duration = start.elapsed(); + let time_str = format_time(duration); + let font_name = ufo + .font_info + .as_ref() + .and_then(|f| f.family_name.clone()) + .unwrap_or_else(|| "an unnamed font".into()); - (input, output) + println!("loaded {} glyphs from {} in {}.", ufo.glyph_count(), font_name, time_str); + + if let Some(outpath) = args.outpath { + let start = Instant::now(); + ufo.save(outpath).expect("failed to save UFO"); + let duration = start.elapsed(); + let time_str = format_time(duration); + println!("wrote UFO to disk in {}", time_str); + } } fn format_time(duration: Duration) -> String { @@ -55,3 +52,26 @@ fn format_time(duration: Duration) -> String { let millis = duration.subsec_millis(); format!("{}.{}s", secs, millis) } + +struct Args { + path: PathBuf, + outpath: Option, +} + +impl Args { + fn get_from_env_or_exit() -> Self { + let mut args = env::args().skip(1); + let path = match args.next().map(PathBuf::from) { + Some(ref p) if p.exists() && p.extension() == Some(OsStr::new("ufo")) => p.to_owned(), + Some(ref p) => exit_err!("path {:?} is not an existing .ufo file, exiting", p), + None => exit_err!("Please supply a path to a .ufo file"), + }; + + let outpath = args.next().map(PathBuf::from); + if outpath.as_ref().map(|p| p.exists()).unwrap_or(false) { + exit_err!("outpath {} already exists, exiting", outpath.unwrap().display()); + } + + Args { path, outpath } + } +} diff --git a/examples/open_ufo.rs b/examples/open_ufo.rs deleted file mode 100644 index 95848a38..00000000 --- a/examples/open_ufo.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! A small program that loads a UFO file and prints the glyph count. - -use std::env; -use std::ffi::OsStr; -use std::path::PathBuf; -use std::time::{Duration, Instant}; - -use norad::Font; - -fn main() { - let path = get_path_or_exit(); - - let start = Instant::now(); - let ufo = Font::load(&path).expect("failed to load file"); - - let duration = start.elapsed(); - let time_str = format_time(duration); - let font_name = ufo - .font_info - .as_ref() - .and_then(|f| f.family_name.clone()) - .unwrap_or_else(|| "an unnamed font".into()); - - println!("loaded {} glyphs from {} in {}.", ufo.glyph_count(), font_name, time_str); -} - -fn get_path_or_exit() -> PathBuf { - match env::args().skip(1).next().map(PathBuf::from) { - Some(ref p) if p.exists() && p.extension() == Some(OsStr::new("ufo")) => p.to_owned(), - Some(ref p) => { - eprintln!("path {:?} is not an existing .glif file, exiting", p); - std::process::exit(1); - } - None => { - eprintln!("Please supply a path to a glif file"); - std::process::exit(1); - } - } -} - -fn format_time(duration: Duration) -> String { - let secs = duration.as_secs(); - let millis = duration.subsec_millis(); - format!("{}.{}s", secs, millis) -}