Skip to main content

hive_console_sdk/expressions/values/
http.rs

1use std::collections::BTreeMap;
2
3use crate::expressions::{lib::ToVrlValue, FromVrlValue};
4use bytes::Bytes;
5use http::{HeaderMap, HeaderValue, Uri};
6use vrl::core::Value as VrlValue;
7
8/// Error type for HeaderValue conversion failures
9#[derive(Debug, thiserror::Error, Clone)]
10pub enum HeaderValueConversionError {
11    #[error("VRL Array cannot be converted to header value")]
12    UnsupportedArray,
13
14    #[error("VRL Regex cannot be converted to header value")]
15    UnsupportedRegex,
16
17    #[error("VRL Timestamp cannot be converted to header value")]
18    UnsupportedTimestamp,
19
20    #[error("VRL Object cannot be converted to header value")]
21    UnsupportedObject,
22
23    #[error("VRL Null cannot be converted to header value")]
24    UnsupportedNull,
25
26    #[error("Invalid header value: {reason}")]
27    InvalidHeaderValue { reason: String },
28}
29
30impl FromVrlValue for HeaderValue {
31    type Error = HeaderValueConversionError;
32
33    #[inline]
34    fn from_vrl_value(value: VrlValue) -> Result<Self, Self::Error> {
35        match value {
36            VrlValue::Bytes(bytes) => HeaderValue::from_bytes(&bytes).map_err(|e| {
37                HeaderValueConversionError::InvalidHeaderValue {
38                    reason: e.to_string(),
39                }
40            }),
41            VrlValue::Float(f) => HeaderValue::from_str(&f.to_string()).map_err(|e| {
42                HeaderValueConversionError::InvalidHeaderValue {
43                    reason: e.to_string(),
44                }
45            }),
46            VrlValue::Boolean(b) => {
47                let s = if b { "true" } else { "false" };
48                HeaderValue::from_str(s).map_err(|e| {
49                    HeaderValueConversionError::InvalidHeaderValue {
50                        reason: e.to_string(),
51                    }
52                })
53            }
54            VrlValue::Integer(i) => HeaderValue::from_str(&i.to_string()).map_err(|e| {
55                HeaderValueConversionError::InvalidHeaderValue {
56                    reason: e.to_string(),
57                }
58            }),
59            VrlValue::Array(_) => Err(HeaderValueConversionError::UnsupportedArray),
60            VrlValue::Regex(_) => Err(HeaderValueConversionError::UnsupportedRegex),
61            VrlValue::Timestamp(_) => Err(HeaderValueConversionError::UnsupportedTimestamp),
62            VrlValue::Object(_) => Err(HeaderValueConversionError::UnsupportedObject),
63            VrlValue::Null => Err(HeaderValueConversionError::UnsupportedNull),
64        }
65    }
66}
67
68impl ToVrlValue for HeaderMap {
69    fn to_vrl_value(&self) -> VrlValue {
70        let mut obj = BTreeMap::new();
71        for (header_name, header_value) in self.iter() {
72            if let Ok(value) = header_value.to_str() {
73                obj.insert(
74                    header_name.as_str().into(),
75                    VrlValue::Bytes(Bytes::from(value.to_owned())),
76                );
77            }
78        }
79        VrlValue::Object(obj)
80    }
81}
82
83impl ToVrlValue for Uri {
84    fn to_vrl_value(&self) -> VrlValue {
85        VrlValue::Object(BTreeMap::from([
86            ("host".into(), self.host().unwrap_or("unknown").into()),
87            ("path".into(), self.path().into()),
88            (
89                "port".into(),
90                self.port_u16()
91                    .unwrap_or_else(|| {
92                        if self.scheme() == Some(&http::uri::Scheme::HTTPS) {
93                            443
94                        } else {
95                            80
96                        }
97                    })
98                    .into(),
99            ),
100        ]))
101    }
102}