plantuml_server_client_rs/metadata/
include.rs1use anyhow::Result;
2use derive_getters::Getters;
3use normalize_path::NormalizePath;
4use serde::{Deserialize, Serialize};
5use std::collections::BTreeMap;
6use std::path::PathBuf;
7use typed_builder::TypedBuilder;
8
9#[derive(Deserialize, Serialize, Clone, Debug)]
11pub struct IncludesMetadata(
12 #[serde(with = "btreemap_vec_with")] BTreeMap<PathBuf, Vec<IncludesMetadataItem>>,
13);
14
15#[derive(Deserialize, Serialize, TypedBuilder, Getters, Clone, Debug)]
24#[builder(mutators(
25 pub fn path(&mut self, path: PathBuf){
26 self.normalized_path = path.normalize();
27 self.path = path
28 }
29))]
30pub struct IncludesMetadataItem {
31 #[builder(via_mutators)]
32 path: PathBuf,
33 #[builder(via_mutators)]
34 normalized_path: PathBuf,
35 base_path: PathBuf,
36 relative_path: PathBuf,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 index: Option<usize>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 id: Option<String>,
41}
42
43impl IncludesMetadata {
44 pub fn is_empty(&self) -> bool {
46 self.0.is_empty()
47 }
48
49 pub fn len(&self) -> usize {
51 self.0.len()
52 }
53
54 pub fn iter(&self) -> impl std::iter::Iterator<Item = (&PathBuf, &Vec<IncludesMetadataItem>)> {
56 self.0.iter()
57 }
58
59 pub fn flat_iter(&self) -> impl std::iter::Iterator<Item = (&PathBuf, &IncludesMetadataItem)> {
61 self.0
62 .iter()
63 .flat_map(|(k, v)| v.iter().map(move |x| (k, x)))
64 }
65}
66
67impl From<BTreeMap<PathBuf, Vec<IncludesMetadataItem>>> for IncludesMetadata {
68 fn from(inner: BTreeMap<PathBuf, Vec<IncludesMetadataItem>>) -> Self {
69 Self(inner)
70 }
71}
72
73impl btreemap_vec_with::Key for IncludesMetadataItem {
74 type Key = PathBuf;
75 fn key(&self) -> Self::Key {
76 self.path.normalize()
77 }
78}
79
80mod btreemap_vec_with {
81 use super::*;
82
83 use serde::ser::SerializeSeq;
84 use serde::{Deserializer, Serializer};
85
86 pub trait Key {
87 type Key;
88 fn key(&self) -> Self::Key;
89 }
90
91 pub fn deserialize<'de, D, K, V>(deserializer: D) -> Result<BTreeMap<K, Vec<V>>, D::Error>
92 where
93 D: Deserializer<'de>,
94 K: Ord,
95 V: Deserialize<'de> + Key<Key = K>,
96 {
97 let v = Vec::<V>::deserialize(deserializer)?;
98 let mut map = BTreeMap::new();
99 for item in v {
100 map.entry(item.key()).or_insert(vec![]).push(item);
101 }
102 Ok(map)
103 }
104
105 pub fn serialize<S, K, V>(map: &BTreeMap<K, Vec<V>>, serializer: S) -> Result<S::Ok, S::Error>
106 where
107 S: Serializer,
108 V: Serialize,
109 {
110 let len = map.values().flatten().collect::<Vec<_>>().len();
111 let mut seq = serializer.serialize_seq(Some(len))?;
112 for element in map.values().flatten() {
113 seq.serialize_element(element)?;
114 }
115 seq.end()
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn test_serialize_btreemap_values() -> anyhow::Result<()> {
125 #[derive(Serialize)]
126 struct TestStruct {
127 #[serde(with = "btreemap_vec_with")]
128 map: BTreeMap<usize, Vec<String>>,
129 }
130
131 let testdata = TestStruct {
132 map: BTreeMap::from([
133 (1, (0..1).map(|_| "1".into()).collect()),
134 (2, (0..2).map(|_| "2".into()).collect()),
135 (3, (0..3).map(|_| "3".into()).collect()),
136 (4, (0..4).map(|_| "4".into()).collect()),
137 ]),
138 };
139
140 let serialized = serde_json::to_string(&testdata)?;
141 let mut deserialized = serde_json::from_str::<serde_json::Value>(&serialized)?
142 .get("map")
143 .map(|x| serde_json::from_value::<Vec<String>>(x.clone()))
144 .unwrap()?;
145 deserialized.sort();
146 assert_eq!(
147 deserialized,
148 ["1", "2", "2", "3", "3", "3", "4", "4", "4", "4"]
149 );
150
151 Ok(())
152 }
153}