@@ -14,67 +14,73 @@ use thiserror::Error;
14
14
/// [bincode](https://crates.io/crates/bincode) will be one of
15
15
/// the more useful `serde`-related crates.
16
16
///
17
- /// # Examples
17
+ /// The library provides two macros to facilitate implementing metadata
18
+ /// traits:
18
19
///
19
- /// ## Mutation metadata
20
+ /// * [`serde_json_metadata`]
21
+ /// * [`serde_bincode_metadata`]
20
22
///
21
- /// ```
22
- /// use tskit::handle_metadata_return;
23
- /// use tskit::TableAccess;
23
+ /// These macros are optional features.
24
+ /// The feature names are the same as the macro names
24
25
///
25
- /// #[derive(serde::Serialize, serde::Deserialize)]
26
- /// pub struct MyMutation {
27
- /// origin_time: i32,
28
- /// effect_size: f64,
29
- /// dominance: f64,
30
- /// }
31
- ///
32
- /// impl tskit::metadata::MetadataRoundtrip for MyMutation {
33
- /// fn encode(&self) -> Result<Vec<u8>, tskit::metadata::MetadataError> {
34
- /// handle_metadata_return!(bincode::serialize(&self))
35
- /// }
36
- ///
37
- /// fn decode(md: &[u8]) -> Result<Self, tskit::metadata::MetadataError> {
38
- /// handle_metadata_return!(bincode::deserialize(md))
39
- /// }
40
- /// }
41
- ///
42
- /// impl tskit::metadata::MutationMetadata for MyMutation {}
43
- ///
44
- /// let mut tables = tskit::TableCollection::new(100.).unwrap();
45
- /// let mutation = MyMutation{origin_time: 100,
46
- /// effect_size: -1e-4,
47
- /// dominance: 0.25};
48
- ///
49
- /// // Add table row with metadata.
50
- /// tables.add_mutation_with_metadata(0, 0, tskit::MutationId::NULL, 100., None,
51
- /// &mutation).unwrap();
52
- ///
53
- /// // Decode the metadata
54
- /// // The two unwraps are:
55
- /// // 1. Handle Errors vs Option.
56
- /// // 2. Handle the option for the case of no error.
57
- /// //
58
- /// // The .into() reflects the fact that metadata fetching
59
- /// // functions only take a strong ID type, and tskit-rust
60
- /// // adds Into<strong ID type> for i32 for all strong ID types.
61
- ///
62
- /// let decoded = tables.mutations().metadata::<MyMutation>(0.into()).unwrap().unwrap();
63
- /// assert_eq!(mutation.origin_time, decoded.origin_time);
64
- /// match decoded.effect_size.partial_cmp(&mutation.effect_size) {
65
- /// Some(std::cmp::Ordering::Greater) => assert!(false),
66
- /// Some(std::cmp::Ordering::Less) => assert!(false),
67
- /// Some(std::cmp::Ordering::Equal) => (),
68
- /// None => panic!("bad comparison"),
69
- /// };
70
- /// match decoded.dominance.partial_cmp(&mutation.dominance) {
71
- /// Some(std::cmp::Ordering::Greater) => assert!(false),
72
- /// Some(std::cmp::Ordering::Less) => assert!(false),
73
- /// Some(std::cmp::Ordering::Equal) => (),
74
- /// None => panic!("bad comparison"),
75
- /// };
76
- ///
77
- /// ```
26
+ #[ cfg_attr(
27
+ feature = "provenance" ,
28
+ doc = r##"
29
+ # Examples
30
+
31
+ ## Mutation metadata encoded as JSON
32
+
33
+ ```
34
+ use tskit::handle_metadata_return;
35
+ use tskit::TableAccess;
36
+
37
+ #[derive(serde::Serialize, serde::Deserialize)]
38
+ pub struct MyMutation {
39
+ origin_time: i32,
40
+ effect_size: f64,
41
+ dominance: f64,
42
+ }
43
+
44
+ // Implement tskit::metadata::MetadataRoundtrip
45
+ tskit::serde_json_metadata!(MyMutation);
46
+
47
+ impl tskit::metadata::MutationMetadata for MyMutation {}
48
+
49
+ let mut tables = tskit::TableCollection::new(100.).unwrap();
50
+ let mutation = MyMutation{origin_time: 100,
51
+ effect_size: -1e-4,
52
+ dominance: 0.25};
53
+
54
+ // Add table row with metadata.
55
+ tables.add_mutation_with_metadata(0, 0, tskit::MutationId::NULL, 100., None,
56
+ &mutation).unwrap();
57
+
58
+ // Decode the metadata
59
+ // The two unwraps are:
60
+ // 1. Handle Errors vs Option.
61
+ // 2. Handle the option for the case of no error.
62
+ //
63
+ // The .into() reflects the fact that metadata fetching
64
+ // functions only take a strong ID type, and tskit-rust
65
+ // adds Into<strong ID type> for i32 for all strong ID types.
66
+
67
+ let decoded = tables.mutations().metadata::<MyMutation>(0.into()).unwrap().unwrap();
68
+ assert_eq!(mutation.origin_time, decoded.origin_time);
69
+ match decoded.effect_size.partial_cmp(&mutation.effect_size) {
70
+ Some(std::cmp::Ordering::Greater) => assert!(false),
71
+ Some(std::cmp::Ordering::Less) => assert!(false),
72
+ Some(std::cmp::Ordering::Equal) => (),
73
+ None => panic!("bad comparison"),
74
+ };
75
+ match decoded.dominance.partial_cmp(&mutation.dominance) {
76
+ Some(std::cmp::Ordering::Greater) => assert!(false),
77
+ Some(std::cmp::Ordering::Less) => assert!(false),
78
+ Some(std::cmp::Ordering::Equal) => (),
79
+ None => panic!("bad comparison"),
80
+ };
81
+ ```
82
+ "##
83
+ ) ]
78
84
pub trait MetadataRoundtrip {
79
85
fn encode ( & self ) -> Result < Vec < u8 > , MetadataError > ;
80
86
fn decode ( md : & [ u8 ] ) -> Result < Self , MetadataError >
0 commit comments