xsd_types/lexical/
mod.rs

1mod any_uri;
2mod base64_binary;
3mod boolean;
4pub mod date;
5pub mod date_time;
6mod decimal;
7pub mod double;
8pub mod duration;
9pub mod float;
10pub mod g_day;
11pub mod g_month;
12pub mod g_month_day;
13pub mod g_year;
14pub mod g_year_month;
15mod hex_binary;
16mod q_name;
17mod string;
18pub mod time;
19
20pub use base64_binary::*;
21pub use boolean::*;
22pub use date::{Date, DateBuf, InvalidDate};
23pub(crate) use date_time::parse_timezone;
24pub use date_time::{DateTime, DateTimeBuf, DateTimeStamp, DateTimeStampBuf, InvalidDateTime};
25pub use decimal::*;
26pub use double::{Double, DoubleBuf, InvalidDouble};
27pub use duration::{
28	DayTimeDuration, DayTimeDurationBuf, Duration, DurationBuf, InvalidDuration, YearMonthDuration,
29	YearMonthDurationBuf,
30};
31pub use float::{Float, FloatBuf, InvalidFloat};
32pub use g_day::{GDay, GDayBuf, InvalidGDay};
33pub use g_month::{GMonth, GMonthBuf, InvalidGMonth};
34pub use g_month_day::{GMonthDay, GMonthDayBuf, InvalidGMonthDay};
35pub use g_year::{GYear, GYearBuf, InvalidGYear};
36pub use g_year_month::{GYearMonth, GYearMonthBuf, InvalidGYearMonth};
37pub use hex_binary::*;
38pub use q_name::*;
39pub use string::*;
40pub use time::{InvalidTime, Time, TimeBuf};
41
42/// Lexical type.
43pub trait Lexical {
44	type Error;
45
46	fn parse(value: &str) -> Result<&Self, Self::Error>;
47}
48
49impl Lexical for str {
50	type Error = std::convert::Infallible;
51
52	fn parse(value: &str) -> Result<&Self, Self::Error> {
53		Ok(value)
54	}
55}
56
57pub trait LexicalFormOf<V>: Lexical {
58	type ValueError;
59
60	fn try_as_value(&self) -> Result<V, Self::ValueError>;
61
62	fn as_value(&self) -> V
63	where
64		Self: LexicalFormOf<V, ValueError = std::convert::Infallible>,
65	{
66		unsafe {
67			// SAFETY: the error type is not constructible.
68			self.try_as_value().unwrap_unchecked()
69		}
70	}
71}
72
73macro_rules! lexical_form {
74	{
75		$(#[$ty_meta:meta])*
76		ty: $ty:ident,
77
78		$(#[$buffer_ty_meta:meta])*
79		buffer: $buffer_ty:ident,
80
81		$(#[$new_meta:meta])*
82		new,
83
84		$(#[$new_unchecked_meta:meta])*
85		new_unchecked,
86
87		value: $value_ty:ty,
88		error: $error_ty:ident,
89		as_ref: $as_ref:ident,
90		parent_forms: { $( $as_parent_form:ident: $parent_form:ty, $parent_buf_form:ty ),* }
91	} => {
92		#[derive(Debug)]
93		pub struct $error_ty;
94
95		$(#[$ty_meta])*
96		pub struct $ty([u8]);
97
98		$(#[$buffer_ty_meta])*
99		#[derive(Clone)]
100		pub struct $buffer_ty(Vec<u8>);
101
102		impl $ty {
103			$(#[$new_meta])*
104			#[inline(always)]
105			pub fn new<S: ?Sized + AsRef<[u8]>>(s: &S) -> Result<&Self, $error_ty> {
106				if check_bytes(s.as_ref()) {
107					Ok(unsafe { Self::new_unchecked(s) })
108				} else {
109					Err($error_ty)
110				}
111			}
112
113			$(#[$new_unchecked_meta])*
114			#[inline(always)]
115			pub unsafe fn new_unchecked<S: ?Sized + AsRef<[u8]>>(s: &S) -> &Self {
116				std::mem::transmute(s.as_ref())
117			}
118
119			$(#[$new_unchecked_meta])*
120			#[inline(always)]
121			pub const unsafe fn new_unchecked_from_slice(s: &[u8]) -> &Self {
122				std::mem::transmute(s)
123			}
124
125			#[inline(always)]
126			pub fn as_str(&self) -> &str {
127				unsafe { core::str::from_utf8_unchecked(&self.0) }
128			}
129
130			#[inline(always)]
131			pub fn as_bytes(&self) -> &[u8] {
132				&self.0
133			}
134		}
135
136		impl std::fmt::Debug for $ty {
137			#[inline(always)]
138			fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
139				self.as_str().fmt(f)
140			}
141		}
142
143		impl crate::Lexical for $ty {
144			type Error = $error_ty;
145
146			#[inline(always)]
147			fn parse(value: &str) -> Result<&Self, Self::Error> {
148				Self::new(value)
149			}
150		}
151
152		impl std::ops::Deref for $ty {
153			type Target = str;
154
155			#[inline(always)]
156			fn deref(&self) -> &str {
157				self.as_str()
158			}
159		}
160
161		impl AsRef<[u8]> for $ty {
162			fn as_ref(&self) -> &[u8] {
163				&self.0
164			}
165		}
166
167		impl AsRef<str> for $ty {
168			fn as_ref(&self) -> &str {
169				self.as_str()
170			}
171		}
172
173		impl std::borrow::ToOwned for $ty {
174			type Owned = $buffer_ty;
175
176			#[inline(always)]
177			fn to_owned(&self) -> $buffer_ty {
178				unsafe { <$buffer_ty>::new_unchecked(self.as_str().to_owned()) }
179			}
180		}
181
182		impl std::fmt::Display for $ty {
183			#[inline(always)]
184			fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
185				self.as_str().fmt(f)
186			}
187		}
188
189		impl<'a> From<&'a $buffer_ty> for &'a $ty {
190			#[inline(always)]
191			fn from(b: &'a $buffer_ty) -> Self {
192				b.as_ref()
193			}
194		}
195
196		impl $buffer_ty {
197			$(#[$new_meta])*
198			#[inline(always)]
199			pub fn new<S: AsRef<[u8]> + Into<Vec<u8>>>(
200				s: S,
201			) -> Result<Self, ($error_ty, S)> {
202				if check_bytes(s.as_ref()) {
203					Ok(unsafe { Self::new_unchecked(s) })
204				} else {
205					Err(($error_ty, s))
206				}
207			}
208
209			$(#[$new_unchecked_meta])*
210			#[inline(always)]
211			pub unsafe fn new_unchecked(s: impl Into<Vec<u8>>) -> Self {
212				std::mem::transmute(s.into())
213			}
214
215			#[inline(always)]
216			pub fn $as_ref(&self) -> &$ty {
217				unsafe { <$ty>::new_unchecked(&self.0) }
218			}
219
220			#[inline(always)]
221			pub fn into_bytes(self) -> Vec<u8> {
222				self.0
223			}
224
225			#[inline(always)]
226			pub fn into_string(mut self) -> String {
227				let buf = self.0.as_mut_ptr();
228				let len = self.0.len();
229				let capacity = self.0.capacity();
230				core::mem::forget(self);
231				unsafe { String::from_raw_parts(buf, len, capacity) }
232			}
233
234			#[inline(always)]
235			pub fn into_value(self) -> $value_ty {
236				self.value()
237			}
238		}
239
240		impl PartialEq for $buffer_ty {
241			fn eq(&self, other: &Self) -> bool {
242				self.$as_ref().eq(other.$as_ref())
243			}
244		}
245
246		impl Eq for $buffer_ty {}
247
248		impl std::str::FromStr for $buffer_ty {
249			type Err = $error_ty;
250
251			fn from_str(s: &str) -> Result<Self, $error_ty> {
252				Self::new(s.to_owned()).map_err(|(e, _)| e)
253			}
254		}
255
256		impl AsRef<[u8]> for $buffer_ty {
257			#[inline(always)]
258			fn as_ref(&self) -> &[u8] {
259				self.as_bytes()
260			}
261		}
262
263		impl AsRef<str> for $buffer_ty {
264			#[inline(always)]
265			fn as_ref(&self) -> &str {
266				self.as_str()
267			}
268		}
269
270		impl std::ops::Deref for $buffer_ty {
271			type Target = $ty;
272
273			#[inline(always)]
274			fn deref(&self) -> &$ty {
275				self.$as_ref()
276			}
277		}
278
279		impl AsRef<$ty> for $buffer_ty {
280			#[inline(always)]
281			fn as_ref(&self) -> &$ty {
282				self.$as_ref()
283			}
284		}
285
286		impl Borrow<$ty> for $buffer_ty {
287			#[inline(always)]
288			fn borrow(&self) -> &$ty {
289				self.$as_ref()
290			}
291		}
292
293		impl fmt::Display for $buffer_ty {
294			#[inline(always)]
295			fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
296				self.as_str().fmt(f)
297			}
298		}
299
300		impl std::fmt::Debug for $buffer_ty {
301			#[inline(always)]
302			fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
303				self.0.fmt(f)
304			}
305		}
306
307		impl PartialEq<$ty> for $buffer_ty {
308			#[inline(always)]
309			fn eq(&self, other: &$ty) -> bool {
310				self.$as_ref() == other
311			}
312		}
313
314		impl<'a> PartialEq<&'a $ty> for $buffer_ty {
315			#[inline(always)]
316			fn eq(&self, other: &&'a $ty) -> bool {
317				self.$as_ref() == *other
318			}
319		}
320
321		impl PartialEq<$buffer_ty> for $ty {
322			#[inline(always)]
323			fn eq(&self, other: &$buffer_ty) -> bool {
324				self == other.$as_ref()
325			}
326		}
327
328		$(
329			impl $ty {
330				#[inline(always)]
331				pub fn $as_parent_form(&self) -> &$parent_form {
332					self.into()
333				}
334			}
335
336			impl<'a> From<&'a $ty> for &'a $parent_form {
337				#[inline(always)]
338				fn from(value: &'a $ty) -> Self {
339					unsafe { <$parent_form>::new_unchecked(value) }
340				}
341			}
342
343			impl<'a> TryFrom<&'a $parent_form> for &'a $ty {
344				type Error = $error_ty;
345
346				#[inline(always)]
347				fn try_from(i: &'a $parent_form) -> Result<Self, Self::Error> {
348					<$ty>::new(i)
349				}
350			}
351
352			impl TryFrom<$parent_buf_form> for $buffer_ty {
353				type Error = ($error_ty, $parent_buf_form);
354
355				#[inline(always)]
356				fn try_from(i: $parent_buf_form) -> Result<Self, Self::Error> {
357					match Self::new(i.into_string()) {
358						Ok(d) => Ok(d),
359						Err((e, s)) => Err((e, unsafe { <$parent_buf_form>::new_unchecked(s) })),
360					}
361				}
362			}
363
364			impl AsRef<$parent_form> for $ty {
365				#[inline(always)]
366				fn as_ref(&self) -> &$parent_form {
367					self.into()
368				}
369			}
370
371			impl AsRef<$parent_form> for $buffer_ty {
372				#[inline(always)]
373				fn as_ref(&self) -> &$parent_form {
374					self.$as_ref().into()
375				}
376			}
377
378			impl PartialEq<$parent_form> for $ty {
379				#[inline(always)]
380				fn eq(&self, other: &$parent_form) -> bool {
381					self.as_str() == other.as_str()
382				}
383			}
384		)*
385	};
386}
387
388pub(crate) use lexical_form;