pkgs/trace/
trace.rs

1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)]
6pub struct Trace {
7    pub packages: BTreeMap<String, PkgTrace>,
8}
9
10#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
11pub struct PkgTrace {
12    pub directory: String,
13
14    #[serde(with = "trace_map_as_map")]
15    pub maps: BTreeMap<String, String>,
16}
17
18impl PkgTrace {
19    pub fn new(directory: String) -> Self {
20        Self {
21            directory,
22            maps: BTreeMap::new(),
23        }
24    }
25}
26
27#[derive(Debug, Clone, Deserialize, Serialize)]
28struct TraceMap {
29    pub src: String,
30    pub dst: String,
31}
32
33mod trace_map_as_map {
34    use serde::{Deserializer, Serializer};
35
36    use super::*;
37
38    pub fn serialize<S>(map: &BTreeMap<String, String>, serializer: S) -> Result<S::Ok, S::Error>
39    where
40        S: Serializer,
41    {
42        let v: Vec<TraceMap> = map
43            .iter()
44            .map(|(src, dst)| TraceMap {
45                src: src.clone(),
46                dst: dst.clone(),
47            })
48            .collect();
49        v.serialize(serializer)
50    }
51
52    pub fn deserialize<'de, D>(deserializer: D) -> Result<BTreeMap<String, String>, D::Error>
53    where
54        D: Deserializer<'de>,
55    {
56        let v = Vec::<TraceMap>::deserialize(deserializer)?;
57        Ok(v.into_iter().map(|m| (m.src, m.dst)).collect())
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use serde_test::{Token, assert_tokens};
64
65    use super::*;
66
67    #[test]
68    fn pkg_trace_ser_de() {
69        let trace = PkgTrace {
70            directory: "test_dir".to_string(),
71            maps: BTreeMap::from([
72                ("src1".to_string(), "dst1".to_string()),
73                ("src2".to_string(), "dst2".to_string()),
74            ]),
75        };
76
77        assert_tokens(
78            &trace,
79            &[
80                Token::Struct {
81                    name: "PkgTrace",
82                    len: 2,
83                },
84                Token::Str("directory"),
85                Token::Str("test_dir"),
86                Token::Str("maps"),
87                Token::Seq { len: Some(2) },
88                Token::Struct {
89                    name: "TraceMap",
90                    len: 2,
91                },
92                Token::Str("src"),
93                Token::Str("src1"),
94                Token::Str("dst"),
95                Token::Str("dst1"),
96                Token::StructEnd,
97                Token::Struct {
98                    name: "TraceMap",
99                    len: 2,
100                },
101                Token::Str("src"),
102                Token::Str("src2"),
103                Token::Str("dst"),
104                Token::Str("dst2"),
105                Token::StructEnd,
106                Token::SeqEnd,
107                Token::StructEnd,
108            ],
109        )
110    }
111}