mediatype/
params.rs

1use super::{name::*, parse::*, value::*};
2
3/// An iterator over the parameters.
4#[derive(Debug)]
5pub struct Params<'a> {
6    source: ParamsSource<'a>,
7    index: usize,
8}
9
10impl<'a> Params<'a> {
11    pub(crate) const fn from_slice(s: &'a [(Name<'a>, Value<'a>)]) -> Self {
12        Self {
13            source: ParamsSource::Slice(s),
14            index: 0,
15        }
16    }
17
18    pub(crate) const fn from_indices(s: &'a str, i: &'a Indices) -> Self {
19        Self {
20            source: ParamsSource::Indices(s, i),
21            index: 0,
22        }
23    }
24}
25
26#[derive(Debug)]
27enum ParamsSource<'a> {
28    Slice(&'a [(Name<'a>, Value<'a>)]),
29    Indices(&'a str, &'a Indices),
30}
31
32impl<'a> Iterator for Params<'a> {
33    type Item = (Name<'a>, Value<'a>);
34
35    fn next(&mut self) -> Option<Self::Item> {
36        let index = self.index;
37        match self.source {
38            ParamsSource::Slice(s) => {
39                if index >= s.len() {
40                    None
41                } else {
42                    self.index += 1;
43                    Some((s[index].0, s[index].1))
44                }
45            }
46            ParamsSource::Indices(s, i) => {
47                if index >= i.params().len() {
48                    None
49                } else {
50                    self.index += 1;
51                    let param = i.params()[index];
52                    Some((
53                        Name::new_unchecked(&s[param[0]..param[1]]),
54                        Value::new_unchecked(&s[param[2]..param[3]]),
55                    ))
56                }
57            }
58        }
59    }
60
61    fn size_hint(&self) -> (usize, Option<usize>) {
62        let len = match self.source {
63            ParamsSource::Slice(s) => s.len(),
64            ParamsSource::Indices(_, i) => i.params().len(),
65        };
66        (len, Some(len))
67    }
68}
69
70/// A trait for getting parameter values.
71pub trait ReadParams {
72    /// Returns the parameters.
73    fn params(&self) -> Params;
74
75    /// Gets the parameter value by its name.
76    ///
77    /// If the same name appears more than once, returns the last value.
78    fn get_param(&self, name: Name) -> Option<Value>;
79}
80
81/// A trait for mutating parameter values.
82pub trait WriteParams<'a>: ReadParams {
83    /// Sets a parameter value.
84    ///
85    /// If the parameters with the name already exist, they will be removed.
86    ///
87    /// ```
88    /// # use mediatype::{names::*, values::*, MediaType, WriteParams};
89    /// let madia_type = "text/plain; charset=UTF-8; charset=US-ASCII; format=fixed";
90    ///
91    /// let mut text_plain = MediaType::parse(madia_type).unwrap();
92    /// text_plain.set_param(CHARSET, UTF_8);
93    ///
94    /// assert_eq!(
95    ///     text_plain.to_string(),
96    ///     "text/plain; format=fixed; charset=UTF-8"
97    /// );
98    /// ```
99    fn set_param<'n: 'a, 'v: 'a>(&mut self, name: Name<'n>, value: Value<'v>);
100
101    /// Removes all parameters with the name.
102    fn remove_params(&mut self, name: Name);
103
104    /// Removes all parameters.
105    fn clear_params(&mut self);
106}