Skip to main content

rl_lang/interpreter/stdlib/http/
http_request.rs

1use crate::{
2    interpreter::{
3        evaluator::Evaluator,
4        stdlib::{
5            common::{check_arity_range, extract_string, verr, vs},
6            http::common::ureq_result_to_value,
7        },
8        values::Value,
9    },
10    utils::{errors::Error, span::Span},
11};
12
13pub fn func(_: &mut Evaluator, args: Vec<Value>, span: Span) -> Result<Value, Error> {
14    check_arity_range(&args, 2, 4, "http_request", span)?;
15
16    let method = match extract_string(args[0].clone(), "http_request") {
17        Ok(s) => s,
18        Err(e) => return Ok(verr!(vs!(format!("http_request: {e}")))),
19    };
20    let url = match extract_string(args[1].clone(), "http_request") {
21        Ok(s) => s,
22        Err(e) => return Ok(verr!(vs!(format!("http_request: {e}")))),
23    };
24    let body = match args.get(2) {
25        Some(Value::String(s)) => Some(s.clone()),
26        Some(other) => {
27            return Ok(verr!(vs!(format!(
28                "http_request: expects a string body, got {}",
29                other.type_name()
30            ))));
31        }
32        None => None,
33    };
34
35    let mut request = ureq::request(&method, &url);
36    if let Some(Value::Values { items, .. }) = args.get(3) {
37        for item in items {
38            match item {
39                Value::Tuple(pair) if pair.len() == 2 => {
40                    if let (Value::String(name), Value::String(value)) = (&pair[0], &pair[1]) {
41                        request = request.set(name, value);
42                        continue;
43                    }
44                    return Ok(verr!(vs!(
45                        "http_request: expects headers as an array of (string, string) tuples"
46                            .to_string()
47                    )));
48                }
49                _ => {
50                    return Ok(verr!(vs!(
51                        "http_request: expects headers as an array of (string, string) tuples"
52                            .to_string()
53                    )));
54                }
55            }
56        }
57    } else if args.get(3).is_some() {
58        return Ok(verr!(vs!(
59            "http_request: expects headers as an array of (string, string) tuples".to_string()
60        )));
61    }
62
63    let result = match &body {
64        Some(b) => request.send_string(b),
65        None => request.call(),
66    };
67    Ok(ureq_result_to_value(&url, result))
68}