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::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
        })?;
59
6
    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
4
    })?;
64
3
    let formatted = linter::lint_hurl_file(&hurl_file);
65

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