Skip to content

Commit fafd457

Browse files
authored
Refactor metadata encoding: (#158)
* Add per-table metadata trait marker. * Remove use of Option<metadata> from the API Closes #157
1 parent 258b4ee commit fafd457

File tree

5 files changed

+205
-165
lines changed

5 files changed

+205
-165
lines changed

examples/mutation_metadata_bincode.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ impl metadata::MetadataRoundtrip for Mutation {
2727
}
2828
}
2929

30+
impl metadata::MutationMetadata for Mutation {}
31+
3032
pub fn run() {
3133
let mut tables = tskit::TableCollection::new(1000.).unwrap();
3234
// The simulation generates a mutation:
@@ -38,7 +40,7 @@ pub fn run() {
3840

3941
// The mutation's data are included as metadata:
4042
tables
41-
.add_mutation_with_metadata(0, 0, 0, 0.0, None, Some(&m))
43+
.add_mutation_with_metadata(0, 0, 0, 0.0, None, &m)
4244
.unwrap();
4345

4446
// Decoding requres 2 unwraps:

examples/mutation_metadata_std.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub fn run() {
1818

1919
// The mutation's data are included as metadata:
2020
tables
21-
.add_mutation_with_metadata(0, 0, 0, 0.0, None, Some(&m))
21+
.add_mutation_with_metadata(0, 0, 0, 0.0, None, &m)
2222
.unwrap();
2323

2424
// Decoding requres 2 unwraps:
@@ -63,6 +63,8 @@ impl metadata::MetadataRoundtrip for Mutation {
6363
}
6464
}
6565

66+
impl metadata::MutationMetadata for Mutation {}
67+
6668
#[test]
6769
fn run_test() {
6870
run();

src/metadata.rs

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,16 @@ use thiserror::Error;
3939
/// }
4040
/// }
4141
///
42+
/// impl tskit::metadata::MutationMetadata for MyMutation {}
43+
///
4244
/// let mut tables = tskit::TableCollection::new(100.).unwrap();
4345
/// let mutation = MyMutation{origin_time: 100,
4446
/// effect_size: -1e-4,
4547
/// dominance: 0.25};
4648
///
4749
/// // Add table row with metadata.
4850
/// tables.add_mutation_with_metadata(0, 0, tskit::MutationId::NULL, 100., None,
49-
/// Some(&mutation)).unwrap();
51+
/// &mutation).unwrap();
5052
///
5153
/// // Decode the metadata
5254
/// // The two unwraps are:
@@ -80,33 +82,54 @@ pub trait MetadataRoundtrip {
8082
Self: Sized;
8183
}
8284

85+
/// Marker trait indicating [`MetadataRoundtrip`]
86+
/// for the mutation table of a [`TableCollection`](crate::TableCollection).
87+
pub trait MutationMetadata: MetadataRoundtrip {}
88+
89+
/// Marker trait indicating [`MetadataRoundtrip`]
90+
/// for the node table of a [`TableCollection`](crate::TableCollection).
91+
pub trait NodeMetadata: MetadataRoundtrip {}
92+
93+
/// Marker trait indicating [`MetadataRoundtrip`]
94+
/// for the edge table of a [`TableCollection`](crate::TableCollection).
95+
pub trait EdgeMetadata: MetadataRoundtrip {}
96+
///
97+
/// Marker trait indicating [`MetadataRoundtrip`]
98+
/// for the migratoin table of a [`TableCollection`](crate::TableCollection).
99+
pub trait MigrationMetadata: MetadataRoundtrip {}
100+
101+
/// Marker trait indicating [`MetadataRoundtrip`]
102+
/// for the site table of a [`TableCollection`](crate::TableCollection).
103+
pub trait SiteMetadata: MetadataRoundtrip {}
104+
105+
/// Marker trait indicating [`MetadataRoundtrip`]
106+
/// for the individual table of a [`TableCollection`](crate::TableCollection).
107+
pub trait IndividualMetadata: MetadataRoundtrip {}
108+
109+
/// Marker trait indicating [`MetadataRoundtrip`]
110+
/// for the population table of a [`TableCollection`](crate::TableCollection).
111+
pub trait PopulationMetadata: MetadataRoundtrip {}
112+
83113
pub(crate) struct EncodedMetadata {
84-
encoded: Option<Vec<u8>>,
114+
encoded: Vec<u8>,
85115
}
86116

87117
impl EncodedMetadata {
88-
pub(crate) fn new(md: Option<&dyn MetadataRoundtrip>) -> Result<Self, MetadataError> {
89-
match md {
90-
Some(x) => {
91-
let e = x.encode()?;
92-
Ok(Self { encoded: Some(e) })
93-
}
94-
None => Ok(Self { encoded: None }),
95-
}
118+
pub(crate) fn new<M: MetadataRoundtrip + ?Sized>(md: &M) -> Result<Self, MetadataError> {
119+
let encoded = md.encode()?;
120+
Ok(Self { encoded })
96121
}
97122

98123
pub(crate) fn as_ptr(&self) -> *const libc::c_char {
99-
match &self.encoded {
100-
Some(x) => x.as_ptr() as *const libc::c_char,
101-
None => std::ptr::null(),
124+
if self.encoded.is_empty() {
125+
std::ptr::null()
126+
} else {
127+
self.encoded.as_ptr() as *const libc::c_char
102128
}
103129
}
104130

105131
pub(crate) fn len(&self) -> tsk_size_t {
106-
match &self.encoded {
107-
Some(x) => x.len() as tsk_size_t,
108-
None => 0,
109-
}
132+
self.encoded.len() as tsk_size_t
110133
}
111134
}
112135

@@ -194,6 +217,8 @@ mod tests {
194217
}
195218
}
196219

220+
impl MutationMetadata for F {}
221+
197222
#[test]
198223
fn test_metadata_round_trip() {
199224
let f = F { x: -3, y: 42 };
@@ -211,7 +236,7 @@ mod tests {
211236
#[test]
212237
fn test_encoded_metadata_roundtrip() {
213238
let f = F { x: -3, y: 42 };
214-
let enc = EncodedMetadata::new(Some(&f)).unwrap();
239+
let enc = EncodedMetadata::new(&f).unwrap();
215240
let p = enc.as_ptr();
216241
let mut d = vec![];
217242
for i in 0..enc.len() {
@@ -245,7 +270,7 @@ mod test_serde {
245270
#[test]
246271
fn test_encoded_metadata_roundtrip() {
247272
let f = F { x: -3, y: 42 };
248-
let enc = EncodedMetadata::new(Some(&f)).unwrap();
273+
let enc = EncodedMetadata::new(&f).unwrap();
249274
let p = enc.as_ptr();
250275
let mut d = vec![];
251276
for i in 0..enc.len() {

0 commit comments

Comments
 (0)