molgfx-core 0.3.4

The semantic scene graph: columnar tables, GPU record layouts, the borrowed coordinate seam.
Documentation
use super::{AttributeColumn, AttributeDescriptor, AttributeKind, AttributeValues};
use crate::{PointBatchHandle, RowDomain, handle::RawHandle};
use std::sync::Arc;

fn domain() -> RowDomain {
    RowDomain::Points(PointBatchHandle(RawHandle::new_for_test(1, 0)))
}

#[test]
fn descriptors_retain_generic_units_and_provenance_in_the_fingerprint() {
    let values = AttributeValues::Scalar(Arc::from([1.0]));
    let plain = AttributeColumn::new(domain(), "score", values.clone()).unwrap();
    let described = AttributeColumn::with_descriptor(
        domain(),
        AttributeDescriptor::new("score")
            .with_quantity("energy", "kcal/mol")
            .with_provenance("caller:method/v1"),
        values,
    )
    .unwrap();
    assert_eq!(described.descriptor().quantity(), Some("energy"));
    assert_eq!(described.descriptor().unit(), Some("kcal/mol"));
    assert_eq!(
        described.descriptor().provenance(),
        Some("caller:method/v1")
    );
    assert_ne!(plain.fingerprint(), described.fingerprint());
}

#[test]
fn every_attribute_keeps_its_native_row_width() {
    let scalar = AttributeColumn::new(
        domain(),
        "score",
        AttributeValues::Scalar(Arc::from([1.0, 2.0])),
    )
    .unwrap();
    let vector = AttributeColumn::new(
        domain(),
        "gradient",
        AttributeValues::Vector(Arc::from([[1.0, 2.0, 3.0]])),
    )
    .unwrap();

    assert_eq!(scalar.kind(), AttributeKind::Scalar);
    assert_eq!(scalar.stride(), 4);
    assert_eq!(scalar.values().as_bytes().len(), 8);
    assert_eq!(vector.stride(), 12);
    assert_eq!(vector.values().as_bytes().len(), 12);
}

#[test]
fn attributes_retain_shared_values_and_validate_missing_vectors() {
    let values: Arc<[f32]> = Arc::from([1.0, f32::NAN]);
    let column = AttributeColumn::new(
        domain(),
        "optional",
        AttributeValues::Scalar(Arc::clone(&values)),
    )
    .unwrap();
    let AttributeValues::Scalar(stored) = column.values() else {
        panic!("expected scalar values");
    };
    assert!(Arc::ptr_eq(stored, &values));
    assert!(
        AttributeColumn::new(
            domain(),
            "bad vector",
            AttributeValues::Vector(Arc::from([[f32::NAN, 0.0, f32::NAN]])),
        )
        .is_err()
    );
}