diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..d443b18 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,142 @@ +use std::fmt; +use std::fs::{read_to_string, write}; +use std::io::{Error as IoError, Result as IoResult}; +use std::path::PathBuf; +use std::str::FromStr; +use wmap_renderer::{Configuration, StageType, render_to_png, render_to_svg}; + +use thiserror::Error; + +#[derive(Debug)] +enum ImageType { + Png, + Svg, +} + +impl fmt::Display for ImageType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + ImageType::Png => write!(f, "png"), + ImageType::Svg => write!(f, "svg"), + } + } +} + +#[derive(Error, Debug)] +pub enum WmapError { + #[error("unknown image type.")] + UnknownImageType, + #[error("unknown stage type.")] + UnknownStageType, +} + +impl FromStr for ImageType { + type Err = WmapError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s.to_lowercase().as_str() { + "png" => Ok(ImageType::Png), + "svg" => Ok(ImageType::Svg), + _ => Err(Self::Err::UnknownImageType), + } + } +} + +fn stage_from_str(s: &str) -> Option<StageType> { + match s.to_lowercase().as_str() { + "activities" => Some(StageType::Activities), + "behavior" => Some(StageType::Behavior), + "certainty" => Some(StageType::Certainty), + "comparison" => Some(StageType::Comparison), + "cynefin" => Some(StageType::Cynefin), + "data" => Some(StageType::Data), + "decision_drivers" => Some(StageType::DecisionDrivers), + "efficiency" => Some(StageType::Efficiency), + "failure" => Some(StageType::Failure), + "focus_of_value" => Some(StageType::FocusOfValue), + "knowledge" => Some(StageType::Knowledge), + "knowledge_management" => Some(StageType::KnowledgeManagement), + "market" => Some(StageType::Market), + "market_action" => Some(StageType::MarketAction), + "market_perception" => Some(StageType::MarketPerception), + "perception_in_industry" => Some(StageType::PerceptionInIndustry), + "practice" => Some(StageType::Practice), + "publication_types" => Some(StageType::PublicationTypes), + "ubiquity" => Some(StageType::Ubiquity), + "understanding" => Some(StageType::Understanding), + "user_perception" => Some(StageType::UserPerception), + "evolution_stage" => Some(StageType::EvolutionStage), + _ => None, + } +} + +struct Arguments { + input: PathBuf, + output: PathBuf, + stage: StageType, + image_type: ImageType, +} + +fn parse_arguments() -> Result<Arguments, lexopt::Error> { + use lexopt::prelude::*; + + let mut input = None; + let mut output: String = "".to_string(); + let mut stage = StageType::Activities; + let mut image_type = ImageType::Png; + + let mut argument_parser = lexopt::Parser::from_env(); + while let Some(argument) = argument_parser.next()? { + match argument { + Short('t') | Long("type") => { + image_type = argument_parser.value()?.parse()?; + } + Short('s') | Long("stage") => { + let stage_string: String = argument_parser.value()?.parse()?; + stage = stage_from_str(&stage_string).ok_or("Invalid stage name")? + } + Short('o') | Long("output") => { + output = argument_parser.value()?.parse()?; + } + Value(value) if input.is_none() => { + input = Some(value.string()?); + } + Short('h') | Long("help") => { + println!("Usage: wmap [-t|--type=png|svg] [-o=OUTPUT_FILE] INPUT_FILE"); + std::process::exit(0); + } + _ => return Err(argument.unexpected()), + } + } + let input = PathBuf::from(input.ok_or("missing argument INPUT_FILE")?); + let output = match output.is_empty() { + true => input.with_extension(image_type.to_string()), + false => PathBuf::from(output), + }; + + Ok(Arguments { + input, + output, + stage, + image_type, + }) +} + +fn main() -> IoResult<()> { + let arguments = parse_arguments().map_err(|_| IoError::other("Unable to parse arguments"))?; + + arguments.input.try_exists()?; + let source = read_to_string(arguments.input)?; + let map = wmap_parser::parse(&source); + let configuration = Configuration::default(); + + let image_data = match arguments.image_type { + ImageType::Png => render_to_png(&map, arguments.stage, &configuration) + .map_err(|_| IoError::other("Unable to render PNG"))?, + ImageType::Svg => render_to_svg(&map, arguments.stage, &configuration) + .map_err(|_| IoError::other("Unable to render SVG"))? + .into_bytes(), + }; + write(arguments.output, image_data)?; + Ok(()) +} |