http_types/utils/
mod.rs

1mod date;
2
3pub(crate) use date::fmt_http_date;
4pub(crate) use date::parse_http_date;
5pub(crate) use date::HttpDate;
6
7use crate::{Error, Status, StatusCode};
8
9use std::cmp::Ordering;
10use std::str::FromStr;
11
12/// Parse a weight of the form `q=0.123`.
13pub(crate) fn parse_weight(s: &str) -> crate::Result<f32> {
14    let mut parts = s.split('=');
15    if !matches!(parts.next(), Some("q")) {
16        let mut err = Error::new_adhoc("invalid weight");
17        err.set_status(StatusCode::BadRequest);
18        return Err(err);
19    }
20    match parts.next() {
21        Some(s) => {
22            let weight = f32::from_str(s).status(400)?;
23            Ok(weight)
24        }
25        None => {
26            let mut err = Error::new_adhoc("invalid weight");
27            err.set_status(StatusCode::BadRequest);
28            Err(err)
29        }
30    }
31}
32
33/// Order proposals by weight. Try ordering by q value first. If equal or undefined,
34/// order by index, favoring the latest provided value.
35pub(crate) fn sort_by_weight<T: PartialOrd + Clone>(props: &mut Vec<T>) {
36    let mut arr: Vec<(usize, T)> = props.iter().cloned().enumerate().collect();
37    arr.sort_unstable_by(|a, b| match b.1.partial_cmp(&a.1) {
38        None | Some(Ordering::Equal) => b.0.cmp(&a.0),
39        Some(ord) => ord,
40    });
41    *props = arr.into_iter().map(|(_, t)| t).collect::<Vec<T>>();
42}