neutralts/bif/
parse_bif_data.rs1#![doc = include_str!("../../doc/bif-data.md")]
2
3use crate::{bif::constants::*, bif::Bif, bif::BifError, constants::*, utils::*, Value};
4use std::fs;
5use std::path::Path;
6
7impl<'a> Bif<'a> {
8 pub(crate) fn parse_bif_data(&mut self) -> Result<(), BifError> {
12 if self.mod_filter || self.mod_scope {
13 return Err(self.bif_error(BIF_ERROR_MODIFIER_NOT_ALLOWED));
14 }
15
16 self.extract_params_code(true);
17
18 if !self.flags.is_empty() {
19 if !self.flags.contains("|require|") && !self.flags.contains("|inline|") {
20 return Err(self.bif_error(BIF_ERROR_FLAGS_NOT_ALLOWED));
21 }
22 }
23
24 if self.flags.contains("|inline|") {
25 let mut data: Value = match serde_json::from_str(&self.code) {
26 Ok(value) => value,
27 Err(_) => {
28 return Err(self.bif_error(BIF_ERROR_NOT_VALID_JSON));
29 }
30 };
31
32 let indir = &self.inherit.create_block_schema(self.shared);
33
34 let merge_data = data
36 .as_object_mut()
37 .and_then(|obj| obj.remove("data"))
38 .unwrap_or(Value::Null);
39 merge_schema_owned(
40 &mut self.shared.schema["__indir"][indir]["data"],
41 merge_data,
42 );
43
44 self.out = UNPRINTABLE.to_string();
45
46 return Ok(());
47 }
48
49 self.file_path = self.code.clone();
50
51 if self.file_path.contains(BIF_OPEN) {
53 if !self.contains_allow(&self.file_path) {
54 return Err(self.bif_error("insecure file name"));
55 }
56 self.file_path = new_child_parse!(self, &self.code, false);
57 }
58
59 if let Some(stripped) = self.file_path.strip_prefix('#') {
60 self.file_path = format!("{}{}", self.inherit.current_dir, stripped);
61 }
62
63 let path = Path::new(&self.file_path);
64 if !Path::new(path).exists() {
65 if self.flags.contains("|require|") {
66 return Err(self.bif_error("file not found"));
67 } else {
68 self.out = EMPTY_STRING;
69
70 return Ok(());
71 }
72 }
73
74 let canonical_path = fs::canonicalize(path)
75 .unwrap()
76 .to_string_lossy()
77 .into_owned();
78
79 if self.mod_negate && self.inherit.data_files.contains(&canonical_path) {
80 self.out = UNPRINTABLE.to_string();
81
82 return Ok(());
83 }
84
85 self.inherit.data_files.push(canonical_path);
86 let file_raw = fs::read_to_string(&self.file_path).unwrap_or("".to_string());
87
88 let mut data: Value = match serde_json::from_str(&file_raw) {
89 Ok(value) => value,
90 Err(_) => {
91 return Err(self.bif_error(BIF_ERROR_NOT_VALID_JSON));
92 }
93 };
94
95 let indir = &self.inherit.create_block_schema(self.shared);
96
97 let merge_data = data
99 .as_object_mut()
100 .and_then(|obj| obj.remove("data"))
101 .unwrap_or(Value::Null);
102 merge_schema_owned(
103 &mut self.shared.schema["__indir"][indir]["data"],
104 merge_data,
105 );
106
107 self.out = UNPRINTABLE.to_string();
108
109 Ok(())
110 }
111}
112
113#[cfg(test)]
114#[path = "parse_bif_data_tests.rs"]
115mod tests;