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 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 merge_schema(
36 &mut self.shared.schema["__indir"][indir]["data"],
37 &data["data"],
38 );
39
40 self.out = UNPRINTABLE.to_string();
41
42 return Ok(());
43 }
44
45 self.file_path = self.code.clone();
46
47 if self.file_path.contains(BIF_OPEN) {
49 if !self.contains_allow(&self.file_path) {
50 return Err(self.bif_error("insecure file name"));
51 }
52 self.file_path = new_child_parse!(self, &self.code, false);
53 }
54
55 if let Some(stripped) = self.file_path.strip_prefix('#') {
56 self.file_path = format!("{}{}", self.inherit.current_dir, stripped);
57 }
58
59 let path = Path::new(&self.file_path);
60 if !Path::new(path).exists() {
61 if self.flags.contains("|require|") {
62 return Err(self.bif_error("file not found"));
63 } else {
64 self.out = EMPTY_STRING;
65
66 return Ok(());
67 }
68 }
69
70 let canonical_path = fs::canonicalize(path)
71 .unwrap()
72 .to_string_lossy()
73 .into_owned();
74
75 if self.mod_negate && self.inherit.data_files.contains(&canonical_path) {
76 self.out = UNPRINTABLE.to_string();
77
78 return Ok(());
79 }
80
81 self.inherit.data_files.push(canonical_path);
82 let file_raw = fs::read_to_string(&self.file_path).unwrap_or("".to_string());
83
84 let data: Value = match serde_json::from_str(&file_raw) {
85 Ok(value) => value,
86 Err(_) => {
87 return Err(self.bif_error(BIF_ERROR_NOT_VALID_JSON));
88 }
89 };
90
91 let indir = &self.inherit.create_block_schema(self.shared);
92
93 merge_schema(
95 &mut self.shared.schema["__indir"][indir]["data"],
96 &data["data"],
97 );
98
99 self.out = UNPRINTABLE.to_string();
100
101 Ok(())
102 }
103}
104
105#[cfg(test)]
106#[path = "parse_bif_data_tests.rs"]
107mod tests;