flaron-sdk 1.1.0

Official Rust SDK for writing Flaron edge flares - WebAssembly modules that run on the Flaron CDN edge runtime.
Documentation
//! Build the outbound HTTP response.
//!
//! Each setter mutates host-side state for the current invocation. The flare
//! must return [`crate::FlareAction::Respond`] from its `handle_request`
//! export for the assembled response to be sent to the client.

use crate::{ffi, mem};

/// Set the HTTP status code (defaults to `200` if never called).
pub fn set_status(code: u16) {
    unsafe { ffi::resp_set_status(code as i32) }
}

/// Set a response header. Calling with the same name twice overwrites the
/// previous value - there is no append semantics.
///
/// Header names are case-insensitive at the wire level but the host
/// preserves whatever casing you pass.
pub fn set_header(name: &str, value: &str) {
    let (name_ptr, name_len) = mem::host_arg_str(name);
    let (val_ptr, val_len) = mem::host_arg_str(value);
    unsafe { ffi::resp_header_set(name_ptr, name_len, val_ptr, val_len) }
}

/// Set the response body as raw bytes. Pass an empty slice for an empty body.
pub fn set_body(body: &[u8]) {
    let (body_ptr, body_len) = mem::host_arg_bytes(body);
    unsafe { ffi::resp_body_set(body_ptr, body_len) }
}

/// Convenience: set the response body from a string slice.
pub fn set_body_str(body: &str) {
    set_body(body.as_bytes())
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::ffi::test_host;

    #[test]
    fn set_status_records_code() {
        test_host::reset();
        set_status(404);
        assert_eq!(test_host::read_mock(|m| m.resp_status), Some(404));
    }

    #[test]
    fn set_header_records_pair() {
        test_host::reset();
        set_header("content-type", "application/json");
        set_header("x-trace", "abc-123");
        let headers = test_host::read_mock(|m| m.resp_headers.clone());
        assert_eq!(
            headers,
            vec![
                ("content-type".into(), "application/json".into()),
                ("x-trace".into(), "abc-123".into()),
            ]
        );
    }

    #[test]
    fn set_body_records_bytes() {
        test_host::reset();
        set_body(b"hello world");
        assert_eq!(
            test_host::read_mock(|m| m.resp_body.clone()),
            Some(b"hello world".to_vec())
        );
    }

    #[test]
    fn set_body_str_records_utf8() {
        test_host::reset();
        set_body_str("héllo");
        assert_eq!(
            test_host::read_mock(|m| m.resp_body.clone()),
            Some("héllo".as_bytes().to_vec())
        );
    }
}