lemma/planning/
explanation.rs1use crate::planning::semantics::{DataPath, RulePath};
13use serde::{Serialize, Serializer};
14
15pub(crate) fn serialize_rule_path_as_name<S>(
16 path: &RulePath,
17 serializer: S,
18) -> Result<S::Ok, S::Error>
19where
20 S: Serializer,
21{
22 serializer.serialize_str(&path.rule)
23}
24
25pub(crate) fn serialize_data_path_as_name<S>(
26 path: &DataPath,
27 serializer: S,
28) -> Result<S::Ok, S::Error>
29where
30 S: Serializer,
31{
32 serializer.serialize_str(&path.input_key())
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
36#[serde(tag = "type", rename_all = "snake_case")]
37pub enum ExplanationNode {
38 Rule {
39 #[serde(serialize_with = "serialize_rule_path_as_name")]
40 name: RulePath,
41 #[serde(serialize_with = "serialize_option_string")]
42 result: Option<String>,
43 body: String,
44 #[serde(skip_serializing_if = "Vec::is_empty")]
45 causes: Vec<Cause>,
46 #[serde(skip_serializing_if = "Vec::is_empty")]
47 children: Vec<ExplanationNode>,
48 },
49 Compose {
50 expression: String,
51 operands: Vec<ExplanationNode>,
52 },
53 Data {
55 #[serde(serialize_with = "serialize_data_path_as_name")]
56 name: DataPath,
57 display: String,
58 },
59 DataUnused {
62 #[serde(serialize_with = "serialize_data_path_as_name")]
63 name: DataPath,
64 },
65 Conversion {
66 expression: String,
67 steps: Vec<SerializedConversionTraceStep>,
68 operands: Vec<ExplanationNode>,
69 },
70 Veto {
71 #[serde(skip_serializing_if = "Option::is_none")]
72 message: Option<String>,
73 },
74}
75
76fn serialize_option_string<S>(value: &Option<String>, serializer: S) -> Result<S::Ok, S::Error>
77where
78 S: Serializer,
79{
80 match value {
81 Some(s) => serializer.serialize_str(s),
82 None => serializer.serialize_none(),
83 }
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
87pub struct Cause {
88 pub condition: String,
89 pub value: String,
90 #[serde(skip_serializing_if = "Vec::is_empty")]
91 pub children: Vec<ExplanationNode>,
92}
93
94#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
95#[serde(rename_all = "snake_case")]
96pub enum ConversionTraceRole {
97 Outcome,
98 Rule,
99 Source,
100}
101
102#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
103pub struct SerializedConversionTraceStep {
104 pub(crate) role: ConversionTraceRole,
105 pub(crate) text: String,
106}