1use nu_protocol::Value;
2use std::collections::HashMap;
3use std::path::PathBuf;
4
5#[derive(Clone, Debug, serde::Serialize)]
6#[serde(untagged)]
7pub enum HeaderValue {
8 Single(String),
9 Multiple(Vec<String>),
10}
11
12#[derive(Clone, Debug)]
13pub struct Response {
14 pub status: u16,
15 pub headers: HashMap<String, HeaderValue>,
16 pub body_type: ResponseBodyType,
17}
18
19#[derive(Clone, Debug)]
20pub enum ResponseBodyType {
21 Normal,
22 Static {
23 root: PathBuf,
24 path: String,
25 fallback: Option<String>,
26 },
27 ReverseProxy {
28 target_url: String,
29 headers: HashMap<String, HeaderValue>,
30 preserve_host: bool,
31 strip_prefix: Option<String>,
32 request_body: Vec<u8>,
33 query: Option<HashMap<String, String>>,
34 },
35}
36
37#[derive(Debug)]
38pub enum ResponseTransport {
39 Empty,
40 Full(Vec<u8>),
41 Stream(tokio::sync::mpsc::Receiver<Vec<u8>>),
42}
43
44pub fn value_to_json(value: &Value) -> serde_json::Value {
45 match value {
46 Value::Nothing { .. } => serde_json::Value::Null,
47 Value::Bool { val, .. } => serde_json::Value::Bool(*val),
48 Value::Int { val, .. } => serde_json::Value::Number((*val).into()),
49 Value::Float { val, .. } => serde_json::Number::from_f64(*val)
50 .map(serde_json::Value::Number)
51 .unwrap_or(serde_json::Value::Null),
52 Value::String { val, .. } => serde_json::Value::String(val.clone()),
53 Value::List { vals, .. } => {
54 serde_json::Value::Array(vals.iter().map(value_to_json).collect())
55 }
56 Value::Record { val, .. } => {
57 let mut map = serde_json::Map::new();
58 for (k, v) in val.iter() {
59 map.insert(k.clone(), value_to_json(v));
60 }
61 serde_json::Value::Object(map)
62 }
63 _ => todo!(),
64 }
65}
66
67pub fn value_to_bytes(value: Value) -> Vec<u8> {
68 match value {
69 Value::Nothing { .. } => Vec::new(),
70 Value::String { val, .. } => val.into_bytes(),
71 Value::Int { val, .. } => val.to_string().into_bytes(),
72 Value::Float { val, .. } => val.to_string().into_bytes(),
73 Value::Binary { val, .. } => val,
74 Value::Bool { val, .. } => val.to_string().into_bytes(),
75
76 Value::Record { val, .. } if val.get("__html").is_some() => match val.get("__html") {
78 Some(Value::String { val, .. }) => val.clone().into_bytes(),
79 _ => Vec::new(),
80 },
81
82 Value::List { .. } | Value::Record { .. } => serde_json::to_string(&value_to_json(&value))
84 .unwrap_or_else(|_| String::new())
85 .into_bytes(),
86
87 _ => todo!("value_to_bytes: {:?}", value),
88 }
89}