1use core::borrow::Borrow;
4use core::cmp::Ordering;
5use core::fmt::Display;
6use core::iter::{Extend, FromIterator};
7use core::marker::PhantomData;
8
9use super::Request;
10use crate::serializer::Serializer;
11
12#[cfg_attr(feature = "alloc", doc = " ```")]
19#[cfg_attr(not(feature = "alloc"), doc = " ```ignore")]
20pub struct ParameterList<
32 K,
33 V,
34 #[cfg(feature = "alloc")] A = alloc::vec::Vec<(K, V)>,
35 #[cfg(not(feature = "alloc"))] A,
36 P = (K, V),
37> {
38 list: A,
39 #[allow(clippy::type_complexity)]
40 marker: PhantomData<fn() -> (K, V, P)>,
41}
42
43pub struct Iter<'a, K, V, P> {
47 inner: core::slice::Iter<'a, P>,
48 marker: PhantomData<fn() -> (K, V)>,
49}
50
51impl<K, V, A, P> ParameterList<K, V, A, P>
52where
53 K: AsRef<str>,
54 V: Display,
55 A: AsRef<[P]>,
56 P: Borrow<(K, V)>,
57{
58 pub fn from_sorted(list: A) -> Option<Self> {
62 if is_sorted_by(list.as_ref(), cmp) {
63 Some(ParameterList {
64 list,
65 marker: PhantomData,
66 })
67 } else {
68 None
69 }
70 }
71}
72
73impl<K, V, A, P> ParameterList<K, V, A, P>
74where
75 K: AsRef<str>,
76 V: Display,
77 A: AsRef<[P]> + AsMut<[P]>,
78 P: Borrow<(K, V)>,
79{
80 pub fn new(list: A) -> Self {
84 let mut ret = ParameterList {
85 list,
86 marker: PhantomData,
87 };
88 ret.sort();
89 ret
90 }
91}
92
93impl<K, V, A, P> ParameterList<K, V, A, P> {
94 pub fn into_inner(self) -> A {
96 self.list
97 }
98}
99
100impl<K, V, A, P> ParameterList<K, V, A, P>
101where
102 K: AsRef<str>,
103 V: Display,
104 A: AsMut<[P]>,
105 P: Borrow<(K, V)>,
106{
107 fn sort(&mut self) {
108 self.list.as_mut().sort_unstable_by(cmp);
109 }
110}
111
112impl<K, V, A, P> ParameterList<K, V, A, P>
113where
114 A: AsRef<[P]>,
115 P: Borrow<(K, V)>,
116{
117 pub fn iter(&self) -> Iter<'_, K, V, P> {
119 Iter {
120 inner: self.list.as_ref().iter(),
121 marker: PhantomData,
122 }
123 }
124}
125
126impl<K, V, A, P> AsRef<[P]> for ParameterList<K, V, A, P>
127where
128 A: AsRef<[P]>,
129{
130 fn as_ref(&self) -> &[P] {
131 self.list.as_ref()
132 }
133}
134
135impl<K, V, A, P> Default for ParameterList<K, V, A, P>
136where
137 K: AsRef<str>,
138 V: Display,
139 A: AsRef<[P]> + Default,
140 P: Borrow<(K, V)>,
141{
142 fn default() -> Self {
143 ParameterList {
144 list: A::default(),
145 marker: PhantomData,
146 }
147 }
148}
149
150impl<K, V, A, P> From<A> for ParameterList<K, V, A, P>
151where
152 K: AsRef<str>,
153 V: Display,
154 A: AsRef<[P]> + AsMut<[P]>,
155 P: Borrow<(K, V)>,
156{
157 fn from(list: A) -> Self {
158 ParameterList::new(list)
159 }
160}
161
162impl<K, V, A, P> FromIterator<P> for ParameterList<K, V, A, P>
163where
164 K: AsRef<str>,
165 V: Display,
166 A: AsRef<[P]> + AsMut<[P]> + FromIterator<P>,
167 P: Borrow<(K, V)>,
168{
169 fn from_iter<I>(iter: I) -> Self
170 where
171 I: IntoIterator<Item = P>,
172 {
173 ParameterList::new(iter.into_iter().collect())
174 }
175}
176
177impl<K, V, A, P> Extend<P> for ParameterList<K, V, A, P>
178where
179 K: AsRef<str>,
180 V: Display,
181 A: AsMut<[P]> + Extend<P>,
182 P: Borrow<(K, V)>,
183{
184 fn extend<I>(&mut self, iter: I)
185 where
186 I: IntoIterator<Item = P>,
187 {
188 self.list.extend(iter);
189 self.sort();
190 }
191}
192
193impl<K, V, A, P> Request for ParameterList<K, V, A, P>
194where
195 K: AsRef<str>,
196 V: Display,
197 A: AsRef<[P]>,
198 P: Borrow<(K, V)>,
199{
200 fn serialize<S>(&self, serializer: S) -> S::Output
201 where
202 S: Serializer,
203 {
204 return inner::<S, K, V, P>(self.list.as_ref(), serializer);
205
206 fn inner<S, K, V, P>(this: &[P], serializer: S) -> S::Output
207 where
208 S: Serializer,
209 K: AsRef<str>,
210 V: Display,
211 P: Borrow<(K, V)>,
212 {
213 super::AssertSorted::new(this.iter().map(|pair| {
214 let (ref k, ref v) = *pair.borrow();
215 (k, v)
216 }))
217 .serialize(serializer)
218 }
219 }
220}
221
222impl<'a, K: 'a, V: 'a, P> Iterator for Iter<'a, K, V, P>
223where
224 P: Borrow<(K, V)>,
225{
226 type Item = &'a (K, V);
227
228 fn next(&mut self) -> Option<Self::Item> {
229 self.inner.next().map(Borrow::borrow)
230 }
231}
232
233fn cmp<K, V, P>(lhs: &P, rhs: &P) -> Ordering
234where
235 K: AsRef<str>,
236 V: Display,
237 P: Borrow<(K, V)>,
238{
239 let (ref kl, ref vl) = *lhs.borrow();
240 let (ref kr, ref vr) = *rhs.borrow();
241 return inner(kl.as_ref(), vl, kr.as_ref(), vr);
242 fn inner<V: Display>(kl: &str, vl: &V, kr: &str, vr: &V) -> Ordering {
243 (kl, fmt_cmp::Cmp(vl)).cmp(&(kr, fmt_cmp::Cmp(vr)))
244 }
245}
246
247fn is_sorted_by<T, F>(slice: &[T], mut cmp: F) -> bool
250where
251 F: FnMut(&T, &T) -> Ordering,
252{
253 slice
254 .windows(2)
255 .all(|slice| !matches!(cmp(&slice[1], &slice[0]), Ordering::Less))
256}