|
1 | | -// src/main.rs |
2 | | -use clap::{Arg, ArgMatches, Command}; |
3 | | -use ga4ghphetools::dto::etl_dto::EtlDto; |
| 1 | +mod commands; |
| 2 | + |
| 3 | +use clap::Command; |
4 | 4 | use ontolius::{io::OntologyLoaderBuilder, ontology::csr::FullCsrOntology}; |
5 | 5 | use std::sync::Arc; |
6 | 6 |
|
7 | | - |
8 | | -#[cfg(feature = "excel_export")] |
9 | | -use ga4ghphetools::export::output_excel_comparison; |
10 | | - |
11 | | - |
12 | 7 | fn main() { |
13 | | - let matches = Command::new("phetools") |
| 8 | + let mut cmd = Command::new("phetools") |
14 | 9 | .about("GA4GH Phenopacket Schema Curation Library Demo") |
15 | | - .version(env!("CARGO_PKG_VERSION")) |
16 | | - .subcommand( |
17 | | - Command::new("excel") |
18 | | - .about("Test loading of legacy Excel template") |
19 | | - .arg(Arg::new("template").short('t').long("template").required(true)) |
20 | | - .arg(Arg::new("hpo").short('o').long("hpo").required(true)) |
21 | | - ) |
22 | | - .subcommand( |
23 | | - Command::new("json") |
24 | | - .about("Test loading of new JSON template") |
25 | | - .arg(Arg::new("json").short('i').long("input")) |
26 | | - .arg(Arg::new("hpo").short('o').long("hpo").required(true)) |
27 | | - ) |
28 | | - .subcommand( |
29 | | - Command::new("etl") |
30 | | - .about("Test converting an EtlDto to CohortData") |
31 | | - .arg(Arg::new("input").short('i').long("input").required(true)) |
32 | | - .arg(Arg::new("hpo").short('o').long("hpo").required(true)) |
33 | | - ) |
34 | | - .subcommand( |
35 | | - Command::new("version") |
36 | | - .about("Show library version") |
37 | | - .arg(Arg::new("version").short('v').long("version")) |
38 | | - ) |
39 | | - .subcommand( |
40 | | - Command::new("excel") |
41 | | - .about("Compare two cohorts and export to Excel") |
42 | | - .arg(Arg::new("cohort1").long("cohort1").required(true)) |
43 | | - .arg(Arg::new("cohort2").long("cohort2").required(true)) |
44 | | - .arg(Arg::new("output").long("output").required(true)) |
45 | | - .arg(Arg::new("hpo").long("hpo").required(true)) |
46 | | - .arg( |
47 | | - Arg::new("threshold") |
48 | | - .long("threshold") |
49 | | - .default_value("1"), |
50 | | - ) |
51 | | - ) |
52 | | - .get_matches(); |
| 10 | + .version(env!("CARGO_PKG_VERSION")) |
| 11 | + .subcommand(commands::excel::command()) |
| 12 | + .subcommand(commands::etl::command()) |
| 13 | + .subcommand(commands::compare::command()) |
| 14 | + .subcommand(commands::json::command()) |
| 15 | + .subcommand(commands::removeterm::command()); |
| 16 | + |
| 17 | + let matches = cmd.clone().get_matches(); |
| 18 | + |
53 | 19 | match matches.subcommand() { |
54 | | - Some(("excel", sub_matches)) => handle_excel(sub_matches).expect("Could not start excel command"), |
55 | | - Some(("json", sub_matches)) => { |
56 | | - let input = sub_matches.get_one::<String>("input").unwrap(); |
57 | | - println!("json: {}", input); |
58 | | - }, |
59 | | - Some(("etl", sub_matches)) => handle_etl(sub_matches).expect("Could not start ETL command"), |
60 | | - Some(("version", sub_matches)) => { |
61 | | - println!("Version: {}", env!("CARGO_PKG_VERSION")); |
62 | | - }, |
63 | | - Some(("compare", sub_matches)) => { |
64 | | - #[cfg(feature = "excel_export")] |
65 | | - handle_compare(sub_matches).expect("Excel comparison failed"); |
66 | | - |
67 | | - #[cfg(not(feature = "excel_export"))] |
68 | | - eprintln!("This binary was built without the `excel_export` feature"); |
69 | | - } |
70 | | - _ => println!("No subcommand was used"), |
| 20 | + Some(("excel", sub_matches)) => commands::excel::handle(sub_matches).unwrap(), |
| 21 | + Some(("etl", sub_matches)) => commands::etl::handle(sub_matches).unwrap(), |
| 22 | + Some(("compare", sub_matches)) => commands::compare::handle(sub_matches).unwrap(), |
| 23 | + Some(("json", sub_matches)) => commands::json::handle(sub_matches).unwrap(), |
| 24 | + Some(("remove-term", sub_matches)) => commands::removeterm::handle(sub_matches).unwrap(), |
| 25 | + _ => cmd.print_help().unwrap(), |
71 | 26 | } |
72 | | - |
73 | | -} |
74 | | - |
75 | | -#[cfg(feature = "excel_export")] |
76 | | -fn handle_compare(sub_matches: &ArgMatches) -> Result<(), Box<dyn std::error::Error>> { |
77 | | - let cohort_1 = sub_matches |
78 | | - .get_one::<String>("cohort1") |
79 | | - .expect("cohort1 is required"); |
80 | | - |
81 | | - let cohort_2 = sub_matches |
82 | | - .get_one::<String>("cohort2") |
83 | | - .expect("cohort2 is required"); |
84 | | - |
85 | | - let output = sub_matches |
86 | | - .get_one::<String>("output") |
87 | | - .expect("output is required"); |
88 | | - |
89 | | - let hpo_path = sub_matches |
90 | | - .get_one::<String>("hpo") |
91 | | - .expect("hpo is required"); |
92 | | - |
93 | | - let threshold: usize = sub_matches |
94 | | - .get_one::<String>("threshold") |
95 | | - .unwrap() |
96 | | - .parse()?; |
97 | | - |
98 | | - let hpo = load_hpo(hpo_path)?; |
99 | | - |
100 | | - output_excel_comparison( |
101 | | - cohort_1, |
102 | | - cohort_2, |
103 | | - output, |
104 | | - hpo, |
105 | | - threshold, |
106 | | - ) |
107 | | - .map_err(|e| e.into()) |
108 | | -} |
109 | | - |
110 | | -fn handle_excel(sub_matches: &ArgMatches) -> Result<(), Box<dyn std::error::Error>> { |
111 | | - let template = sub_matches |
112 | | - .get_one::<String>("template") |
113 | | - .expect("template argument is required"); |
114 | | - let hpo = sub_matches |
115 | | - .get_one::<String>("hpo") |
116 | | - .ok_or("Missing required --hpo argument")?; |
117 | | - |
118 | | - let hpo_arc = load_hpo(hpo)?; |
119 | | - test_load_template(hpo_arc, template); |
120 | | - Ok(()) |
121 | | -} |
122 | | - |
123 | | -fn handle_etl(sub_matches: &ArgMatches) -> Result<(), Box<dyn std::error::Error>> { |
124 | | - let input = sub_matches.get_one::<String>("input").unwrap(); |
125 | | - println!("ETL: {}", input); |
126 | | - let hpo = sub_matches |
127 | | - .get_one::<String>("hpo") |
128 | | - .ok_or("Missing required --hpo argument")?; |
129 | | - let hpo_arc = load_hpo(hpo)?; |
130 | | - let contents = std::fs::read_to_string(input) |
131 | | - .map_err(|e| format!("Failed to read file: {}", e)).unwrap(); |
132 | | - let dto: EtlDto = serde_json::from_str(&contents) |
133 | | - .map_err(|e| format!("Failed to deserialize JSON: {}", e)).unwrap(); |
134 | | - |
135 | | - let cohort = ga4ghphetools::etl::get_cohort_data_from_etl_dto(hpo_arc.clone(), dto)?; |
136 | | - let json = serde_json::to_string_pretty(&cohort).unwrap(); |
137 | | - println!("{}", json); |
138 | | - Ok(()) |
139 | 27 | } |
140 | 28 |
|
141 | | - |
142 | | -fn load_hpo(json_path: &str) -> Result<Arc<FullCsrOntology>, Box<dyn std::error::Error>> { |
| 29 | +/// Load HPO JSON |
| 30 | +pub fn load_hpo(json_path: &str) -> Result<Arc<FullCsrOntology>, Box<dyn std::error::Error>> { |
143 | 31 | let loader = OntologyLoaderBuilder::new().obographs_parser().build(); |
144 | 32 | let hpo: FullCsrOntology = loader.load_from_path(json_path)?; |
145 | 33 | Ok(Arc::new(hpo)) |
146 | 34 | } |
147 | | - |
148 | | - |
149 | | - |
150 | | -fn test_load_template(hpo: Arc<FullCsrOntology>, template: &str) { |
151 | | - match ga4ghphetools::factory::load_pyphetools_excel_template(template, false, hpo,|p,q|{ |
152 | | - println!("{}/{} variants validated", p, q);}) { |
153 | | - Ok(cohort_dto) => { |
154 | | - println!("[INFO] No errors identified for {:?}\n\n\n", cohort_dto); |
155 | | - } |
156 | | - Err(e) => { |
157 | | - println!("[ERROR] {:?}", e); |
158 | | - return; |
159 | | - } |
160 | | - } |
161 | | -} |
0 commit comments