1use crate::value::VmValue;
2use std::collections::BTreeMap;
3
4mod api;
5mod canonicalize;
6mod result;
7mod transform;
8mod type_check;
9mod validate;
10
11pub(crate) use api::{
12 schema_assert_param, schema_expect_value, schema_extend_value, schema_from_json_schema_value,
13 schema_from_openapi_schema_value, schema_is_value, schema_omit_value, schema_partial_value,
14 schema_pick_value, schema_result_value, schema_to_json_schema_value,
15 schema_to_openapi_schema_value,
16};
17pub(crate) use canonicalize::json_to_vm_value;
18
19fn vm_value_to_serde_json(value: &VmValue) -> serde_json::Value {
20 match value {
21 VmValue::Nil => serde_json::Value::Null,
22 VmValue::Bool(value) => serde_json::Value::Bool(*value),
23 VmValue::Int(value) => serde_json::json!(value),
24 VmValue::Float(value) => serde_json::json!(value),
25 VmValue::String(value) => serde_json::Value::String(value.to_string()),
26 VmValue::List(items) | VmValue::Set(items) => {
27 serde_json::Value::Array(items.iter().map(vm_value_to_serde_json).collect())
28 }
29 VmValue::Dict(items) => serde_json::Value::Object(
30 items
31 .iter()
32 .map(|(key, value)| (key.clone(), vm_value_to_serde_json(value)))
33 .collect(),
34 ),
35 _ => serde_json::Value::String(value.display()),
36 }
37}
38
39fn schema_bool(schema: &BTreeMap<String, VmValue>, key: &str) -> bool {
40 matches!(schema.get(key), Some(VmValue::Bool(true)))
41}
42
43fn schema_i64(schema: &BTreeMap<String, VmValue>, key: &str) -> Option<i64> {
44 match schema.get(key) {
45 Some(VmValue::Int(value)) => Some(*value),
46 _ => None,
47 }
48}
49
50fn schema_number(schema: &BTreeMap<String, VmValue>, key: &str) -> Option<f64> {
51 match schema.get(key) {
52 Some(VmValue::Int(value)) => Some(*value as f64),
53 Some(VmValue::Float(value)) => Some(*value),
54 _ => None,
55 }
56}
57
58fn location_label(path: &str) -> String {
59 if path.is_empty() {
60 "root".to_string()
61 } else {
62 path.to_string()
63 }
64}
65
66fn child_path(path: &str, key: &str) -> String {
67 if path.is_empty() {
68 key.to_string()
69 } else {
70 format!("{}.{}", path, key)
71 }
72}
73
74fn index_path(path: &str, index: usize) -> String {
75 if path.is_empty() {
76 format!("[{}]", index)
77 } else {
78 format!("{}[{}]", path, index)
79 }
80}
81
82#[cfg(test)]
83mod tests;