reddb-io-engine 1.26.8

Shared RedDB query execution and storage primitives for native and WebAssembly runtimes.
Documentation
use super::{codec_corpus, metadata_corpus};
use reddb_engine::storage::{
    entity_codec::write_entity_binary,
    metadata::{Metadata, MetadataValue},
    metadata_codec::*,
};

pub const CASES: &[(&str, fn())] = &[
    ("metadata_codec_native_goldens", native_goldens),
    ("metadata_codec_record_envelopes", record_envelopes),
    ("metadata_codec_malformed_payloads", malformed_payloads),
    ("metadata_codec_depth_boundary", depth_boundary),
];

fn native_goldens() {
    let golden = include_bytes!("../fixtures/native-metadata.bin");
    let metadata = metadata_corpus::metadata();
    assert_eq!(serialize_metadata(Some(&metadata)), golden);
    assert_eq!(
        deserialize_metadata(golden)
            .expect("native metadata")
            .fields,
        metadata.fields
    );
    let decoded = deserialize_metadata(golden).expect("native metadata");
    assert_eq!(serialize_metadata(Some(&decoded)), golden);
    assert!(serialize_metadata(None).is_empty());
    assert!(serialize_metadata(Some(&Metadata::new())).is_empty());
    assert!(deserialize_metadata(&[0; 4])
        .expect("zero fields")
        .is_empty());
}

fn record_envelopes() {
    let metadata = metadata_corpus::metadata();
    for version in 1..=reddb_file::STORE_VERSION_CURRENT {
        for entity in codec_corpus::entities() {
            let mut bare = vec![];
            write_entity_binary(&mut bare, &entity, version);
            for metadata in [None, Some(&metadata)] {
                let record = serialize_entity_record(&entity, metadata, version);
                let expected = reddb_file::encode_native_entity_record_frame(
                    &bare,
                    metadata.map(|_| include_bytes!("../fixtures/native-metadata.bin").as_slice()),
                );
                assert_eq!(record, expected, "original native framing V{version}");
                let (decoded, decoded_metadata) =
                    deserialize_entity_record(&record, version).expect("framed record");
                assert_eq!(decoded.id, entity.id);
                assert_eq!(
                    decoded_metadata.as_ref().map(|m| &m.fields),
                    metadata.map(|m| &m.fields)
                );
            }
            let (decoded, metadata) =
                deserialize_entity_record(&bare, version).expect("legacy bare entity");
            assert_eq!(decoded.id, entity.id);
            assert!(metadata.is_none());
        }
    }
}

fn malformed_payloads() {
    let golden = include_bytes!("../fixtures/native-metadata.bin");
    for end in 0..golden.len() {
        assert!(
            deserialize_metadata(&golden[..end]).is_err(),
            "truncated at {end}"
        );
    }
    assert!(deserialize_metadata(&u32::MAX.to_le_bytes()).is_err());
    for tag in [6, 7, 11] {
        let mut bytes = vec![1, 0, 0, 0, 0, 0, 0, 0, tag];
        bytes.extend_from_slice(&u32::MAX.to_le_bytes());
        assert!(
            deserialize_metadata(&bytes).is_err(),
            "invalid count for tag {tag}"
        );
    }
    for tail in [vec![255], vec![10, 255], vec![4, 1, 0, 0, 0, 255]] {
        let mut bytes = vec![1, 0, 0, 0, 0, 0, 0, 0];
        bytes.extend(tail);
        assert!(deserialize_metadata(&bytes).is_err());
    }
    let entity = &codec_corpus::entities()[0];
    let mut bare = vec![];
    write_entity_binary(&mut bare, entity, 12);
    let record = reddb_file::encode_native_entity_record_frame(&bare, Some(&[255]));
    assert!(deserialize_entity_record(&record, 12).is_err());
}

fn depth_boundary() {
    let mut value = MetadataValue::Null;
    for _ in 0..reddb_rql::limits::JSON_LITERAL_MAX_DEPTH {
        value = MetadataValue::Array(vec![value]);
    }
    let mut metadata = Metadata::new();
    metadata.set("nested", value.clone());
    let bytes = serialize_metadata(Some(&metadata));
    assert_eq!(
        deserialize_metadata(&bytes)
            .expect("supported depth")
            .fields,
        metadata.fields
    );
    metadata.set("nested", MetadataValue::Array(vec![value]));
    assert!(deserialize_metadata(&serialize_metadata(Some(&metadata))).is_err());
}