aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs142
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(())
+}