#![cfg(feature = "derive")]
mod experimental_features {
trait MetadataRetrieval<R> {
type Metadata: tskit::metadata::MetadataRoundtrip;
fn metadata(&self, r: impl Into<R>) -> Option<Result<Self::Metadata, tskit::TskitError>>;
}
trait MutationMetadataRetrieval: MetadataRetrieval<tskit::MutationId> {
fn mutation_metadata(
&self,
row: impl Into<tskit::MutationId>,
) -> Option<
Result<<Self as MetadataRetrieval<tskit::MutationId>>::Metadata, tskit::TskitError>,
>
where
<Self as MetadataRetrieval<tskit::MutationId>>::Metadata:
tskit::metadata::MutationMetadata;
}
impl<T> MutationMetadataRetrieval for T
where
T: MetadataRetrieval<tskit::MutationId>,
<Self as MetadataRetrieval<tskit::MutationId>>::Metadata: tskit::metadata::MutationMetadata,
{
fn mutation_metadata(
&self,
row: impl Into<tskit::MutationId>,
) -> Option<
Result<<Self as MetadataRetrieval<tskit::MutationId>>::Metadata, tskit::TskitError>,
> {
self.metadata(row)
}
}
#[allow(dead_code)]
trait IndividualMetadataRetrieval: MetadataRetrieval<tskit::IndividualId> {
fn individual_metadata(
&self,
row: impl Into<tskit::IndividualId>,
) -> Option<
Result<<Self as MetadataRetrieval<tskit::IndividualId>>::Metadata, tskit::TskitError>,
>
where
<Self as MetadataRetrieval<tskit::IndividualId>>::Metadata:
tskit::metadata::MutationMetadata;
}
impl<T> IndividualMetadataRetrieval for T
where
T: MetadataRetrieval<tskit::IndividualId>,
<Self as MetadataRetrieval<tskit::IndividualId>>::Metadata:
tskit::metadata::IndividualMetadata,
{
fn individual_metadata(
&self,
row: impl Into<tskit::IndividualId>,
) -> Option<
Result<<Self as MetadataRetrieval<tskit::IndividualId>>::Metadata, tskit::TskitError>,
> {
self.metadata(row)
}
}
trait MutationMetadataExtraction {
type Item: tskit::metadata::MutationMetadata;
fn get_mutation_metadata<M: Into<tskit::MutationId>>(
&self,
row: M,
) -> Option<Result<Self::Item, tskit::TskitError>>;
}
#[derive(serde::Serialize, serde::Deserialize, tskit::metadata::MutationMetadata)]
#[serializer("serde_json")]
struct MutationMetadataType {
effect_size: f64,
}
#[derive(serde::Serialize, serde::Deserialize, tskit::metadata::IndividualMetadata)]
#[serializer("serde_json")]
struct IndividualMetadataType {
fitness: f64,
location: [f64; 3],
}
struct MyTableCollection(tskit::TableCollection);
impl std::ops::Deref for MyTableCollection {
type Target = tskit::TableCollection;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::ops::DerefMut for MyTableCollection {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl MutationMetadataExtraction for MyTableCollection {
type Item = MutationMetadataType;
fn get_mutation_metadata<M: Into<tskit::MutationId>>(
&self,
row: M,
) -> Option<Result<Self::Item, tskit::TskitError>> {
self.mutations().metadata::<Self::Item>(row.into())
}
}
impl MetadataRetrieval<tskit::MutationId> for MyTableCollection {
type Metadata = MutationMetadataType;
fn metadata(
&self,
row: impl Into<tskit::MutationId>,
) -> Option<Result<MutationMetadataType, tskit::TskitError>> {
self.mutations()
.metadata::<MutationMetadataType>(row.into())
}
}
impl MetadataRetrieval<tskit::IndividualId> for MyTableCollection {
type Metadata = IndividualMetadataType;
fn metadata(
&self,
row: impl Into<tskit::IndividualId>,
) -> Option<Result<IndividualMetadataType, tskit::TskitError>> {
self.individuals()
.metadata::<IndividualMetadataType>(row.into())
}
}
#[test]
fn test_table_collection_newtype() {
let mut tables = MyTableCollection(tskit::TableCollection::new(1.0).unwrap());
let md = MutationMetadataType { effect_size: 0.1 };
tables
.add_mutation_with_metadata(0, 0, 0, 0.0, None, &md)
.unwrap();
let decoded = tables.get_mutation_metadata(0).unwrap().unwrap();
assert_eq!(decoded.effect_size, 0.10);
let decoded =
<MyTableCollection as MetadataRetrieval<tskit::MutationId>>::metadata(&tables, 0)
.unwrap()
.unwrap();
assert_eq!(decoded.effect_size, 0.10);
let decoded = tables.mutation_metadata(0).unwrap().unwrap();
assert_eq!(decoded.effect_size, 0.10);
let decoded = tables
.mutations()
.metadata::<MutationMetadataType>(0)
.unwrap()
.unwrap();
assert_eq!(decoded.effect_size, 0.10);
}
}
mod experimental_features_refined {
trait AsTableCollection {
fn as_tables(&self) -> &tskit::TableCollection;
}
trait MutationMetadataExtraction: AsTableCollection {
type Item: tskit::metadata::MutationMetadata;
fn get_mutation_metadata<M: Into<tskit::MutationId>>(
&self,
row: M,
) -> Option<Result<Self::Item, tskit::TskitError>> {
self.as_tables()
.mutations()
.metadata::<Self::Item>(row.into())
}
}
#[derive(serde::Serialize, serde::Deserialize, tskit::metadata::MutationMetadata)]
#[serializer("serde_json")]
struct MutationMetadataType {
effect_size: f64,
}
struct MyTableCollection(tskit::TableCollection);
impl AsTableCollection for MyTableCollection {
fn as_tables(&self) -> &tskit::TableCollection {
&self.0
}
}
impl MutationMetadataExtraction for MyTableCollection {
type Item = MutationMetadataType;
}
#[test]
fn test_table_collection_newtype() {
let mut tables = MyTableCollection(tskit::TableCollection::new(1.0).unwrap());
let md = MutationMetadataType { effect_size: 0.1 };
tables
.0
.add_mutation_with_metadata(0, 0, 0, 0.0, None, &md)
.unwrap();
let decoded = tables.get_mutation_metadata(0).unwrap().unwrap();
assert_eq!(decoded.effect_size, 0.10);
let decoded = tables
.0
.mutations()
.metadata::<MutationMetadataType>(0)
.unwrap()
.unwrap();
assert_eq!(decoded.effect_size, 0.10);
}
}