Skip to content

Commit 6a40c2a

Browse files
Merge pull request #206 from code0-tech/#205-reworked-http-func
reworked http functions
2 parents ca5657a + 34f4e0a commit 6a40c2a

3 files changed

Lines changed: 29 additions & 209 deletions

File tree

crates/taurus-core/src/runtime/engine.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -754,24 +754,18 @@ mod tests {
754754
events.borrow_mut().push(emit_type);
755755
};
756756

757-
let create_response_node = node(
757+
let respond_node = node(
758758
1,
759-
"http::response::create",
759+
"rest::control::respond",
760760
vec![
761761
literal_param(100, "http_status_code", int_value(200)),
762762
literal_param(101, "headers", empty_struct_value()),
763763
literal_param(102, "payload", string_value("hello")),
764764
],
765765
Some(2),
766766
);
767-
let respond_node = node(
768-
2,
769-
"rest::control::respond",
770-
vec![node_result_ref_param(200, "response", 1)],
771-
Some(3),
772-
);
773767
let finish_node = node(
774-
3,
768+
2,
775769
"std::number::add",
776770
vec![
777771
literal_param(300, "lhs", int_value(1)),
@@ -782,7 +776,7 @@ mod tests {
782776

783777
let (_signal, reason) = engine.execute_graph(
784778
1,
785-
vec![create_response_node, respond_node, finish_node],
779+
vec![respond_node, finish_node],
786780
None,
787781
None,
788782
Some(&emitter),

crates/taurus-core/src/runtime/functions/http.rs

Lines changed: 23 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ use ureq::http;
1919
use ureq::{Body, RequestExt};
2020

2121
pub(crate) const FUNCTIONS: &[FunctionRegistration] = &[
22-
FunctionRegistration::eager("http::request::create", create_request, 4),
23-
FunctionRegistration::eager("http::request::send", send_request, 1),
24-
FunctionRegistration::eager("http::response::create", create_response, 3),
25-
FunctionRegistration::eager("rest::control::respond", respond, 1),
22+
FunctionRegistration::eager("http::request::send", send_request, 4),
23+
FunctionRegistration::eager("rest::control::respond", respond, 3),
2624
];
2725

2826
fn fail(category: &str, message: impl Into<String>) -> Signal {
@@ -34,81 +32,20 @@ fn respond(
3432
_ctx: &mut ValueStore,
3533
_run: &mut crate::handler::registry::ThunkRunner<'_>,
3634
) -> Signal {
37-
args!(args => struct_val: Struct);
38-
39-
let fields = &struct_val.fields;
40-
41-
let Some(headers_val) = fields.get("headers") else {
42-
return Signal::Failure(RuntimeError::new(
43-
"T-STD-00001",
44-
"InvalidArgumentRuntimeError",
45-
"Missing 'headers' field".to_string(),
46-
));
47-
};
48-
49-
let Some(status_code_val) = fields.get("http_status_code") else {
50-
return fail(
51-
"InvalidArgumentRuntimeError",
52-
"Missing 'http_status_code' field",
53-
);
54-
};
55-
56-
let Some(payload_val) = fields.get("payload") else {
57-
return Signal::Failure(RuntimeError::new(
58-
"T-STD-00001",
59-
"InvalidArgumentRuntimeError",
60-
"Missing 'payload' field".to_string(),
61-
));
62-
};
63-
64-
let Some(Kind::StructValue(_headers_struct)) = &headers_val.kind else {
65-
return fail(
66-
"InvalidArgumentRuntimeError",
67-
"Expected 'headers' to be StructValue",
68-
);
69-
};
70-
71-
let Some(Kind::NumberValue(_status_code_str)) = &status_code_val.kind else {
72-
return Signal::Failure(RuntimeError::new(
73-
"T-STD-00001",
74-
"InvalidArgumentRuntimeError",
75-
"Expected 'status_code' to be NumberValue".to_string(),
76-
));
77-
};
78-
79-
let Some(_payload_kind) = &payload_val.kind else {
80-
return Signal::Failure(RuntimeError::new(
81-
"T-STD-00001",
82-
"InvalidArgumentRuntimeError",
83-
"Expected 'payload' to have a value".to_string(),
84-
));
85-
};
86-
87-
// `Respond` is a control signal; the executor can still continue with `next` if present.
88-
Signal::Respond(Value {
89-
kind: Some(Kind::StructValue(struct_val.clone())),
90-
})
91-
}
92-
93-
fn create_request(
94-
args: &[Argument],
95-
_ctx: &mut ValueStore,
96-
_run: &mut crate::handler::registry::ThunkRunner<'_>,
97-
) -> Signal {
98-
args!(args => http_method: String, headers: Struct, http_url: String, payload: Value);
99-
let mut fields = std::collections::HashMap::new();
35+
args!(args => http_status_code: i64, headers: Struct, payload: Value);
10036

101-
fields.insert(String::from("http_method"), http_method.to_value());
102-
fields.insert(String::from("url"), http_url.to_value());
103-
fields.insert(String::from("payload"), payload.clone());
37+
let mut fields = HashMap::new();
38+
fields.insert("http_status_code".to_string(), http_status_code.to_value());
10439
fields.insert(
105-
String::from("headers"),
40+
"headers".to_string(),
10641
Value {
107-
kind: Some(Kind::StructValue(headers.clone())),
42+
kind: Some(Kind::StructValue(headers)),
10843
},
10944
);
45+
fields.insert("payload".to_string(), payload);
11046

111-
Signal::Success(Value {
47+
// `Respond` is a control signal; the executor can still continue with `next` if present.
48+
Signal::Respond(Value {
11249
kind: Some(Kind::StructValue(Struct { fields })),
11350
})
11451
}
@@ -118,31 +55,9 @@ fn send_request(
11855
_ctx: &mut ValueStore,
11956
_run: &mut crate::handler::registry::ThunkRunner<'_>,
12057
) -> Signal {
121-
args!(args => http_request: Struct);
122-
123-
let method = match expect_struct_string_field(&http_request, "http_method") {
124-
Ok(value) => value,
125-
Err(signal) => return signal,
126-
};
127-
let url = match expect_struct_string_field(&http_request, "url") {
128-
Ok(value) => value,
129-
Err(signal) => return signal,
130-
};
131-
let headers_struct = match expect_struct_struct_field(&http_request, "headers") {
132-
Ok(value) => value,
133-
Err(signal) => return signal,
134-
};
135-
let payload = match http_request.fields.get("payload") {
136-
Some(value) => value.clone(),
137-
None => {
138-
return fail(
139-
"InvalidArgumentRuntimeError",
140-
"Missing 'payload' field in http_request",
141-
);
142-
}
143-
};
58+
args!(args => http_method: String, headers: Struct, http_url: String, payload: Value);
14459

145-
let mut headers = match encode_headers(&headers_struct) {
60+
let mut headers = match encode_headers(&headers) {
14661
Ok(headers) => headers,
14762
Err(message) => return fail("InvalidArgumentRuntimeError", message),
14863
};
@@ -160,17 +75,17 @@ fn send_request(
16075
headers.insert("content-type".to_string(), default_content_type.to_string());
16176
}
16277

163-
let http_method = match http::Method::from_bytes(method.as_bytes()) {
78+
let http_method = match http::Method::from_bytes(http_method.as_bytes()) {
16479
Ok(value) => value,
16580
Err(_) => {
16681
return fail(
16782
"InvalidArgumentRuntimeError",
168-
format!("Invalid HTTP method '{}'", method),
83+
format!("Invalid HTTP method '{}'", http_method),
16984
);
17085
}
17186
};
17287

173-
let mut request_builder = http::Request::builder().method(http_method).uri(&url);
88+
let mut request_builder = http::Request::builder().method(http_method).uri(&http_url);
17489
for (name, value) in &headers {
17590
request_builder = request_builder.header(name, value);
17691
}
@@ -244,66 +159,6 @@ fn send_request(
244159
})
245160
}
246161

247-
fn create_response(
248-
args: &[Argument],
249-
_ctx: &mut ValueStore,
250-
_run: &mut crate::handler::registry::ThunkRunner<'_>,
251-
) -> Signal {
252-
args!(args => http_status_code: i64, headers: Struct, payload: Value);
253-
let mut fields = std::collections::HashMap::new();
254-
255-
fields.insert(
256-
String::from("http_status_code"),
257-
http_status_code.to_value(),
258-
);
259-
fields.insert(String::from("payload"), payload.clone());
260-
261-
fields.insert(
262-
String::from("headers"),
263-
Value {
264-
kind: Some(Kind::StructValue(headers.clone())),
265-
},
266-
);
267-
268-
Signal::Success(Value {
269-
kind: Some(Kind::StructValue(Struct { fields })),
270-
})
271-
}
272-
273-
fn expect_struct_string_field(struct_val: &Struct, field: &str) -> Result<String, Signal> {
274-
let Some(value) = struct_val.fields.get(field) else {
275-
return Err(fail(
276-
"InvalidArgumentRuntimeError",
277-
format!("Missing '{}' field in http_request", field),
278-
));
279-
};
280-
281-
match &value.kind {
282-
Some(Kind::StringValue(str_val)) => Ok(str_val.clone()),
283-
_ => Err(fail(
284-
"InvalidArgumentRuntimeError",
285-
format!("Expected '{}' to be StringValue", field),
286-
)),
287-
}
288-
}
289-
290-
fn expect_struct_struct_field(struct_val: &Struct, field: &str) -> Result<Struct, Signal> {
291-
let Some(value) = struct_val.fields.get(field) else {
292-
return Err(fail(
293-
"InvalidArgumentRuntimeError",
294-
format!("Missing '{}' field in http_request", field),
295-
));
296-
};
297-
298-
match &value.kind {
299-
Some(Kind::StructValue(struct_val)) => Ok(struct_val.clone()),
300-
_ => Err(fail(
301-
"InvalidArgumentRuntimeError",
302-
format!("Expected '{}' to be StructValue", field),
303-
)),
304-
}
305-
}
306-
307162
fn encode_headers(headers: &Struct) -> Result<HashMap<String, String>, String> {
308163
let mut out = HashMap::with_capacity(headers.fields.len());
309164
for (name, value) in &headers.fields {
@@ -710,26 +565,14 @@ mod tests {
710565
let request_headers = Struct {
711566
fields: HashMap::from([("x-bool".to_string(), true.to_value())]),
712567
};
713-
let request = Struct {
714-
fields: HashMap::from([
715-
("http_method".to_string(), string_value("POST")),
716-
(
717-
"url".to_string(),
718-
string_value(&format!("http://{}/echo?x=1", addr)),
719-
),
720-
(
721-
"headers".to_string(),
722-
Value {
723-
kind: Some(Kind::StructValue(request_headers)),
724-
},
725-
),
726-
("payload".to_string(), request_payload),
727-
]),
728-
};
729-
730-
let args = vec![Argument::Eval(Value {
731-
kind: Some(Kind::StructValue(request)),
732-
})];
568+
let args = vec![
569+
Argument::Eval(string_value("POST")),
570+
Argument::Eval(Value {
571+
kind: Some(Kind::StructValue(request_headers)),
572+
}),
573+
Argument::Eval(string_value(&format!("http://{}/echo?x=1", addr))),
574+
Argument::Eval(request_payload),
575+
];
733576
let mut ctx = ValueStore::default();
734577
let mut run = |_: &crate::handler::argument::Thunk, _: &mut ValueStore| Signal::Stop;
735578

flows/01_return_object.json

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,8 @@
1818
"node_functions": [
1919
{
2020
"definition_source": "taurus",
21-
"databaseId": "2",
22-
"runtimeFunctionId": "rest::control::respond",
23-
"parameters": [
24-
{
25-
"databaseId": "4",
26-
"runtimeParameterId": "http_response",
27-
"value": {
28-
"referenceValue": {
29-
"nodeId": "1"
30-
}
31-
}
32-
}
33-
]
34-
},
35-
{
3621
"databaseId": "1",
37-
"definition_source": "taurus",
38-
"runtimeFunctionId": "http::response::create",
22+
"runtimeFunctionId": "rest::control::respond",
3923
"parameters": [
4024
{
4125
"databaseId": "1",
@@ -72,8 +56,7 @@
7256
}
7357
}
7458
}
75-
],
76-
"nextNodeId": "2"
59+
]
7760
}
7861
]
7962
}

0 commit comments

Comments
 (0)