1use pct_str::{PctStr, PctString};
2use std::{
3 cmp,
4 hash::{self, Hash},
5 ops,
6};
7
8use static_regular_grammar::RegularGrammar;
9
10use crate::common::QueryImpl;
11
12#[derive(RegularGrammar)]
14#[grammar(
15 file = "src/iri/grammar.abnf",
16 entry_point = "iquery",
17 name = "IRI query",
18 no_deref,
19 cache = "automata/iri/query.aut.cbor"
20)]
21#[grammar(sized(QueryBuf, derive(Debug, Display, PartialEq, Eq, PartialOrd, Ord, Hash)))]
22#[cfg_attr(feature = "serde", grammar(serde))]
23#[cfg_attr(feature = "ignore-grammars", grammar(disable))]
24pub struct Query(str);
25
26impl QueryImpl for Query {
27 unsafe fn new_unchecked(bytes: &[u8]) -> &Self {
28 Self::new_unchecked(std::str::from_utf8_unchecked(bytes))
29 }
30
31 fn as_bytes(&self) -> &[u8] {
32 self.0.as_bytes()
33 }
34}
35
36impl Query {
37 #[inline]
39 pub fn as_pct_str(&self) -> &PctStr {
40 unsafe { PctStr::new_unchecked(self.as_str()) }
41 }
42}
43
44impl ops::Deref for Query {
45 type Target = PctStr;
46
47 fn deref(&self) -> &Self::Target {
48 self.as_pct_str()
49 }
50}
51
52impl cmp::PartialEq for Query {
53 #[inline]
54 fn eq(&self, other: &Query) -> bool {
55 self.as_pct_str() == other.as_pct_str()
56 }
57}
58
59impl Eq for Query {}
60
61impl<'a> PartialEq<&'a str> for Query {
62 #[inline]
63 fn eq(&self, other: &&'a str) -> bool {
64 self.as_str() == *other
65 }
66}
67
68impl PartialOrd for Query {
69 #[inline]
70 fn partial_cmp(&self, other: &Query) -> Option<cmp::Ordering> {
71 Some(self.cmp(other))
72 }
73}
74
75impl Ord for Query {
76 #[inline]
77 fn cmp(&self, other: &Query) -> cmp::Ordering {
78 self.as_pct_str().cmp(other.as_pct_str())
79 }
80}
81
82impl Hash for Query {
83 #[inline]
84 fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
85 self.as_pct_str().hash(hasher)
86 }
87}
88
89impl QueryBuf {
90 pub fn into_pct_string(self) -> PctString {
91 unsafe { PctString::new_unchecked(self.0) }
92 }
93}