kutil_http/headers/preferences/
selector.rs1use super::super::super::cache::*;
2
3use std::{cmp::*, fmt, hash::*, str::*};
4
5pub trait IsSpecific {
11 fn is_specific(&self) -> bool;
13}
14
15#[derive(Clone, Debug, Eq)]
21pub enum Selector<SelectionT> {
22 Any,
24
25 Specific(SelectionT),
27}
28
29impl<SelectionT> Selector<SelectionT> {
30 pub fn select<'own>(&'own self, candidates: &'own [SelectionT]) -> Vec<&'own SelectionT>
35 where
36 SelectionT: Eq,
37 {
38 match self {
39 Self::Any => candidates.iter().collect(),
40
41 Self::Specific(selection) => {
42 if candidates.contains(&selection) {
43 vec![selection]
44 } else {
45 Vec::new()
46 }
47 }
48 }
49 }
50}
51
52impl<SelectionT> IsSpecific for Selector<SelectionT> {
53 fn is_specific(&self) -> bool {
54 matches!(self, Self::Specific(_))
55 }
56}
57
58impl<SelectionT> CacheWeight for Selector<SelectionT>
59where
60 SelectionT: CacheWeight,
61{
62 fn cache_weight(&self) -> usize {
63 let mut size = size_of::<Self>();
64 if let Self::Specific(selection) = self {
65 size += selection.cache_weight();
66 }
67 size
68 }
69}
70
71impl<SelectionT> PartialEq for Selector<SelectionT>
72where
73 SelectionT: PartialEq,
74{
75 fn eq(&self, other: &Self) -> bool {
76 match self {
77 Self::Any => matches!(other, Self::Any),
78 Self::Specific(selection) => match other {
79 Self::Any => false,
80 Self::Specific(other_selection) => selection.eq(other_selection),
81 },
82 }
83 }
84}
85
86impl<SelectionT> PartialEq<SelectionT> for Selector<SelectionT>
87where
88 SelectionT: PartialEq,
89{
90 fn eq(&self, other: &SelectionT) -> bool {
91 match self {
92 Self::Any => false,
93 Self::Specific(selection) => selection.eq(other),
94 }
95 }
96}
97
98impl<SelectionT> Hash for Selector<SelectionT>
99where
100 SelectionT: Hash,
101{
102 fn hash<HasherT>(&self, state: &mut HasherT)
103 where
104 HasherT: Hasher,
105 {
106 match self {
107 Self::Any => {
108 state.write_u8(0);
109 }
110
111 Self::Specific(selection) => {
112 state.write_u8(1);
113 selection.hash(state);
114 }
115 }
116 }
117}
118
119impl<SelectionT> From<SelectionT> for Selector<SelectionT> {
120 fn from(selection: SelectionT) -> Self {
121 Self::Specific(selection)
122 }
123}
124
125impl<SelectionT> FromStr for Selector<SelectionT>
126where
127 SelectionT: FromStr,
128{
129 type Err = SelectionT::Err;
130
131 fn from_str(representation: &str) -> Result<Self, Self::Err> {
132 Ok(if representation == "*" { Self::Any } else { Self::Specific(representation.parse()?) })
133 }
134}
135
136impl<SelectionT> fmt::Display for Selector<SelectionT>
137where
138 SelectionT: fmt::Display,
139{
140 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
141 match self {
142 Self::Any => fmt::Display::fmt("*", formatter),
143 Self::Specific(selector) => fmt::Display::fmt(selector, formatter),
144 }
145 }
146}