1
/*
2
 * Hurl (https://hurl.dev)
3
 * Copyright (C) 2026 Orange
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *          http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
mod commands;
19
mod matches;
20

            
21
use std::env;
22
use std::path::PathBuf;
23

            
24
use clap::ArgMatches;
25
use hurl_core::input::Input;
26

            
27
#[derive(Clone, Debug, PartialEq, Eq)]
28
pub struct Options {
29
    pub check: bool,
30
    pub color: Option<bool>,
31
    pub in_place: bool,
32
    pub input_files: Vec<Input>,
33
    pub input_format: InputFormat,
34
    pub output_file: Option<PathBuf>,
35
    pub output_format: OutputFormat,
36
    pub standalone: bool,
37
}
38

            
39
#[derive(Clone, Debug, PartialEq, Eq)]
40
pub enum InputFormat {
41
    Curl,
42
    Hurl,
43
}
44

            
45
#[derive(Clone, Debug, PartialEq, Eq)]
46
pub enum OutputFormat {
47
    Hurl,
48
    Json,
49
    Html,
50
}
51

            
52
#[derive(Clone, Debug, PartialEq, Eq)]
53
pub enum OptionsError {
54
    Info(String),
55
    Error(String),
56
}
57

            
58
impl From<clap::Error> for OptionsError {
59
4
    fn from(error: clap::Error) -> Self {
60
4
        match error.kind() {
61
2
            clap::error::ErrorKind::DisplayVersion => OptionsError::Info(error.to_string()),
62
2
            clap::error::ErrorKind::DisplayHelp => OptionsError::Info(error.to_string()),
63
            _ => OptionsError::Error(error.to_string()),
64
        }
65
    }
66
}
67

            
68
144
pub fn parse() -> Result<Options, OptionsError> {
69
144
    let mut command = clap::Command::new("hurlfmt")
70
144
        .version(clap::crate_version!())
71
144
        .disable_colored_help(true)
72
144
        .about("Format Hurl files")
73
144
        .arg(commands::check())
74
144
        .arg(commands::color())
75
144
        .arg(commands::in_place())
76
144
        .arg(commands::input_files())
77
144
        .arg(commands::input_format())
78
144
        .arg(commands::no_color())
79
144
        .arg(commands::output())
80
144
        .arg(commands::output_format())
81
144
        .arg(commands::standalone());
82

            
83
144
    let arg_matches = command.try_get_matches_from_mut(env::args_os())?;
84
140
    let opts = parse_matches(&arg_matches)?;
85

            
86
140
    if opts.input_files.is_empty() {
87
        let help = command.render_help().to_string();
88
        return Err(OptionsError::Error(help));
89
    }
90
140
    Ok(opts)
91
}
92

            
93
140
fn parse_matches(arg_matches: &ArgMatches) -> Result<Options, OptionsError> {
94
140
    let check = matches::check(arg_matches);
95
140
    let color = matches::color(arg_matches);
96
140
    let in_place = matches::in_place(arg_matches)?;
97
140
    let input_files = matches::input_files(arg_matches)?;
98
140
    let input_format = matches::input_format(arg_matches)?;
99
140
    let output_file = matches::output_file(arg_matches);
100
140
    let output_format = matches::output_format(arg_matches)?;
101
140
    let standalone = matches::standalone(arg_matches)?;
102
140
    Ok(Options {
103
140
        check,
104
140
        color,
105
140
        in_place,
106
140
        input_files,
107
140
        input_format,
108
140
        output_file,
109
140
        output_format,
110
140
        standalone,
111
140
    })
112
}