1use std::collections::BTreeMap;
9
10use ahk::runtime::{Property, Report, Step, Value};
11use ahk::warnings::Warning;
12
13use crate::json::Object;
14
15pub fn the_report(report: &Report, notes: &[String]) -> String {
17 let mut object = Object::new(1024);
18 object.boolean("ok", report.ok);
19 object.field("steps", |out| the_steps(out, &report.steps));
20 object.texts("output", &report.output);
21 object.field("warnings", |out| the_warnings(out, &report.warnings));
22 object.texts("notes", notes);
23 match &report.error {
24 Some(error) => object.text("error", error),
25 None => object.nothing("error"),
26 };
27 object.optional_number("error_line", report.error_line.map(i64::from));
28 object.optional_number("exit_code", report.exit_code.map(i64::from));
29 object.number("elapsed_ms", report.elapsed_ms as i64);
30 object.field("variables", |out| the_variables(out, &report.variables));
31 object.finish()
32}
33
34pub fn the_failure_of_the_load(error: &str, line: u32, column: u32) -> String {
39 let mut object = Object::new(256);
40 object.boolean("ok", false);
41 object.text("error", error);
42 object.number("error_line", i64::from(line));
43 object.number("column", i64::from(column));
44 object.field("steps", |out| out.push_str("[]"));
47 object.field("output", |out| out.push_str("[]"));
48 object.field("notes", |out| out.push_str("[]"));
49 object.finish()
50}
51
52fn the_steps(out: &mut String, steps: &[Step]) {
54 out.push('[');
55 for (index, step) in steps.iter().enumerate() {
56 if index > 0 {
57 out.push(',');
58 }
59 let mut object = Object::new(128);
60 object.number("line", i64::from(step.line));
61 object.text("op", &step.op);
62 object.text("detail", &step.detail);
63 object.boolean("ok", step.ok);
64 object.number("elapsed_ms", step.elapsed_ms as i64);
65 out.push_str(&object.finish());
66 }
67 out.push(']');
68}
69
70fn the_warnings(out: &mut String, warnings: &[Warning]) {
72 out.push('[');
73 for (index, warning) in warnings.iter().enumerate() {
74 if index > 0 {
75 out.push(',');
76 }
77 let mut object = Object::new(128);
78 object.number("line", i64::from(warning.line));
79 object.text("message", &warning.message);
80 out.push_str(&object.finish());
81 }
82 out.push(']');
83}
84
85fn the_variables(out: &mut String, variables: &BTreeMap<String, Value>) {
87 out.push('{');
88 for (index, (name, value)) in variables.iter().enumerate() {
89 if index > 0 {
90 out.push(',');
91 }
92 crate::json::write_text(out, name);
93 out.push(':');
94 the_value(out, value);
95 }
96 out.push('}');
97}
98
99fn the_value(out: &mut String, value: &Value) {
101 match value {
102 Value::Int(number) => out.push_str(&number.to_string()),
103 Value::Float(number) => {
104 if number.is_finite() {
105 out.push_str(&number.to_string());
106 } else {
107 out.push_str("null");
109 }
110 }
111 Value::Text(text) => crate::json::write_text(out, text),
112 Value::List(values) => {
113 out.push('[');
114 for (index, value) in values.iter().enumerate() {
115 if index > 0 {
116 out.push(',');
117 }
118 the_value(out, value);
119 }
120 out.push(']');
121 }
122 Value::Object(object) => {
123 let object = object.borrow();
124 let mut written = Object::new(256);
125 written.text("class", &object.class);
126 written.field("properties", |out| {
127 the_properties(out, &object.properties)
128 });
129 out.push_str(&written.finish());
130 }
131 Value::Reference(reference) => {
132 let mut written = Object::new(128);
133 written.text("name", &reference.name);
134 written.text("scope", &format!("{:?}", reference.scope));
135 written.boolean("alias", reference.alias);
136 out.push_str(&written.finish());
137 }
138 }
139}
140
141fn the_properties(out: &mut String, properties: &BTreeMap<String, Property>) {
143 out.push('{');
144 for (index, (name, property)) in properties.iter().enumerate() {
145 if index > 0 {
146 out.push(',');
147 }
148 crate::json::write_text(out, name);
149 out.push(':');
150 let mut written = Object::new(128);
151 written.text("name", &property.name);
152 written.field("value", |out| the_value(out, &property.value));
153 out.push_str(&written.finish());
154 }
155 out.push('}');
156}