1use std::fmt;
2
3use http::HeaderValue;
4
5use crate::Error;
6
7pub(crate) fn from_comma_delimited<'i, I, T, E>(values: &mut I) -> Result<E, Error>
9where
10 I: Iterator<Item = &'i HeaderValue>,
11 T: ::std::str::FromStr,
12 E: ::std::iter::FromIterator<T>,
13{
14 values
15 .flat_map(|value| {
16 value.to_str().into_iter().flat_map(|string| {
17 let mut in_quotes = false;
18 string
19 .split(move |c| {
20 #[allow(clippy::collapsible_else_if)]
21 if in_quotes {
22 if c == '"' {
23 in_quotes = false;
24 }
25 false } else {
27 if c == ',' {
28 true } else {
30 if c == '"' {
31 in_quotes = true;
32 }
33 false }
35 }
36 })
37 .filter_map(|x| match x.trim() {
38 "" => None,
39 y => Some(y),
40 })
41 .map(|x| x.parse().map_err(|_| Error::invalid()))
42 })
43 })
44 .collect()
45}
46
47pub(crate) fn fmt_comma_delimited<T: fmt::Display>(
49 f: &mut fmt::Formatter,
50 mut iter: impl Iterator<Item = T>,
51) -> fmt::Result {
52 if let Some(part) = iter.next() {
53 fmt::Display::fmt(&part, f)?;
54 }
55 for part in iter {
56 f.write_str(", ")?;
57 fmt::Display::fmt(&part, f)?;
58 }
59 Ok(())
60}