1use language_tags::LanguageTag;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::{convert::TryFrom, fmt, str::FromStr};
5
6use crate::error::{CPEError, Result};
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
9pub enum Language {
10 #[default]
12 Any,
13 NA,
15 Value(String),
17 Language(LanguageTag),
19}
20
21impl FromStr for Language {
22 type Err = CPEError;
23 fn from_str(s: &str) -> Result<Self> {
24 match LanguageTag::parse(s) {
25 Err(_) => match s {
26 "*" => Ok(Self::Any),
27 "-" => Ok(Self::NA),
28 _ => Ok(Self::Value(s.to_string())),
29 },
30 Ok(tag) => Ok(Self::Language(tag)),
31 }
32 }
33}
34
35impl TryFrom<&str> for Language {
36 type Error = CPEError;
37 fn try_from(val: &str) -> Result<Self> {
38 Self::from_str(val)
39 }
40}
41
42impl TryFrom<String> for Language {
43 type Error = CPEError;
44 fn try_from(val: String) -> Result<Self> {
45 Self::from_str(val.as_str())
46 }
47}
48
49impl fmt::Display for Language {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 write!(
52 f,
53 "{}",
54 match self {
55 Language::Any => "*",
56 Language::NA => "-",
57 Language::Value(s) => s.as_str(),
58 Language::Language(v) => v.as_str(),
59 }
60 )
61 }
62}
63
64impl Serialize for Language {
65 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
66 where
67 S: Serializer,
68 {
69 serializer.serialize_str(match self {
70 Language::Any => "*",
71 Language::NA => "-",
72 Language::Value(s) => s.as_str(),
73 Language::Language(ref other) => other.as_str(),
74 })
75 }
76}
77
78impl<'de> Deserialize<'de> for Language {
79 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
80 where
81 D: Deserializer<'de>,
82 {
83 let s = String::deserialize(deserializer)?;
84 Ok(match LanguageTag::parse(&s) {
85 Err(_) => match s.as_str() {
86 "*" => Language::Any,
87 "-" => Language::NA,
88 _ => Language::Value(s.to_string()),
89 },
90 Ok(tag) => Language::Language(tag),
91 })
92 }
93}
94#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
96pub enum Component {
97 #[default]
99 Any,
100 NA,
102 Value(String),
104}
105
106impl Serialize for Component {
107 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
108 where
109 S: Serializer,
110 {
111 serializer.serialize_str(match *self {
112 Component::Any => "*",
113 Component::NA => "-",
114 Component::Value(ref other) => other,
115 })
116 }
117}
118
119impl<'de> Deserialize<'de> for Component {
120 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
121 where
122 D: Deserializer<'de>,
123 {
124 let s = String::deserialize(deserializer)?;
125 Ok(match s.as_str() {
126 "*" => Component::Any,
127 "-" => Component::NA,
128 _ => Component::Value(s),
129 })
130 }
131}
132
133impl TryFrom<&str> for Component {
134 type Error = CPEError;
135 fn try_from(val: &str) -> Result<Self> {
136 Self::from_str(val)
137 }
138}
139
140impl TryFrom<String> for Component {
141 type Error = CPEError;
142 fn try_from(val: String) -> Result<Self> {
143 Self::from_str(val.as_str())
144 }
145}
146
147impl FromStr for Component {
148 type Err = CPEError;
149
150 fn from_str(val: &str) -> Result<Self> {
151 Ok(match val {
152 "*" => Component::Any,
153 "-" => Component::NA,
154 _ => Component::Value(val.to_owned()),
155 })
156 }
157}
158
159impl Component {
160 pub fn matches(&self, val: &str) -> bool {
161 match self {
162 Component::Any => true,
163 Component::NA => false,
164 Component::Value(v) => v == val,
165 }
166 }
167
168 pub fn is_any(&self) -> bool {
169 matches!(self, Component::Any)
170 }
171
172 pub fn is_na(&self) -> bool {
173 matches!(self, Component::NA)
174 }
175
176 pub fn is_value(&self) -> bool {
177 matches!(self, Component::Value(_))
178 }
179}
180
181impl fmt::Display for Component {
182 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
183 write!(
184 f,
185 "{}",
186 match self {
187 Component::Any => "*".to_owned(),
188 Component::NA => "-".to_owned(),
189 Component::Value(v) => v.to_owned(),
190 }
191 )
192 }
193}