1use json_syntax::JsonString;
2use langtag::{LangTag, LangTagBuf};
3
4use crate::{JsonLdDirection, JsonLdLenient};
5
6#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize))]
13pub struct JsonLdLangString {
14 #[cfg_attr(feature = "serde", serde(rename = "@value"))]
16 data: JsonString,
17
18 #[cfg_attr(
19 feature = "serde",
20 serde(rename = "@language", skip_serializing_if = "Option::is_none")
21 )]
22 language: Option<JsonLdLenient<LangTagBuf>>,
23
24 #[cfg_attr(
25 feature = "serde",
26 serde(rename = "@direction", skip_serializing_if = "Option::is_none")
27 )]
28 direction: Option<JsonLdDirection>,
29}
30
31#[derive(Clone, Copy, Debug)]
33pub struct InvalidJsonLdLangString;
34
35impl JsonLdLangString {
36 pub fn new<T>(
38 data: T,
39 language: Option<JsonLdLenient<LangTagBuf>>,
40 direction: Option<JsonLdDirection>,
41 ) -> Result<Self, T>
42 where
43 T: Into<JsonString>,
44 {
45 if language.is_some() || direction.is_some() {
46 Ok(Self {
47 data: data.into(),
48 language,
49 direction,
50 })
51 } else {
52 Err(data)
53 }
54 }
55
56 pub fn from_language(
57 data: impl Into<JsonString>,
58 language: impl Into<JsonLdLenient<LangTagBuf>>,
59 ) -> Self {
60 Self {
61 data: data.into(),
62 language: Some(language.into()),
63 direction: None,
64 }
65 }
66
67 pub fn from_direction(data: impl Into<JsonString>, direction: JsonLdDirection) -> Self {
68 Self {
69 data: data.into(),
70 language: None,
71 direction: Some(direction),
72 }
73 }
74
75 pub fn into_parts(
76 self,
77 ) -> (
78 JsonString,
79 Option<JsonLdLenient<LangTagBuf>>,
80 Option<JsonLdDirection>,
81 ) {
82 (self.data, self.language, self.direction)
83 }
84
85 pub fn parts(
86 &self,
87 ) -> (
88 &str,
89 Option<&JsonLdLenient<LangTagBuf>>,
90 Option<&JsonLdDirection>,
91 ) {
92 (&self.data, self.language.as_ref(), self.direction.as_ref())
93 }
94
95 #[inline(always)]
97 pub fn as_str(&self) -> &str {
98 self.data.as_ref()
99 }
100
101 #[inline(always)]
103 pub fn language(&self) -> Option<JsonLdLenient<&LangTag>> {
104 self.language.as_ref().map(|tag| tag.as_deref())
105 }
106
107 pub fn set_language(
112 &mut self,
113 language: Option<JsonLdLenient<LangTagBuf>>,
114 ) -> Result<(), InvalidJsonLdLangString> {
115 if self.direction.is_some() || language.is_some() {
116 self.language = language;
117 Ok(())
118 } else {
119 Err(InvalidJsonLdLangString)
120 }
121 }
122
123 #[inline(always)]
125 pub fn direction(&self) -> Option<JsonLdDirection> {
126 self.direction
127 }
128
129 pub fn set_direction(
134 &mut self,
135 direction: Option<JsonLdDirection>,
136 ) -> Result<(), InvalidJsonLdLangString> {
137 if direction.is_some() || self.language.is_some() {
138 self.direction = direction;
139 Ok(())
140 } else {
141 Err(InvalidJsonLdLangString)
142 }
143 }
144
145 pub fn set(
150 &mut self,
151 language: Option<JsonLdLenient<LangTagBuf>>,
152 direction: Option<JsonLdDirection>,
153 ) -> Result<(), InvalidJsonLdLangString> {
154 if direction.is_some() || language.is_some() {
155 self.language = language;
156 self.direction = direction;
157 Ok(())
158 } else {
159 Err(InvalidJsonLdLangString)
160 }
161 }
162
163 pub fn as_lang_str(&self) -> JsonLdLangStr<'_> {
165 JsonLdLangStr {
166 data: &self.data,
167 language: self.language.as_ref().map(JsonLdLenient::as_deref),
168 direction: self.direction,
169 }
170 }
171}
172
173#[cfg(feature = "serde")]
174impl<'de> serde::Deserialize<'de> for JsonLdLangString {
175 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
176 where
177 D: serde::Deserializer<'de>,
178 {
179 #[derive(serde::Deserialize)]
180 struct Value {
181 #[serde(rename = "@value")]
182 data: JsonString,
183 #[serde(rename = "@language")]
184 language: Option<JsonLdLenient<LangTagBuf>>,
185 #[serde(rename = "@direction")]
186 direction: Option<JsonLdDirection>,
187 }
188
189 let value = Value::deserialize(deserializer)?;
190
191 Self::new(value.data, value.language, value.direction).map_err(serde::de::Error::custom)
192 }
193}
194
195#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
201#[cfg_attr(feature = "serde", derive(serde::Serialize))]
202pub struct JsonLdLangStr<'a> {
203 #[cfg_attr(feature = "serde", serde(rename = "@value"))]
205 data: &'a str,
206
207 #[cfg_attr(
208 feature = "serde",
209 serde(rename = "@language", skip_serializing_if = "Option::is_none")
210 )]
211 language: Option<JsonLdLenient<&'a LangTag>>,
212
213 #[cfg_attr(
214 feature = "serde",
215 serde(rename = "@direction", skip_serializing_if = "Option::is_none")
216 )]
217 direction: Option<JsonLdDirection>,
218}
219
220impl<'a> JsonLdLangStr<'a> {
221 pub fn new(
223 data: &'a str,
224 language: Option<JsonLdLenient<&'a LangTag>>,
225 direction: Option<JsonLdDirection>,
226 ) -> Result<Self, InvalidJsonLdLangString> {
227 if language.is_some() || direction.is_some() {
228 Ok(Self {
229 data,
230 language,
231 direction,
232 })
233 } else {
234 Err(InvalidJsonLdLangString)
235 }
236 }
237
238 pub fn into_parts(
239 self,
240 ) -> (
241 &'a str,
242 Option<JsonLdLenient<&'a LangTag>>,
243 Option<JsonLdDirection>,
244 ) {
245 (self.data, self.language, self.direction)
246 }
247
248 #[inline(always)]
250 pub fn as_str(&self) -> &'a str {
251 self.data
252 }
253
254 #[inline(always)]
256 pub fn language(&self) -> Option<JsonLdLenient<&'a LangTag>> {
257 self.language
258 }
259
260 #[inline(always)]
262 pub fn direction(&self) -> Option<JsonLdDirection> {
263 self.direction
264 }
265}