sark 0.9.0

Simple Asynchronous Rust webKit - Server
Documentation
use http::StatusCode;
use o3::buffer::{Bytes, Retained, Shared};
use sark::json::JsonEncode;
use sark::service::RouteSpec;

#[sark_gen::json(encode)]
struct Item {
    id: u64,
    name: String,
    score: f64,
}

#[sark_gen::json(encode)]
struct Output {
    ok: bool,
    delta: i64,
    #[field(seq, nested)]
    items: Vec<Item>,
}

#[sark_gen::json(encode)]
struct OwnedText {
    shared: Shared,
    retained: Bytes<Retained>,
}

#[sark_gen::request]
struct OwnedRequest {}

#[sark_gen::response(json)]
struct OwnedReply {
    status: StatusCode,
    body: OwnedText,
}

#[sark_gen::handler]
async fn owned_json(_request: OwnedRequest, _state: &()) -> OwnedReply {
    let shared = Shared::from_static(b"shared");
    OwnedReply {
        status: StatusCode::OK,
        body: OwnedText {
            shared: shared.clone(),
            retained: Bytes::<Retained>::from(shared),
        },
    }
}

#[test]
fn encode_only_supports_owned_output_shapes() {
    let output = Output {
        ok: true,
        delta: -7,
        items: vec![Item {
            id: 3,
            name: String::from("a\"b"),
            score: 1.25,
        }],
    };
    let encoded = output.encode_json();
    assert_eq!(
        encoded.as_slice(),
        br#"{"ok":true,"delta":-7,"items":[{"id":3,"name":"a\"b","score":1.25}]}"#
    );
    assert_eq!(encoded.len(), output.json_len());
}

#[test]
fn encode_only_maps_nonfinite_numbers_to_null() {
    let output = Item {
        id: 0,
        name: String::new(),
        score: f64::INFINITY,
    };
    let encoded = output.encode_json();
    assert_eq!(encoded.as_slice(), br#"{"id":0,"name":"","score":null}"#);
    assert_eq!(encoded.len(), output.json_len());
}

#[test]
fn shared_and_retained_bytes_form_owned_async_json() {
    fn require_route<T: RouteSpec>() {}
    require_route::<owned_json>();

    let shared = Shared::from_static(b"a\"b");
    let output = OwnedText {
        shared: shared.clone(),
        retained: Bytes::<Retained>::from(shared),
    };
    assert_eq!(
        output.encode_json().as_slice(),
        br#"{"shared":"a\"b","retained":"a\"b"}"#
    );
}