geam_core/runtime/value/
inspection.rs1mod bit_array;
2mod custom;
3mod function;
4mod list;
5mod tuple;
6
7use std::fmt::{self, Display, Formatter};
8
9use super::Value;
10
11pub struct ValueInspection<'value> {
12 value: &'value Value,
13}
14
15impl<'value> ValueInspection<'value> {
16 pub(super) fn new(value: &'value Value) -> Self {
17 Self { value }
18 }
19
20 pub(crate) fn write_to(&self, output: &mut String) {
21 write_value(output, self.value);
22 }
23}
24
25impl Display for ValueInspection<'_> {
26 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
27 let mut output = String::new();
28 self.write_to(&mut output);
29 formatter.write_str(&output)
30 }
31}
32
33fn write_value(output: &mut String, value: &Value) {
34 match value {
35 Value::Int(value) => output.push_str(&value.to_string()),
36 Value::Float(value) => output.push_str(&format!("{value:?}")),
37 Value::String(value) => output.push_str(&format!("{value:?}")),
38 Value::BitArray(value) => bit_array::write(output, value),
39 Value::UtfCodepoint(value) => output.push_str(&format!("{value:?}")),
40 Value::Custom(value) => custom::write(output, value),
41 Value::External(value) => output.push_str(value.inspection()),
42 Value::Bool(true) => output.push_str("True"),
43 Value::Bool(false) => output.push_str("False"),
44 Value::Nil => output.push_str("Nil"),
45 Value::Tuple(values) => tuple::write(output, values),
46 Value::List(value) => list::write(output, value),
47 Value::Function(value) => function::write(output, value),
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::super::Value;
54
55 #[test]
56 fn inspects_primitive_values() {
57 let cases = [
58 (Value::Int((-12).into()), "-12"),
59 (Value::Float(1.0), "1.0"),
60 (Value::Float(-0.0), "-0.0"),
61 (Value::Float(f64::INFINITY), "inf"),
62 (Value::Float(f64::NEG_INFINITY), "-inf"),
63 (Value::Float(f64::NAN), "NaN"),
64 (
65 Value::String("one\n\"two\"\\".into()),
66 r#""one\n\"two\"\\""#,
67 ),
68 (Value::UtfCodepoint('A'), "'A'"),
69 (Value::UtfCodepoint('\n'), "'\\n'"),
70 (Value::UtfCodepoint('\u{10ffff}'), "'\\u{10ffff}'"),
71 (Value::Bool(true), "True"),
72 (Value::Bool(false), "False"),
73 (Value::Nil, "Nil"),
74 ];
75
76 for (value, expected) in cases {
77 assert_eq!(value.inspect().to_string(), expected);
78 }
79 }
80}