1use std::path::PathBuf;
2
3use clap::{Args, Parser, Subcommand};
4
5use clap_complete::Shell;
6use conjure_cp::settings::{
7 DEFAULT_MINION_DISCRETE_THRESHOLD, Parser as InputParser, QuantifiedExpander, Rewriter,
8 SolverFamily,
9};
10
11use crate::{pretty, solve, test_solve};
12
13pub(crate) const DEBUG_HELP_HEADING: Option<&str> = Some("Debug");
14pub(crate) const LOGGING_HELP_HEADING: Option<&str> = Some("Logging & Output");
15pub(crate) const CONFIGURATION_HELP_HEADING: Option<&str> = Some("Configuration");
16pub(crate) const OPTIMISATIONS_HELP_HEADING: Option<&str> = Some("Optimisations");
17
18#[derive(Clone, Debug, Subcommand)]
20pub enum Command {
21 Solve(solve::Args),
23 PrintJsonSchema,
25 TestSolve(test_solve::Args),
30 Completion(CompletionArgs),
32 Pretty(pretty::Args),
33 ServerLSP,
35}
36
37#[derive(Clone, Debug, Parser)]
39#[command(
40 author,
41 about = "Conjure Oxide: Automated Constraints Modelling Toolkit",
42 before_help = "Full documentation can be found online at: https://conjure-cp.github.io/conjure-oxide"
43)]
44pub struct Cli {
45 #[command(subcommand)]
46 pub subcommand: Command,
47
48 #[command(flatten)]
49 pub global_args: GlobalArgs,
50
51 #[arg(long = "version", short = 'V')]
53 pub version: bool,
54}
55
56#[derive(Debug, Clone, Args)]
57pub struct GlobalArgs {
58 #[arg(long, value_name = "EXTRA_RULE_SETS", global = true)]
60 pub extra_rule_sets: Vec<String>,
61
62 #[arg(long, short = 'v', help = "Log verbosely to stderr", global = true, help_heading = LOGGING_HELP_HEADING)]
64 pub verbose: bool,
65
66 #[arg(
71 long,
72 overrides_with = "_no_check_equally_applicable_rules",
73 default_value_t = false,
74 global = true,
75 help_heading= DEBUG_HELP_HEADING
76 )]
77 pub check_equally_applicable_rules: bool,
78
79 #[arg(long, global = true, help_heading=LOGGING_HELP_HEADING)]
81 pub rule_trace: Option<PathBuf>,
82
83 #[arg(long, global = true, help_heading=LOGGING_HELP_HEADING)]
88 pub rule_trace_aggregates: Option<PathBuf>,
89
90 #[arg(long, default_value_t = false, global = true, help_heading=LOGGING_HELP_HEADING)]
95 pub rule_trace_cdp: bool,
96
97 #[arg(long, global = true, help_heading=LOGGING_HELP_HEADING)]
101 pub rule_trace_verbose: Option<PathBuf>,
102
103 #[arg(long, global = true, help_heading = DEBUG_HELP_HEADING)]
107 pub _no_check_equally_applicable_rules: bool,
108
109 #[arg(
113 long,
114 default_value_t = InputParser::ViaConjure,
115 value_parser = parse_parser,
116 global = true,
117 help_heading = CONFIGURATION_HELP_HEADING
118 )]
119 pub parser: InputParser,
120
121 #[arg(long, default_value_t = Rewriter::Naive, value_parser = parse_rewriter, global = true, help_heading = CONFIGURATION_HELP_HEADING)]
125 pub rewriter: Rewriter,
126
127 #[arg(
131 long,
132 default_value_t = QuantifiedExpander::Native,
133 value_parser = parse_comprehension_expander,
134 global = true,
135 help_heading = CONFIGURATION_HELP_HEADING
136 )]
137 pub comprehension_expander: QuantifiedExpander,
138
139 #[arg(
145 long,
146 value_name = "SOLVER",
147 value_parser = parse_solver_family,
148 default_value = "minion",
149 short = 's',
150 global = true,
151 help_heading = CONFIGURATION_HELP_HEADING
152 )]
153 pub solver: SolverFamily,
154
155 #[arg(
159 long,
160 default_value_t = DEFAULT_MINION_DISCRETE_THRESHOLD,
161 global = true,
162 help_heading = CONFIGURATION_HELP_HEADING
163 )]
164 pub minion_discrete_threshold: usize,
165
166 #[arg(long,global=true, value_names=["filename"], next_line_help=true, help_heading=LOGGING_HELP_HEADING)]
175 pub save_solver_input_file: Option<PathBuf>,
176
177 #[arg(long, global = true, help_heading = OPTIMISATIONS_HELP_HEADING)]
181 pub solver_timeout: Option<humantime::Duration>,
182
183 #[arg(long, default_value_t = false, global = true, help_heading = LOGGING_HELP_HEADING)]
185 pub log: bool,
186
187 #[arg(long, value_name = "LOGFILE", global = true, help_heading = LOGGING_HELP_HEADING)]
189 pub logfile: Option<PathBuf>,
190
191 #[arg(long, value_name = "JSON LOGFILE", global = true, help_heading = LOGGING_HELP_HEADING)]
193 pub logfile_json: Option<PathBuf>,
194}
195
196#[derive(Debug, Clone, Args)]
197pub struct CompletionArgs {
198 #[arg(value_enum)]
200 pub shell: Shell,
201}
202
203#[derive(Debug, Clone, Copy, clap::ValueEnum)]
204pub enum ShellTypes {
205 Bash,
206 Zsh,
207 Fish,
208 PowerShell,
209 Elvish,
210}
211
212fn parse_comprehension_expander(input: &str) -> Result<QuantifiedExpander, String> {
213 input.parse()
214}
215
216fn parse_rewriter(input: &str) -> Result<Rewriter, String> {
217 input.parse::<Rewriter>()
218}
219
220fn parse_solver_family(input: &str) -> Result<SolverFamily, String> {
221 input.parse()
222}
223
224fn parse_parser(input: &str) -> Result<InputParser, String> {
225 input.parse()
226}