1use itertools::Itertools;
2use serde::{Deserialize, Serialize, Serializer};
3
4#[derive(Deserialize, Serialize)]
5#[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
6#[serde(rename_all = "PascalCase")]
7pub struct Init {
8 pub incoming: String,
9 pub scales: String,
10 pub channels: Channels,
11}
12
13#[derive(Deserialize, Serialize)]
14#[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
15#[serde(rename_all = "PascalCase")]
16pub struct Channels {
17 pub channel: Vec<Channel>
18}
19
20#[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
21pub struct Channel (pub Vec<i32>);
22
23impl<'de> Deserialize<'de> for Channel {
24 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
25 where
26 D: serde::Deserializer<'de> {
27 use serde::de::Error;
28 let channel_str = String::deserialize(deserializer)?;
29 let entries: Result<Vec<i32>, _> = channel_str.split(',')
30 .map(|e| e.parse())
31 .collect();
32 let entries = entries.map_err(Error::custom)?;
33 Ok(Self(entries))
34 }
35}
36
37impl Serialize for Channel {
38 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
39 where
40 S: Serializer,
41 {
42 let res = self.0.iter().map(ToString::to_string).join(",");
43 serializer.serialize_str(&res)
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn deser_init() {
53 const REF_CHANNELS: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
54<Init>
55 <Incoming> p p with NNPDF31_nnlo_as_0118/0 </Incoming>
56 <Scales> muR = HT, muF = HT </Scales>
57 <Channels>
58 <Channel> 0,5,1,1,2,2,3,3,4,4,5,5 </Channel>
59 <Channel> 1,5,1,-1,2,-2,3,-3,4,-4,5,-5 </Channel>
60 <Channel> 2,20,1,2,1,3,1,4,1,5,2,1,2,3,2,4,2,5,3,1,3,2,3,4,3,5,4,1,4,2,4,3,4,5,5,1,5,2,5,3,5,4 </Channel>
61 <Channel> 3,20,1,-2,1,-3,1,-4,1,-5,2,-1,2,-3,2,-4,2,-5,3,-1,3,-2,3,-4,3,-5,4,-1,4,-2,4,-3,4,-5,5,-1,5,-2,5,-3,5,-4 </Channel>
62 <Channel> 4,5,1,21,2,21,3,21,4,21,5,21 </Channel>
63 <Channel> 5,5,-1,1,-2,2,-3,3,-4,4,-5,5 </Channel>
64 <Channel> 6,5,-1,-1,-2,-2,-3,-3,-4,-4,-5,-5 </Channel>
65 <Channel> 7,20,-1,2,-1,3,-1,4,-1,5,-2,1,-2,3,-2,4,-2,5,-3,1,-3,2,-3,4,-3,5,-4,1,-4,2,-4,3,-4,5,-5,1,-5,2,-5,3,-5,4 </Channel>
66 <Channel> 8,20,-1,-2,-1,-3,-1,-4,-1,-5,-2,-1,-2,-3,-2,-4,-2,-5,-3,-1,-3,-2,-3,-4,-3,-5,-4,-1,-4,-2,-4,-3,-4,-5,-5,-1,-5,-2,-5,-3,-5,-4 </Channel>
67 <Channel> 9,5,-1,21,-2,21,-3,21,-4,21,-5,21 </Channel>
68 <Channel> 10,5,21,1,21,2,21,3,21,4,21,5 </Channel>
69 <Channel> 11,5,21,-1,21,-2,21,-3,21,-4,21,-5 </Channel>
70 <Channel> 12,1,21,21 </Channel>
71 </Channels>
72</Init>
73"#;
74 let init: Init = quick_xml::de::from_str(REF_CHANNELS).unwrap();
75 assert_eq!(init.channels.channel[5].0, [5,5,-1,1,-2,2,-3,3,-4,4,-5,5]);
76 }
77}