1
/*
2
 * Hurl (https://hurl.dev)
3
 * Copyright (C) 2025 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

            
19
use std::fs;
20
use std::io::Write;
21
use std::path::{Path, PathBuf};
22

            
23
use hurl_core::input::Input;
24
use hurl_core::parser::{self, ParseError};
25

            
26
use crate::{format, linter};
27

            
28
/// Represents a check error.
29
pub enum FormatError {
30
    IO {
31
        filename: String,
32
        message: String,
33
    },
34
    Parse {
35
        content: String,
36
        input_file: Input,
37
        error: ParseError,
38
    },
39
}
40

            
41
/// Run the format command for a list of input files
42
6
pub fn run(input_files: &[PathBuf]) -> Vec<FormatError> {
43
6
    let mut errors = vec![];
44
12
    for input_file in input_files {
45
6
        if let Err(e) = run_format(input_file) {
46
3
            errors.push(e);
47
        }
48
    }
49
6
    errors
50
}
51

            
52
/// Run the format command for one input file
53
6
fn run_format(input_file: &Path) -> Result<(), FormatError> {
54
6
    let content =
55
6
        fs::read_to_string(input_file.display().to_string()).map_err(|e| FormatError::IO {
56
            filename: input_file.display().to_string(),
57
            message: e.to_string(),
58
6
        })?;
59
7
    let hurl_file = parser::parse_hurl_file(&content).map_err(|error| FormatError::Parse {
60
3
        content: content.clone(),
61
3
        input_file: Input::new(input_file.display().to_string().as_str()),
62
3
        error,
63
7
    })?;
64
3
    let hurl_file = linter::lint_hurl_file(&hurl_file);
65
3
    let formatted = format::format_text(&hurl_file, false);
66

            
67
3
    let mut file = match std::fs::File::create(input_file) {
68
        Err(e) => {
69
            return Err(FormatError::IO {
70
                filename: input_file.display().to_string(),
71
                message: e.to_string(),
72
            })
73
        }
74
3
        Ok(file) => file,
75
3
    };
76
3
    file.write_all(formatted.as_bytes())
77
3
        .map_err(|e| FormatError::IO {
78
            filename: input_file.display().to_string(),
79
            message: e.to_string(),
80
3
        })?;
81
3
    Ok(())
82
}