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}