1#![allow(clippy::unsafe_derive_deserialize)]
2pub mod basic_delay;
5pub mod delay;
6
7pub mod command {
8 use crux_core::{Request, capability::Operation};
9 use serde::{Deserialize, Serialize};
10
11 #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
12 pub enum AnOperation {
13 One(u8),
14 Two(u8),
15 }
16
17 #[derive(Debug, PartialEq, Eq, Deserialize)]
18 pub enum AnOperationOutput {
19 One(u8),
20 Two(u8),
21 }
22
23 impl Operation for AnOperation {
24 type Output = AnOperationOutput;
25 }
26
27 pub enum Effect {
28 AnEffect(Request<AnOperation>),
29 Http(Request<crux_http::protocol::HttpRequest>),
30 Render(Request<crux_core::render::RenderOperation>),
31 }
32
33 impl From<Request<AnOperation>> for Effect {
34 fn from(request: Request<AnOperation>) -> Self {
35 Self::AnEffect(request)
36 }
37 }
38
39 impl From<Request<crux_http::protocol::HttpRequest>> for Effect {
40 fn from(request: Request<crux_http::protocol::HttpRequest>) -> Self {
41 Self::Http(request)
42 }
43 }
44
45 impl From<Request<crux_core::render::RenderOperation>> for Effect {
46 fn from(request: Request<crux_core::render::RenderOperation>) -> Self {
47 Self::Render(request)
48 }
49 }
50
51 #[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
52 pub struct Post {
53 pub url: String,
54 pub title: String,
55 pub body: String,
56 }
57
58 #[derive(Debug, PartialEq, Eq)]
59 pub enum Event {
60 Start,
61 Completed(AnOperationOutput),
62 Aborted,
63 GotPost(Result<crux_http::Response<Post>, crux_http::HttpError>),
64 }
65
66 #[cfg(test)]
67 mod tests {
68 use crux_http::{
69 command::Http,
70 protocol::{HttpRequest, HttpResponse, HttpResult},
71 testing::ResponseBuilder,
72 };
73
74 use crate::command::{Effect, Event, Post};
75
76 #[test]
77 fn http_post() {
78 const API_URL: &str = "https://example.com/api/posts";
79
80 let mut cmd = Http::post(API_URL)
83 .body(serde_json::json!({"title":"New Post", "body":"Hello!"}))
84 .expect_json()
85 .build()
86 .then_send(Event::GotPost);
87
88 let effect = cmd.effects().next().unwrap();
90 let Effect::Http(mut request) = effect else {
91 panic!("Expected a HTTP effect")
92 };
93
94 assert_eq!(
96 &request.operation,
97 &HttpRequest::post(API_URL)
98 .header("content-type", "application/json")
99 .body(r#"{"body":"Hello!","title":"New Post"}"#)
100 .build()
101 );
102
103 let body = Post {
105 url: API_URL.to_string(),
106 title: "New Post".to_string(),
107 body: "Hello!".to_string(),
108 };
109 request
110 .resolve(HttpResult::Ok(HttpResponse::ok().json(&body).build()))
111 .expect("Resolve should succeed");
112
113 let actual = cmd.events().next().unwrap();
115 let expected = Event::GotPost(Ok(ResponseBuilder::ok().body(body).build()));
116 assert_eq!(actual, expected);
117
118 assert!(cmd.is_done());
119 }
120 }
121}