backblaze_b2_client/util/
into_header_map.rs

1use std::{collections::HashMap, str::FromStr};
2
3use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
4use serde::Serialize;
5
6use crate::error::IntoHeaderMapError;
7
8pub trait IntoHeaderMap: Sized + Serialize {
9    fn into_header_map(self) -> Result<HeaderMap, IntoHeaderMapError> {
10        let serialized_object = serde_json::to_value(self)
11            .map_err(|err| IntoHeaderMapError::SerializationFailed(err))?;
12
13        match serialized_object {
14            serde_json::Value::Object(object) => object
15                .into_iter()
16                .filter_map(|(key, value)| {
17                    let value = match value {
18                        serde_json::Value::Null => return None,
19                        serde_json::Value::String(value) => value,
20                        val => val.to_string(),
21                    };
22
23                    let header_name = match HeaderName::from_str(&key) {
24                        Ok(header_name) => header_name,
25                        Err(_) => return Some(Err(IntoHeaderMapError::InvalidHeaderName(key))),
26                    };
27
28                    let header_value = match HeaderValue::from_str(&value) {
29                        Ok(header_value) => header_value,
30                        Err(_) => return Some(Err(IntoHeaderMapError::InvalidHeaderValue(value))),
31                    };
32
33                    Some(Ok((header_name, header_value)))
34                })
35                .collect(),
36            _ => return Err(IntoHeaderMapError::InvalidObject),
37        }
38    }
39}
40
41impl<A: Sized + Serialize, B: Sized + Serialize> IntoHeaderMap for HashMap<A, B> {}