use crate::{Command, DocumentCommand, FileFormat, Options, TransformCommand};
use atelier_lib::assembler::SearchPath;
use somedoc::write::OutputFormat;
use std::error::Error;
use std::path::PathBuf;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "cargo-atelier", about = "Tools for the Smithy IDL.")]
struct CommandLine {
#[structopt(long, short = "v", parse(from_occurrences))]
verbose: i8,
#[cfg(feature = "color")]
#[structopt(long)]
no_color: bool,
#[structopt(subcommand)]
cmd: SubCommand,
}
#[derive(Debug, StructOpt)]
struct FileInput {
#[structopt(long, short)]
in_file: Vec<PathBuf>,
#[structopt(long, short, conflicts_with = "search_env")]
default_search_env: bool,
#[structopt(long, short, conflicts_with = "default_search_env")]
search_env: Option<String>,
}
#[derive(Debug, StructOpt)]
enum SubCommand {
Lint {
#[structopt(flatten)]
file_input: FileInput,
},
Validate {
#[structopt(flatten)]
file_input: FileInput,
},
Convert {
#[structopt(flatten)]
file_input: FileInput,
#[structopt(long, short)]
out_file: Option<PathBuf>,
#[structopt(short, long, default_value = "json")]
write_format: FileFormat,
#[structopt(short, long)]
namespace: Option<String>,
},
Document {
#[structopt(flatten)]
file_input: FileInput,
#[structopt(long, short)]
out_file: Option<PathBuf>,
#[structopt(short, long, default_value = "markdown")]
write_format: OutputFormat,
},
}
pub fn parse() -> Result<Command, Box<dyn Error>> {
let args = CommandLine::from_iter(check_command_line());
let options = Options {
use_color: !args.no_color,
};
match args.cmd {
SubCommand::Lint {
file_input:
FileInput {
in_file,
default_search_env,
search_env,
},
} => Ok(Command::Lint(
in_file,
make_search_path(default_search_env, search_env),
options,
)),
SubCommand::Validate {
file_input:
FileInput {
in_file,
default_search_env,
search_env,
},
} => Ok(Command::Validate(
in_file,
make_search_path(default_search_env, search_env),
options,
)),
SubCommand::Convert {
file_input:
FileInput {
in_file,
default_search_env,
search_env,
},
out_file,
write_format,
namespace,
} => Ok(Command::Convert(
TransformCommand {
input_files: in_file,
output_file: out_file,
output_format: write_format,
namespace,
},
make_search_path(default_search_env, search_env),
options,
)),
SubCommand::Document {
file_input:
FileInput {
in_file,
default_search_env,
search_env,
},
out_file,
write_format,
} => Ok(Command::Document(
DocumentCommand {
input_files: in_file,
output_file: out_file,
output_format: write_format,
},
make_search_path(default_search_env, search_env),
options,
)),
}
}
fn check_command_line() -> Vec<String> {
use std::env;
let mut args = env::args().collect::<Vec<String>>();
if let Some(command) = args.get(1) {
if command == "atelier" {
args.remove(1);
}
}
args
}
fn make_search_path(default_search_env: bool, search_env: Option<String>) -> Option<SearchPath> {
if default_search_env {
Some(SearchPath::default())
} else {
search_env.map(|search_env| SearchPath::from_env(&search_env))
}
}