intuicio_frontend_simpleton/library/
debug.rs1use crate::{
2 library::bytes::Bytes, Array, Boolean, Function, Integer, Map, Real, Reference, Text, Type,
3};
4use intuicio_core::registry::Registry;
5use intuicio_derive::intuicio_function;
6use std::fmt::Write;
7
8#[intuicio_function(module_name = "debug")]
9pub fn assert(status: Reference, message: Reference) -> Reference {
10 if !*status.read::<Boolean>().unwrap() {
11 panic!("{}", message.read::<Text>().unwrap().as_str());
12 }
13 Reference::null()
14}
15
16fn debug_indent(result: &mut dyn Write, indent: usize) {
17 for _ in 0..(indent * 2) {
18 result.write_char(' ').unwrap()
19 }
20}
21
22fn debug_impl(value: &Reference, result: &mut dyn Write, indent: &mut Option<usize>) {
23 if value.is_null() {
24 write!(result, "null").unwrap();
25 } else if let Some(value) = value.read::<Boolean>() {
26 write!(result, "{}", *value).unwrap();
27 } else if let Some(value) = value.read::<Integer>() {
28 write!(result, "{}", *value).unwrap();
29 } else if let Some(value) = value.read::<Real>() {
30 write!(result, "{}", *value).unwrap();
31 } else if let Some(value) = value.read::<Text>() {
32 write!(result, r#""{}""#, value.as_str()).unwrap();
33 } else if let Some(value) = value.read::<Bytes>() {
34 write!(result, "#{:?}", value.get_ref()).unwrap();
35 } else if let Some(value) = value.read::<Array>() {
36 write!(result, "[").unwrap();
37 if !value.is_empty() {
38 if let Some(indent) = indent {
39 *indent += 1;
40 writeln!(result).unwrap();
41 debug_indent(result, *indent);
42 }
43 for (index, value) in value.iter().enumerate() {
44 if index > 0 {
45 write!(result, ", ").unwrap();
46 if let Some(indent) = indent {
47 writeln!(result).unwrap();
48 debug_indent(result, *indent);
49 }
50 }
51 debug_impl(value, result, indent);
52 }
53 if let Some(indent) = indent {
54 *indent -= 1;
55 writeln!(result).unwrap();
56 debug_indent(result, *indent);
57 }
58 }
59 write!(result, "]").unwrap();
60 } else if let Some(value) = value.read::<Map>() {
61 write!(result, "{{").unwrap();
62 if !value.is_empty() {
63 if let Some(indent) = indent {
64 *indent += 1;
65 writeln!(result).unwrap();
66 debug_indent(result, *indent);
67 }
68 for (index, (key, value)) in value.iter().enumerate() {
69 if index > 0 {
70 write!(result, ", ").unwrap();
71 if let Some(indent) = indent {
72 writeln!(result).unwrap();
73 debug_indent(result, *indent);
74 }
75 }
76 write!(result, "{}: ", key).unwrap();
77 debug_impl(value, result, indent);
78 }
79 if let Some(indent) = indent {
80 *indent -= 1;
81 writeln!(result).unwrap();
82 debug_indent(result, *indent);
83 }
84 }
85 write!(result, "}}").unwrap();
86 } else if let Some(value) = value.read::<Type>() {
87 write!(
88 result,
89 "<{}::{}>",
90 value.handle().unwrap().module_name().unwrap_or(""),
91 value.handle().unwrap().name()
92 )
93 .unwrap();
94 } else if let Some(value) = value.read::<Function>() {
95 let signature = value.handle().unwrap().signature();
96 write!(
97 result,
98 "<{}::{}(",
99 signature.module_name.as_deref().unwrap_or(""),
100 signature.name,
101 )
102 .unwrap();
103 for (index, parameter) in signature.inputs.iter().enumerate() {
104 if index > 0 {
105 write!(result, ", ").unwrap();
106 }
107 write!(result, "{}", parameter.name).unwrap();
108 }
109 write!(result, ")>").unwrap();
110 } else if let Some(value) = value.read_object() {
111 match &**value.type_handle() {
112 intuicio_core::types::Type::Struct(type_) => {
113 write!(
114 result,
115 "<{}::{}> {{",
116 type_.module_name.as_deref().unwrap_or(""),
117 type_.name
118 )
119 .unwrap();
120 if !type_.fields().is_empty() {
121 if let Some(indent) = indent {
122 *indent += 1;
123 writeln!(result).unwrap();
124 debug_indent(result, *indent);
125 }
126 for (index, field) in type_.fields().iter().enumerate() {
127 if let Some(value) = value.read_field::<Reference>(&field.name) {
128 if index > 0 {
129 write!(result, ", ").unwrap();
130 if let Some(indent) = indent {
131 writeln!(result).unwrap();
132 debug_indent(result, *indent);
133 }
134 }
135 write!(result, "{}: ", field.name).unwrap();
136 debug_impl(value, result, indent);
137 } else {
138 if index > 0 {
139 write!(result, ", ").unwrap();
140 }
141 write!(result, "<?>").unwrap();
142 }
143 }
144 if let Some(indent) = indent {
145 *indent -= 1;
146 writeln!(result).unwrap();
147 debug_indent(result, *indent);
148 }
149 }
150 write!(result, "}}").unwrap();
151 }
152 intuicio_core::types::Type::Enum(_) => {}
153 }
154 } else {
155 write!(result, "<?>").unwrap();
156 }
157}
158
159#[intuicio_function(module_name = "debug", use_registry)]
160pub fn debug(registry: &Registry, value: Reference, pretty: Reference) -> Reference {
161 let mut result = String::new();
162 let indent = Some(0);
163 debug_impl(
164 &value,
165 &mut result,
166 &mut if *pretty.read::<Boolean>().unwrap() {
167 indent
168 } else {
169 None
170 },
171 );
172 Reference::new_text(result, registry)
173}
174
175pub fn install(registry: &mut Registry) {
176 registry.add_function(assert::define_function(registry));
177 registry.add_function(debug::define_function(registry));
178}