vrl/value/kind/
debug.rs

1use super::{super::ObjectMap, Kind, Value};
2
3impl Kind {
4    /// Returns a tree representation of `Kind`, in a more human readable format.
5    /// This is for debugging / development purposes only.
6    #[must_use]
7    pub fn debug_info(&self) -> ObjectMap {
8        let mut output = ObjectMap::new();
9        insert_kind(&mut output, self, true);
10        output
11    }
12}
13
14fn insert_kind(tree: &mut ObjectMap, kind: &Kind, show_unknown: bool) {
15    if kind.is_never() {
16        insert_if_true(tree, "never", true);
17    } else if kind.is_any() {
18        insert_if_true(tree, "any", true);
19    } else if kind.is_json() {
20        insert_if_true(tree, "json", true);
21    } else {
22        insert_if_true(tree, "bytes", kind.contains_bytes());
23        insert_if_true(tree, "integer", kind.contains_integer());
24        insert_if_true(tree, "float", kind.contains_float());
25        insert_if_true(tree, "boolean", kind.contains_boolean());
26        insert_if_true(tree, "timestamp", kind.contains_timestamp());
27        insert_if_true(tree, "regex", kind.contains_regex());
28        insert_if_true(tree, "null", kind.contains_null());
29        insert_if_true(tree, "undefined", kind.contains_undefined());
30
31        if let Some(fields) = &kind.object {
32            let mut object_tree = ObjectMap::new();
33            for (field, field_kind) in fields.known() {
34                let mut field_tree = ObjectMap::new();
35                insert_kind(&mut field_tree, field_kind, show_unknown);
36                object_tree.insert(field.to_string().into(), Value::Object(field_tree));
37            }
38            tree.insert("object".into(), Value::Object(object_tree));
39            if show_unknown {
40                insert_unknown(
41                    tree,
42                    &fields.unknown_kind(),
43                    fields.is_unknown_exact(),
44                    "object",
45                );
46            }
47        }
48
49        if let Some(indices) = &kind.array {
50            let mut array_tree = ObjectMap::new();
51            for (index, index_kind) in indices.known() {
52                let mut index_tree = ObjectMap::new();
53                insert_kind(&mut index_tree, index_kind, show_unknown);
54                array_tree.insert(index.to_string().into(), Value::Object(index_tree));
55            }
56            tree.insert("array".to_owned().into(), Value::Object(array_tree));
57            if show_unknown {
58                insert_unknown(
59                    tree,
60                    &indices.unknown_kind(),
61                    indices.is_unknown_exact(),
62                    "array",
63                );
64            }
65        }
66    }
67}
68
69fn insert_unknown(tree: &mut ObjectMap, unknown: &Kind, unknown_exact: bool, prefix: &str) {
70    if unknown.is_undefined() {
71        return;
72    }
73    let mut unknown_tree = ObjectMap::new();
74    insert_kind(&mut unknown_tree, unknown, unknown_exact);
75    if unknown.is_exact() {
76        tree.insert(
77            format!("{prefix}_unknown_exact").into(),
78            Value::Object(unknown_tree),
79        );
80    } else {
81        tree.insert(
82            format!("{prefix}_unknown_infinite").into(),
83            Value::Object(unknown_tree),
84        );
85    }
86}
87
88fn insert_if_true(tree: &mut ObjectMap, key: &str, value: bool) {
89    if value {
90        tree.insert(key.to_owned().into(), Value::Boolean(true));
91    }
92}