Skip to main content

android_manifest/
attribute_list.rs

1use crate::xml::{XmlDeserialize, XmlSerialize};
2use serde::{
3    Deserialize, Deserializer, Serialize, Serializer,
4    de::{self, DeserializeOwned, Visitor},
5    ser::Error,
6};
7use std::fmt;
8use std::io::{Read, Write};
9use std::marker::PhantomData;
10
11pub trait Delimiter {
12    fn delimiter_symbol() -> &'static str;
13}
14
15#[derive(Debug, PartialEq, Eq, Default, Clone)]
16pub struct Semicolon;
17
18impl Delimiter for Semicolon {
19    fn delimiter_symbol() -> &'static str {
20        ";"
21    }
22}
23
24#[derive(Debug, PartialEq, Eq, Default, Clone)]
25pub struct VerticalBar;
26
27impl Delimiter for VerticalBar {
28    fn delimiter_symbol() -> &'static str {
29        "|"
30    }
31}
32
33#[derive(Debug, PartialEq, Eq, Default, Clone)]
34pub struct AttributeList<D: Delimiter, T: Serialize + DeserializeOwned> {
35    vec: Vec<T>,
36    phantom: PhantomData<D>,
37}
38
39impl<D: Delimiter, T: Serialize + DeserializeOwned> AttributeList<D, T> {
40    pub fn new() -> Self {
41        AttributeList {
42            vec: Vec::new(),
43            phantom: PhantomData,
44        }
45    }
46
47    pub fn from_vec(vec: Vec<T>) -> Self {
48        AttributeList {
49            vec,
50            phantom: PhantomData,
51        }
52    }
53
54    pub fn vec(&self) -> &Vec<T> {
55        &self.vec
56    }
57
58    pub fn is_empty(&self) -> bool {
59        self.vec.is_empty()
60    }
61}
62
63impl<D: Delimiter, T: Serialize + DeserializeOwned> From<Vec<T>> for AttributeList<D, T> {
64    fn from(vec: Vec<T>) -> Self {
65        AttributeList {
66            vec,
67            phantom: PhantomData,
68        }
69    }
70}
71
72impl<D: Delimiter, T: Serialize + DeserializeOwned> Serialize for AttributeList<D, T> {
73    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74    where
75        S: Serializer,
76    {
77        if self.is_empty() {
78            return Err(S::Error::custom("a value list can't be empty"));
79        };
80        serializer.serialize_str(
81            &self
82                .vec()
83                .iter()
84                .map(|v| serde_plain::to_string(v).unwrap())
85                .collect::<Vec<String>>()
86                .join(D::delimiter_symbol()),
87        )
88    }
89}
90
91impl<D: Delimiter, T: Serialize + DeserializeOwned> XmlSerialize for AttributeList<D, T> {
92    fn serialize<W: Write>(
93        &self,
94        writer: &mut crate::xml::ser::Serializer<W>,
95    ) -> Result<(), String> {
96        let values = self
97            .vec()
98            .iter()
99            .map(serde_plain::to_string)
100            .collect::<Result<Vec<_>, _>>()
101            .map_err(|error| error.to_string())?;
102        writer
103            .write(xml::writer::XmlEvent::characters(
104                &values.join(D::delimiter_symbol()),
105            ))
106            .map_err(|error| error.to_string())
107    }
108}
109
110fn parse_list_with_delimiter<D: Delimiter, T: Serialize + DeserializeOwned>(
111    v: &str,
112) -> Result<AttributeList<D, T>, String> {
113    if v.is_empty() {
114        return Err(
115            "there is no default value list. at least one value must be specified".to_string(),
116        );
117    };
118    let values = v
119        .replace(' ', "")
120        .split(D::delimiter_symbol())
121        .map(|s| serde_plain::from_str(s).unwrap())
122        .collect();
123    Ok(AttributeList::from_vec(values))
124}
125
126struct ListVisitor<D: Delimiter, T: Serialize + DeserializeOwned> {
127    delimiter: PhantomData<D>,
128    value_type: PhantomData<T>,
129}
130
131impl<D: Delimiter, T: Serialize + DeserializeOwned> ListVisitor<D, T> {
132    pub fn new() -> Self {
133        ListVisitor {
134            delimiter: PhantomData,
135            value_type: PhantomData,
136        }
137    }
138}
139
140impl<'de, D: Delimiter, T: Serialize + DeserializeOwned> Visitor<'de> for ListVisitor<D, T> {
141    type Value = AttributeList<D, T>;
142
143    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
144        formatter.write_str(&format!(
145            "an value list in format 'value1' or 'value1{}value2{}value3'",
146            D::delimiter_symbol(),
147            D::delimiter_symbol()
148        ))
149    }
150
151    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
152    where
153        E: de::Error,
154    {
155        parse_list_with_delimiter(v).map_err(|e| E::custom(e))
156    }
157}
158
159impl<'de, D: Delimiter, T: Serialize + DeserializeOwned> Deserialize<'de> for AttributeList<D, T> {
160    fn deserialize<De>(deserializer: De) -> Result<Self, De::Error>
161    where
162        De: Deserializer<'de>,
163    {
164        deserializer.deserialize_string(ListVisitor::new())
165    }
166}
167
168impl<D: Delimiter, T: Serialize + DeserializeOwned> XmlDeserialize for AttributeList<D, T> {
169    fn deserialize<R: Read>(reader: &mut crate::xml::de::Deserializer<R>) -> Result<Self, String> {
170        loop {
171            match reader.next_event()? {
172                xml::reader::XmlEvent::StartElement { .. } => {}
173                xml::reader::XmlEvent::Characters(ref v) => {
174                    return parse_list_with_delimiter(v);
175                }
176                _ => {
177                    break;
178                }
179            }
180        }
181        Err("Unable to parse attribute".to_string())
182    }
183}