Newer
Older
use clap::Parser;
use structopt::StructOpt;
use rprompt::prompt_reply;
use std::path::Path;
use crate::{analyzer::AnalyzerType, error::OpossumError};
use strum::IntoEnumIterator;
type Result<T> = std::result::Result<T, OpossumError>;
/// Simple program to greet a person
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct Args {
/// file path to buikd-filed of the optical setup, which should be read in
#[arg(short, long)]
pub file_path: String,
/// analyzer type that should be used to analyze the optical setup
#[arg(short, long)]
pub analyzer: String,
/// destination directory of the report. if not defined, same directory as the filepath for the optical setup is used
#[derive(Parser, StructOpt)]
pub struct PartialArgs {
/// filepath of the opticscenery to read in
#[arg(short, long)]
file_path: Option<String>,
/// analyzer type that should be used to analyze the optical setup
#[arg(short, long)]
analyzer: Option<String>,
/// destination directory of the report. if not defined, same directory as the filepath for the optical setup is used
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
fn file_path_is_valid(path: &str) -> bool{
Path::exists(Path::new(path)) && Path::is_file(Path::new(path)) && path.ends_with(".yaml")
}
fn eval_file_path(path: Option<String>, err_count:&mut usize) -> Result<String>{
match path{
Some(f) => {
if file_path_is_valid(&f) {
Ok(f)
}
else{
user_prompt(&format!("Invalid file path: {}\nFile must be inside of an existing directory end end with .yaml!\n\nPlease insert valid file path!\n", f), "f", err_count)
}
},
None => user_prompt("Insert path to optical-setup-description file:\n", "f", err_count)
}
}
fn eval_analyzer_flag(analyzer_flag: Option<String>, err_count:&mut usize) -> Result<String>{
match analyzer_flag{
Some(flag) => {
match flag.as_str() {
"e" => Ok("energy".to_owned()),
"p" => Ok("paraxial ray-tracing".to_owned()),
_ => {
*err_count += 1;
user_prompt(&format!("Invalid analyzer flag: {}\n\nPlease choose an analyzer for your setup:\n", flag), "a", err_count)
}
}
}
None => user_prompt("Please choose an analyzer for your setup:\n", "a", err_count)
}
}
fn eval_report_directory(report_dir: Option<String>, err_count: &mut usize) -> Result<String>{
match report_dir{
Some(r) => {
let r_path = Path::new(&r);
if Path::exists(r_path){
if r_path.ends_with("\\"){
Ok(r.to_owned())
}
else{
Ok(r + "\\")
}
}
else if r == "" {
Ok("".to_owned())
}
else{
user_prompt(&format!("Invalid directory: {}\n\nPlease insert a valid directory or nothing to choose the same directory as the optical-setup file\n", r), "r", err_count)
}
},
None => Ok("".to_owned())
}
}
fn user_prompt(prompt: &str, check_flag: &str, err_count: &mut usize) -> Result<String>{
if *err_count < 3{
match check_flag{
"f" => {
let input: String = prompt_reply(prompt).unwrap();
}
"a" =>
{
let mut prompt_str = prompt.to_owned();
for a_type in AnalyzerType::iter(){
prompt_str += match a_type {
AnalyzerType::Energy => "e for energy analysis\n",
AnalyzerType::ParAxialRayTrace=> "p for paraxial ray-tracing analysis\n",
};
}
let input: String = prompt_reply(prompt_str).unwrap();
eval_analyzer_flag(Some(input), err_count)
}
"r" =>
{
let input: String = prompt_reply(prompt).unwrap();
eval_report_directory(Some(input), err_count)
}
_ => {
Err(OpossumError::Console("Wrong check flag! This type of flag is not defined!".into()))
}
}
}
else{
Err(OpossumError::Console("Too many wrong inputs! Program exits! Please type \"opossum.exe -h\" for help!".into()))
}
}
impl TryFrom<PartialArgs> for Args{
type Error = OpossumError;
fn try_from(part_args: PartialArgs) -> Result<Args> {
let mut err_count: usize = 0;
let file_path = eval_file_path(part_args.file_path, &mut err_count)?;
println!("{}", format!("Path to optical-setup file: {}\n", file_path));
let analyzer = eval_analyzer_flag(part_args.analyzer, &mut err_count)?;
println!("{}", format!("Chosen analysis: {}\n", analyzer));
let report_directory = eval_report_directory(part_args.report_directory, &mut err_count)?;
let report_directory = if report_directory.is_empty(){
Path::parent(Path::new(&file_path))
.unwrap()
.to_str()
.unwrap()
.to_owned()
}
else{
report_directory
};
println!("{}", format!("Report directory: {}\n", report_directory));
Ok(Args{ file_path: file_path, analyzer: analyzer, report_directory: report_directory})