android_manifest/resources/
any.rs1use super::{
2 DrawableResource, Resource, ResourceType, StringResource, StyleResource, XmlResource,
3 parse_resource,
4};
5use crate::xml::{XmlDeserialize, XmlSerialize};
6use serde::{
7 Deserialize, Deserializer, Serialize, Serializer,
8 de::{self, Visitor},
9};
10use std::fmt;
11use std::io::{Read, Write};
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 XmlSerialize for AnyResource {
37 fn serialize<W: Write>(
38 &self,
39 writer: &mut crate::xml::ser::Serializer<W>,
40 ) -> Result<(), String> {
41 match self {
42 AnyResource::String(r) => XmlSerialize::serialize(r, writer),
43 AnyResource::Drawable(r) => XmlSerialize::serialize(r, writer),
44 AnyResource::Xml(r) => XmlSerialize::serialize(r, writer),
45 AnyResource::Style(r) => XmlSerialize::serialize(r, writer),
46 }
47 }
48}
49
50fn parse_any_resource(v: &str) -> Result<AnyResource, String> {
51 if v.is_empty() {
52 return Err("value of attribute is empty".to_string());
53 };
54 let (package, resource_type, name) = parse_resource(v)?;
55 let any = if StringResource::resource_type() == resource_type {
56 AnyResource::String(Resource::<StringResource>::new_with_package(&name, package))
57 } else if DrawableResource::resource_type() == resource_type {
58 AnyResource::Drawable(Resource::<DrawableResource>::new_with_package(
59 &name, package,
60 ))
61 } else if XmlResource::resource_type() == resource_type {
62 AnyResource::Xml(Resource::<XmlResource>::new_with_package(&name, package))
63 } else if StyleResource::resource_type() == resource_type {
64 AnyResource::Style(Resource::<StyleResource>::new_with_package(&name, package))
65 } else {
66 return Err(format!("unsuported resource type: {}", resource_type));
67 };
68 Ok(any)
69}
70
71struct AnyResourceVisitor;
72
73impl<'de> Visitor<'de> for AnyResourceVisitor {
74 type Value = AnyResource;
75
76 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
77 formatter.write_str("an resource in format @resource_type/resource_name")
78 }
79
80 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
81 where
82 E: de::Error,
83 {
84 parse_any_resource(v).map_err(|e| E::custom(e))
85 }
86}
87
88impl<'de> Deserialize<'de> for AnyResource {
89 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
90 where
91 D: Deserializer<'de>,
92 {
93 deserializer.deserialize_string(AnyResourceVisitor)
94 }
95}
96
97impl XmlDeserialize for AnyResource {
98 fn deserialize<R: Read>(reader: &mut crate::xml::de::Deserializer<R>) -> Result<Self, String> {
99 loop {
100 match reader.next_event()? {
101 xml::reader::XmlEvent::StartElement { .. } => {}
102 xml::reader::XmlEvent::Characters(ref v) => {
103 return parse_any_resource(v);
104 }
105 _ => {
106 break;
107 }
108 }
109 }
110 Err("Unable to parse attribute".to_string())
111 }
112}