Skip to main content

sim_lib_net_core/
cookbook.rs

1//! Deterministic cookbook builders for net-core recipes.
2
3use crate::{HttpBodyMode, NdjsonDecoder, NetError, SseDecoder, body_mode, parse_http_head};
4
5/// Report produced by the HTTP response-head cookbook recipe.
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct ResponseHeadDemo {
8    /// Parsed status code.
9    pub status: u16,
10    /// Parsed reason phrase.
11    pub reason: String,
12    /// Parsed content type header.
13    pub content_type: String,
14    /// Parsed body framing mode.
15    pub body_mode: HttpBodyMode,
16    /// Event name decoded from a modeled SSE frame.
17    pub sse_event: Option<String>,
18    /// Payload decoded from a modeled SSE frame.
19    pub sse_data: String,
20    /// First NDJSON record decoded from a modeled stream.
21    pub ndjson_record: String,
22}
23
24/// Build the modeled response-head parse report used by the cookbook recipe.
25pub fn response_head_demo() -> Result<ResponseHeadDemo, NetError> {
26    let head = parse_http_head(
27        "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 11\r\n\r\n",
28    )?;
29    let body_mode = body_mode(&head)?;
30    let content_type = head
31        .header("Content-Type")
32        .expect("fixture has content type")
33        .to_owned();
34
35    let mut sse = SseDecoder::new();
36    let mut events = sse.push(b"event: ready\ndata: {\"ok\":true}\n\n")?;
37    let event = events
38        .pop()
39        .expect("cookbook SSE fixture dispatches one event");
40
41    let mut ndjson = NdjsonDecoder::new();
42    let ndjson_record = ndjson
43        .push(b"{\"ok\":true}\n")?
44        .pop()
45        .expect("cookbook NDJSON fixture emits one record");
46
47    Ok(ResponseHeadDemo {
48        status: head.status,
49        reason: head.reason,
50        content_type,
51        body_mode,
52        sse_event: event.event,
53        sse_data: event.data,
54        ndjson_record,
55    })
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn response_head_demo_parses_head_sse_and_ndjson() {
64        let demo = response_head_demo().expect("valid response-head demo");
65
66        assert_eq!(demo.status, 200);
67        assert_eq!(demo.reason, "OK");
68        assert_eq!(demo.content_type, "application/json");
69        assert_eq!(demo.body_mode, HttpBodyMode::ContentLength(11));
70        assert_eq!(demo.sse_event.as_deref(), Some("ready"));
71        assert_eq!(demo.sse_data, "{\"ok\":true}");
72        assert_eq!(demo.ndjson_record, "{\"ok\":true}");
73    }
74}