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)]
87 pub rule_trace_verbose: Option<PathBuf>,
88
89 #[arg(long, global = true, help_heading = DEBUG_HELP_HEADING)]
93 pub _no_check_equally_applicable_rules: bool,
94
95 #[arg(
99 long,
100 default_value_t = InputParser::ViaConjure,
101 value_parser = parse_parser,
102 global = true,
103 help_heading = CONFIGURATION_HELP_HEADING
104 )]
105 pub parser: InputParser,
106
107 #[arg(long, default_value_t = Rewriter::Naive, value_parser = parse_rewriter, global = true, help_heading = CONFIGURATION_HELP_HEADING)]
111 pub rewriter: Rewriter,
112
113 #[arg(
117 long,
118 default_value_t = QuantifiedExpander::Native,
119 value_parser = parse_comprehension_expander,
120 global = true,
121 help_heading = CONFIGURATION_HELP_HEADING
122 )]
123 pub comprehension_expander: QuantifiedExpander,
124
125 #[arg(
131 long,
132 value_name = "SOLVER",
133 value_parser = parse_solver_family,
134 default_value = "minion",
135 short = 's',
136 global = true,
137 help_heading = CONFIGURATION_HELP_HEADING
138 )]
139 pub solver: SolverFamily,
140
141 #[arg(
145 long,
146 default_value_t = DEFAULT_MINION_DISCRETE_THRESHOLD,
147 global = true,
148 help_heading = CONFIGURATION_HELP_HEADING
149 )]
150 pub minion_discrete_threshold: usize,
151
152 #[arg(long,global=true, value_names=["filename"], next_line_help=true, help_heading=LOGGING_HELP_HEADING)]
161 pub save_solver_input_file: Option<PathBuf>,
162
163 #[arg(long, global = true, help_heading = OPTIMISATIONS_HELP_HEADING)]
167 pub solver_timeout: Option<humantime::Duration>,
168
169 #[arg(long, default_value_t = false, global = true, help_heading = LOGGING_HELP_HEADING)]
171 pub log: bool,
172
173 #[arg(long, value_name = "LOGFILE", global = true, help_heading = LOGGING_HELP_HEADING)]
175 pub logfile: Option<PathBuf>,
176
177 #[arg(long, value_name = "JSON LOGFILE", global = true, help_heading = LOGGING_HELP_HEADING)]
179 pub logfile_json: Option<PathBuf>,
180}
181
182#[derive(Debug, Clone, Args)]
183pub struct CompletionArgs {
184 #[arg(value_enum)]
186 pub shell: Shell,
187}
188
189#[derive(Debug, Clone, Copy, clap::ValueEnum)]
190pub enum ShellTypes {
191 Bash,
192 Zsh,
193 Fish,
194 PowerShell,
195 Elvish,
196}
197
198fn parse_comprehension_expander(input: &str) -> Result<QuantifiedExpander, String> {
199 input.parse()
200}
201
202fn parse_rewriter(input: &str) -> Result<Rewriter, String> {
203 input.parse()
204}
205
206fn parse_solver_family(input: &str) -> Result<SolverFamily, String> {
207 input.parse()
208}
209
210fn parse_parser(input: &str) -> Result<InputParser, String> {
211 input.parse()
212}