haddock_restraints/core/
input.rs

1use crate::Interactor;
2use std::fs::File;
3use std::io::BufReader;
4use std::process;
5
6/// Reads and processes a JSON file containing Interactor data.
7///
8/// This function reads a JSON file, deserializes it into a vector of Interactors,
9/// and updates the file paths for any structures referenced in the Interactors.
10///
11/// # Arguments
12///
13/// * `file_path` - A string slice that holds the path to the JSON file.
14///
15/// # Returns
16///
17/// * `Ok(Vec<Interactor>)` - A vector of Interactor objects if successful.
18/// * `Err(Box<dyn std::error::Error>)` - An error if file reading or JSON parsing fails.
19///
20/// # Errors
21///
22/// This function will return an error if:
23/// - The file cannot be opened
24/// - The JSON is invalid or cannot be deserialized into `Vec<Interactor>`
25/// - Any referenced structure file does not exist
26///
27/// # Panics
28///
29/// The function will call `process::exit(1)` if a referenced structure file does not exist.
30///
31pub fn read_json_file(file_path: &str) -> Result<Vec<Interactor>, Box<dyn std::error::Error>> {
32    // Open the file and create a buffered reader
33    let file = File::open(file_path)?;
34    let reader = BufReader::new(file);
35
36    // Deserialize the JSON into a vector of Interactors
37    let mut data: Vec<Interactor> = serde_json::from_reader(reader)?;
38
39    // Get the directory of the input file
40    let wd = std::path::Path::new(file_path).parent().unwrap();
41
42    // Process each Interactor
43    data.iter_mut().for_each(|interactor| {
44        if !interactor.structure().is_empty() {
45            // Construct the full path to the structure file
46            let pdb_path = wd.join(interactor.structure());
47
48            if pdb_path.exists() {
49                // Update the structure path to the full path
50                interactor.set_structure(pdb_path.to_str().unwrap());
51            } else {
52                // Print an error message and exit if the structure file doesn't exist
53                eprintln!("\n### ERROR LOADING STRUCTURE ###");
54                eprintln!("# The file `{}` does not exist", interactor.structure());
55                eprintln!(
56                    "# If you are using relative paths, they should be relative to `{}`\n",
57                    file_path
58                );
59                process::exit(1);
60            }
61
62            // Set the structure path (this line seems redundant with the earlier set_structure call)
63            interactor.set_structure(pdb_path.to_str().unwrap());
64        }
65    });
66
67    Ok(data)
68}