neutralts/bif/
parse_bif_locale.rs1#![doc = include_str!("../../doc/bif-locale.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_locale(&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|")
20 && !self.flags.contains("|inline|")
21 && !self.flags.contains("|noparse|")
22 {
23 return Err(self.bif_error(BIF_ERROR_FLAGS_NOT_ALLOWED));
24 }
25 }
26
27 if self.flags.contains("|inline|") {
28 if self.code.contains(BIF_OPEN) {
30 self.code = new_child_parse!(self, &self.code, false);
31 }
32
33 let locale: Value = match serde_json::from_str(&self.code) {
34 Ok(value) => value,
35 Err(_) => {
36 return Err(self.bif_error(BIF_ERROR_NOT_VALID_JSON));
37 }
38 };
39
40 let indir = &self.inherit.create_block_schema(self.shared);
41
42 merge_schema(&mut self.shared.schema["__indir"][indir]["locale"], &locale);
44
45 self.out = EMPTY_STRING;
46
47 return Ok(());
48 }
49
50 self.file_path = self.code.clone();
51
52 if self.file_path.contains(BIF_OPEN) {
54 if !self.contains_allow(&self.file_path) {
55 return Err(self.bif_error(BIF_ERROR_INSECURE_FILE_NAME));
56 }
57 self.file_path = new_child_parse!(self, &self.code, false);
58 }
59
60 if let Some(stripped) = self.file_path.strip_prefix('#') {
61 self.file_path = format!("{}{}", self.inherit.current_dir, stripped);
62 }
63
64 let path = Path::new(&self.file_path);
65 if !Path::new(path).exists() {
66 if self.flags.contains("|require|") {
67 return Err(self.bif_error(BIF_ERROR_FILE_NOT_FOUND));
68 } else {
69 return Ok(());
70 }
71 }
72
73 let canonical_path = fs::canonicalize(path)
74 .unwrap()
75 .to_string_lossy()
76 .into_owned();
77 if self.mod_negate && self.inherit.locale_files.contains(&canonical_path) {
78 self.out = UNPRINTABLE.to_string();
79
80 return Ok(());
81 }
82
83 self.inherit.locale_files.push(canonical_path);
84 let mut file_raw = fs::read_to_string(&self.file_path).unwrap_or("".to_string());
85
86 if !self.flags.contains("|noparse|") {
87 if file_raw.contains(BIF_OPEN) {
89 file_raw = new_child_parse!(self, &file_raw, false);
90 }
91 }
92
93 let locale: Value = match serde_json::from_str(&file_raw) {
94 Ok(value) => value,
95 Err(_) => {
96 return Err(self.bif_error(BIF_ERROR_NOT_VALID_JSON));
97 }
98 };
99
100 let indir = &self.inherit.create_block_schema(self.shared);
101
102 merge_schema(&mut self.shared.schema["__indir"][indir]["locale"], &locale);
104
105 self.out = UNPRINTABLE.to_string();
106
107 Ok(())
108 }
109}
110
111#[cfg(test)]
112#[path = "parse_bif_locale_tests.rs"]
113mod tests;