fn deserialize_multi_value_headers()

in lambda-http/src/request.rs [297:336]


fn deserialize_multi_value_headers<'de, D>(deserializer: D) -> Result<http::HeaderMap, D::Error>
where
    D: Deserializer<'de>,
{
    struct HeaderVisitor;

    impl<'de> Visitor<'de> for HeaderVisitor {
        type Value = http::HeaderMap;

        fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(formatter, "a multi valued HeaderMap<HeaderValue>")
        }

        fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
        where
            A: MapAccess<'de>,
        {
            let mut headers = map
                .size_hint()
                .map(http::HeaderMap::with_capacity)
                .unwrap_or_else(http::HeaderMap::new);
            while let Some((key, values)) = map.next_entry::<Cow<'_, str>, Vec<Cow<'_, str>>>()? {
                // note the aws docs for multi value headers include an empty key. I'm not sure if this is a doc bug
                // or not by the http crate doesn't handle it
                // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
                if !key.is_empty() {
                    for value in values {
                        let header_name = key.parse::<http::header::HeaderName>().map_err(A::Error::custom)?;
                        let header_value = http::header::HeaderValue::from_maybe_shared(value.into_owned())
                            .map_err(A::Error::custom)?;
                        headers.append(header_name, header_value);
                    }
                }
            }
            Ok(headers)
        }
    }

    Ok(deserializer.deserialize_map(HeaderVisitor).unwrap_or_default())
}