android_manifest/resources/
any.rs1use super::{
2 parse_resource, DrawableResource, Resource, ResourceType, StringResource, StyleResource,
3 XmlResource,
4};
5use serde::{
6 de::{self, Visitor},
7 Deserialize, Deserializer, Serialize, Serializer,
8};
9use std::fmt;
10use std::io::{Read, Write};
11use yaserde::{YaDeserialize, YaSerialize};
12
13#[derive(Debug, PartialEq, Eq, Clone)]
15pub enum AnyResource {
16 String(Resource<StringResource>),
17 Drawable(Resource<DrawableResource>),
18 Xml(Resource<XmlResource>),
19 Style(Resource<StyleResource>),
20}
21
22impl Serialize for AnyResource {
23 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
24 where
25 S: Serializer,
26 {
27 match self {
28 AnyResource::String(r) => Serialize::serialize(&r, serializer),
29 AnyResource::Drawable(r) => Serialize::serialize(&r, serializer),
30 AnyResource::Xml(r) => Serialize::serialize(&r, serializer),
31 AnyResource::Style(r) => Serialize::serialize(&r, serializer),
32 }
33 }
34}
35
36impl YaSerialize for AnyResource {
37 fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>) -> Result<(), String> {
38 match self {
39 AnyResource::String(r) => YaSerialize::serialize(r, writer),
40 AnyResource::Drawable(r) => YaSerialize::serialize(r, writer),
41 AnyResource::Xml(r) => YaSerialize::serialize(r, writer),
42 AnyResource::Style(r) => YaSerialize::serialize(r, writer),
43 }
44 }
45
46 fn serialize_attributes(
47 &self,
48 attributes: Vec<xml::attribute::OwnedAttribute>,
49 namespace: xml::namespace::Namespace,
50 ) -> Result<
51 (
52 Vec<xml::attribute::OwnedAttribute>,
53 xml::namespace::Namespace,
54 ),
55 String,
56 > {
57 Ok((attributes, namespace))
58 }
59}
60
61fn parse_any_resource(v: &str) -> Result<AnyResource, String> {
62 if v.is_empty() {
63 return Err("value of attribute is empty".to_string());
64 };
65 let (package, resource_type, name) = parse_resource(v)?;
66 let any = if StringResource::resource_type() == resource_type {
67 AnyResource::String(Resource::<StringResource>::new_with_package(&name, package))
68 } else if DrawableResource::resource_type() == resource_type {
69 AnyResource::Drawable(Resource::<DrawableResource>::new_with_package(
70 &name, package,
71 ))
72 } else if XmlResource::resource_type() == resource_type {
73 AnyResource::Xml(Resource::<XmlResource>::new_with_package(&name, package))
74 } else if StyleResource::resource_type() == resource_type {
75 AnyResource::Style(Resource::<StyleResource>::new_with_package(&name, package))
76 } else {
77 return Err(format!("unsuported resource type: {}", resource_type));
78 };
79 Ok(any)
80}
81
82struct AnyResourceVisitor;
83
84impl<'de> Visitor<'de> for AnyResourceVisitor {
85 type Value = AnyResource;
86
87 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
88 formatter.write_str("an resource in format @resource_type/resource_name")
89 }
90
91 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
92 where
93 E: de::Error,
94 {
95 parse_any_resource(v).map_err(|e| E::custom(e))
96 }
97}
98
99impl<'de> Deserialize<'de> for AnyResource {
100 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
101 where
102 D: Deserializer<'de>,
103 {
104 deserializer.deserialize_string(AnyResourceVisitor)
105 }
106}
107
108impl YaDeserialize for AnyResource {
109 fn deserialize<R: Read>(reader: &mut yaserde::de::Deserializer<R>) -> Result<Self, String> {
110 loop {
111 match reader.next_event()? {
112 xml::reader::XmlEvent::StartElement { .. } => {}
113 xml::reader::XmlEvent::Characters(ref v) => {
114 return parse_any_resource(v);
115 }
116 _ => {
117 break;
118 }
119 }
120 }
121 Err("Unable to parse attribute".to_string())
122 }
123}