Metadata and tables

Let us create a table and add a row with our mutation metadata:

    let mut tables = tskit::TableCollection::new(50.0).unwrap();

    let md = MutationMetadata {
        effect_size: 1e-3,
        dominance: 1.0,
    };

    let mut_id_0 = tables
        .add_mutation_with_metadata(
            0,    // site id
            0,    // node id
            -1,   // mutation parent id
            0.0,  // time
            None, // derived state is Option<&[u8]>
            &md,  // metadata for this row
        )
        .unwrap();

Meta data is optional on a per-row basis:

    let mut_id_1 = tables
        .add_mutation(
            0,    // site id
            0,    // node id
            -1,   // mutation parent id
            0.0,  // time
            None, // derived state is Option<&[u8]>
        )
        .unwrap();

We can confirm that we have one row with, and one without, metadata:

    assert_eq!(
        tables
            .mutations_iter()
            .filter(|m| m.metadata.is_some())
            .count(),
        1
    );
    assert_eq!(
        tables
            .mutations_iter()
            .filter(|m| m.metadata.is_none())
            .count(),
        1
    );

Fetching our metadata from the table requires specifying the metadata type. The result of a metadata retrieval is Option<Result, TskitError>. The None variant occurs if a row does not have metadata or if a row id does not exist. The error state occurs if decoding raw bytes into the metadata type fails. The details of the error variant are here. The reason why the error type holds Box<dyn Error> is that the API is very general. We assume nothing about the API used to encode/decode metadata. Therefore, the error could be anything.

    let fetched_md = match tables.mutations().metadata::<MutationMetadata>(mut_id_0) {
        Some(Ok(m)) => m,
        Some(Err(e)) => panic!("metadata decoding failed: {:?}", e),
        None => panic!(
            "hmmm...row {} should have been a valid row with metadata...",
            mut_id_0
        ),
    };

    assert_eq!(md.effect_size, fetched_md.effect_size);
    assert_eq!(md.dominance, fetched_md.dominance);
    // There is no metadata at row 1, so
    // you get None back
    assert!(tables
        .mutations()
        .metadata::<MutationMetadata>(mut_id_1)
        .is_none());

    // There is also no metadata at row 2,
    // because that row does not exist, so
    // you get None back
    assert!(tables
        .mutations()
        .metadata::<MutationMetadata>(2.into())
        .is_none());