rl_lang/interpreter/stdlib/http/
http_request.rs1use 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}