neutralts/bif/
parse_bif_debug.rs1#![doc = include_str!("../../doc/bif-debug.md")]
2
3use crate::{
4 bif::constants::*,
5 bif::Bif,
6 bif::BifError,
7 constants::*,
8 utils::*,
9};
10use std::fs;
11use std::path::Path;
12use std::time::{SystemTime, Duration};
13
14impl<'a> Bif<'a> {
15 pub(crate) fn parse_bif_debug(&mut self) -> Result<(), BifError> {
19 if self.mod_scope {
20 return Err(self.bif_error(BIF_ERROR_MODIFIER_NOT_ALLOWED));
21 }
22
23 let debug_enable = self.debug_enable();
24
25 if self.mod_negate {
26 if debug_enable {
27 self.out = UNPRINTABLE.to_string();
28 } else {
29 self.out = EMPTY_STRING;
30 }
31
32 return Ok(());
33 }
34
35 if !debug_enable {
36 self.out = EMPTY_STRING;
37 if self.mod_negate {
38 return Ok(());
39 } else {
40 return Err(self.bif_error("Debug is disabled. Remember to remove the bif debug in production."));
41 }
42 }
43
44 self.extract_params_code(true);
45
46 let mut schema = &self.shared.schema;
47 let mut key_name = self.code.clone();
48 if key_name.starts_with("local::") {
49 key_name = key_name.strip_prefix("local::").unwrap_or("").to_string();
50 schema = &self.shared.schema["__indir"][&self.inherit.indir];
51 }
52
53 let k = if self.code.is_empty() {
54 self.out = VERSION.to_string();
55 return Ok(());
56 } else if key_name == "full-schema" {
57 "".to_string()
58 } else {
59 format!("/{}", key_name).replace(BIF_ARRAY, "/")
60 };
61
62 self.out = match schema.pointer(&k) {
63 Some(value) => match serde_json::to_string_pretty(value) {
64 Ok(json_str) => json_str,
65 Err(e) => format!("Error formatting JSON: {}", e),
66 },
67 None => format!("Undefined: '{}'", self.code),
68 };
69
70 if self.mod_filter {
71 let tmp = unescape_chars(&self.out, true);
73 self.out = escape_chars(&tmp, true);
74 }
75
76 Ok(())
77 }
78
79 pub(crate) fn debug_enable(&self) -> bool {
81 if self.shared.debug_file.is_empty() {
82 return false;
83 }
84
85 let path = Path::new(&self.shared.debug_file);
86
87 if !path.exists() || !path.is_file() {
88 return false;
89 }
90
91 let metadata = match fs::metadata(path) {
92 Ok(md) => md,
93 Err(_) => return false,
94 };
95
96 let modified_time = match metadata.modified() {
97 Ok(time) => time,
98 Err(_) => return false,
99 };
100
101 let now = SystemTime::now();
102
103 match now.duration_since(modified_time) {
104 Ok(duration) => duration < Duration::from_secs(self.shared.debug_expire),
105 Err(_) => false,
106 }
107 }
108}
109
110
111#[cfg(test)]
112#[path = "parse_bif_debug_tests.rs"]
113mod tests;