use qubit_budget::json::JsonEncodeLimits;
use qubit_budget::json::JsonEncodeSession;
use qubit_budget::json::JsonResource;
use serde::Serialize;
use serde::Serializer;
use crate::encode::json_encode_test_support::encode;
#[derive(Serialize)]
struct Pair {
left: u8,
right: u8,
}
#[derive(Serialize)]
struct Triple(u8, u8);
struct Bytes;
impl Serialize for Bytes {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(&[1, 10, 100])
}
}
struct BoundaryBytes;
impl Serialize for BoundaryBytes {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(&[9, 10, 99, 100, 255])
}
}
#[test]
fn test_json_encode_compound_serializes_struct_members() {
let mut session = JsonEncodeSession::from_limits(JsonEncodeLimits::<JsonResource, usize>::builder().build());
let output = encode(&Pair { left: 1, right: 2 }, &mut session).expect("compound JSON should serialize");
assert_eq!(output, br#"{"left":1,"right":2}"#);
}
#[test]
fn test_json_encode_compound_serializes_tuple_struct_fields() {
let mut session = JsonEncodeSession::from_limits(JsonEncodeLimits::<JsonResource, usize>::builder().build());
let output = encode(&Triple(3, 4), &mut session).expect("tuple-struct JSON should serialize");
assert_eq!(output, b"[3,4]");
}
#[test]
fn test_json_encode_bytes_charge_decimal_width_boundaries() {
let exact_limits = JsonEncodeLimits::<JsonResource, usize>::builder()
.max_number_bytes(3)
.max_payload_bytes(11)
.build();
let mut exact = JsonEncodeSession::from_limits(exact_limits);
assert_eq!(
encode(&BoundaryBytes, &mut exact).expect("exact byte budgets must fit"),
b"[9,10,99,100,255]",
);
let number_limits = JsonEncodeLimits::<JsonResource, usize>::builder()
.max_number_bytes(2)
.build();
let mut short_number = JsonEncodeSession::from_limits(number_limits);
assert!(
encode(&BoundaryBytes, &mut short_number).is_err(),
"100 must cross the two-to-three-digit number boundary",
);
let payload_limits = JsonEncodeLimits::<JsonResource, usize>::builder()
.max_payload_bytes(10)
.build();
let mut short_payload = JsonEncodeSession::from_limits(payload_limits);
assert!(
encode(&BoundaryBytes, &mut short_payload).is_err(),
"decimal byte widths must consume eleven payload bytes",
);
}
#[test]
fn test_json_encode_scalar_paths_support_u8_quantities() {
macro_rules! assert_scalar {
($value:expr) => {{
let mut session = JsonEncodeSession::<JsonResource, u8>::from_limits(
JsonEncodeLimits::<JsonResource, u8>::builder().build(),
);
encode(&$value, &mut session).expect("scalar should fit an unconfigured budget");
}};
}
assert_scalar!(-1_i8);
assert_scalar!(-1_i16);
assert_scalar!(-1_i32);
assert_scalar!(-1_i64);
assert_scalar!(-1_i128);
assert_scalar!(1_u8);
assert_scalar!(1_u16);
assert_scalar!(1_u32);
assert_scalar!(1_u64);
assert_scalar!(1_u128);
assert_scalar!(1.5_f32);
assert_scalar!(2.5_f64);
assert_scalar!('x');
assert_scalar!("text");
assert_scalar!(Some(1_u8));
assert_scalar!(None::<u8>);
assert_scalar!(());
assert_scalar!(vec![1_u8]);
assert_scalar!(Bytes);
}