1use sim_kernel::{Expr, Symbol};
4use sim_lib_auto_core::DtcStatus;
5
6pub fn decode_dtc_status(byte: u8) -> DtcStatus {
8 DtcStatus::from_byte(byte)
9}
10
11pub fn dtc_status_expr(byte: u8) -> Expr {
13 let status = decode_dtc_status(byte);
14 Expr::Map(vec![
15 field("test_failed", status.test_failed),
16 field(
17 "test_failed_this_operation_cycle",
18 status.test_failed_this_operation_cycle,
19 ),
20 field("pending", status.pending),
21 field("confirmed", status.confirmed),
22 field(
23 "test_not_completed_since_clear",
24 status.test_not_completed_since_clear,
25 ),
26 field("test_failed_since_clear", status.test_failed_since_clear),
27 field(
28 "test_not_completed_this_operation_cycle",
29 status.test_not_completed_this_operation_cycle,
30 ),
31 field("warning_indicator", status.warning_indicator),
32 ])
33}
34
35pub(crate) fn status_byte_from_expr(expr: &Expr) -> Option<u8> {
36 let Expr::Map(entries) = expr else {
37 return None;
38 };
39 let status = DtcStatus {
40 test_failed: bool_field(entries, "test_failed")?,
41 test_failed_this_operation_cycle: bool_field(entries, "test_failed_this_operation_cycle")?,
42 pending: bool_field(entries, "pending")?,
43 confirmed: bool_field(entries, "confirmed")?,
44 test_not_completed_since_clear: bool_field(entries, "test_not_completed_since_clear")?,
45 test_failed_since_clear: bool_field(entries, "test_failed_since_clear")?,
46 test_not_completed_this_operation_cycle: bool_field(
47 entries,
48 "test_not_completed_this_operation_cycle",
49 )?,
50 warning_indicator: bool_field(entries, "warning_indicator")?,
51 };
52 Some(status.to_byte())
53}
54
55fn field(name: &str, value: bool) -> (Expr, Expr) {
56 (Expr::Symbol(Symbol::new(name)), Expr::Bool(value))
57}
58
59fn bool_field(entries: &[(Expr, Expr)], name: &str) -> Option<bool> {
60 entries.iter().find_map(|(key, value)| {
61 if key == &Expr::Symbol(Symbol::new(name)) {
62 match value {
63 Expr::Bool(value) => Some(*value),
64 _ => None,
65 }
66 } else {
67 None
68 }
69 })
70}