Skip to content

Commit c62ccd2

Browse files
authored
Add TableAccess trait and implement for TableCollection and TreeSequence. (#66)
1 parent 1672094 commit c62ccd2

File tree

4 files changed

+186
-124
lines changed

4 files changed

+186
-124
lines changed

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ mod population_table;
1919
mod site_table;
2020
mod table_collection;
2121
mod table_iterator;
22+
mod traits;
2223
mod trees;
2324
pub mod types;
2425
mod util;
@@ -49,6 +50,7 @@ pub use node_table::{NodeTable, NodeTableRow};
4950
pub use population_table::{PopulationTable, PopulationTableRow};
5051
pub use site_table::{SiteTable, SiteTableRow};
5152
pub use table_collection::TableCollection;
53+
pub use traits::TableAccess;
5254
pub use trees::{NodeIterator, NodeTraversalOrder, Tree, TreeFlags, TreeSequence};
5355

5456
/// Handles return codes from low-level tskit functions.

src/table_collection.rs

Lines changed: 33 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::MutationTable;
1010
use crate::NodeTable;
1111
use crate::PopulationTable;
1212
use crate::SiteTable;
13+
use crate::TableAccess;
1314
use crate::TskReturnValue;
1415
use crate::{tsk_flags_t, tsk_id_t, tsk_size_t};
1516
use ll_bindings::tsk_table_collection_free;
@@ -23,6 +24,7 @@ use ll_bindings::tsk_table_collection_free;
2324
/// # Examples
2425
///
2526
/// ```
27+
/// use tskit::TableAccess;
2628
/// let mut tables = tskit::TableCollection::new(100.).unwrap();
2729
/// assert_eq!(tables.sequence_length(), 100.);
2830
///
@@ -47,6 +49,7 @@ use ll_bindings::tsk_table_collection_free;
4749
///
4850
/// ```
4951
/// use tskit;
52+
/// use tskit::TableAccess;
5053
/// use tskit::metadata::MetadataRoundtrip;
5154
///
5255
/// // Define a type for metadata
@@ -156,130 +159,6 @@ impl TableCollection {
156159
unsafe { (*self.as_ptr()).sequence_length }
157160
}
158161

159-
/// Get reference to the [``EdgeTable``](crate::EdgeTable).
160-
/// Lifetime of return value is tied to (this)
161-
/// parent object.
162-
pub fn edges<'a>(&'a self) -> EdgeTable<'a> {
163-
EdgeTable::<'a>::new_from_table(&self.inner.edges)
164-
}
165-
166-
/// Return an iterator over the edges.
167-
/// See [`EdgeTable::iter`] for details.
168-
pub fn edges_iter<'a>(
169-
&'a self,
170-
decode_metadata: bool,
171-
) -> crate::edge_table::EdgeTableIterator<'a> {
172-
crate::table_iterator::make_table_iterator::<EdgeTable<'a>>(self.edges(), decode_metadata)
173-
}
174-
175-
/// Get reference to the [``IndividualTable``](crate::IndividualTable).
176-
/// Lifetime of return value is tied to (this)
177-
/// parent object.
178-
pub fn individuals<'a>(&'a self) -> IndividualTable<'a> {
179-
IndividualTable::<'a>::new_from_table(&self.inner.individuals)
180-
}
181-
182-
/// Return an iterator over the individuals.
183-
/// See [`IndividualTable::iter`] for details.
184-
pub fn individuals_iter<'a>(
185-
&'a self,
186-
decode_metadata: bool,
187-
) -> crate::individual_table::IndividualTableIterator<'a> {
188-
crate::table_iterator::make_table_iterator::<IndividualTable<'a>>(
189-
self.individuals(),
190-
decode_metadata,
191-
)
192-
}
193-
194-
/// Get reference to the [``MigrationTable``](crate::MigrationTable).
195-
/// Lifetime of return value is tied to (this)
196-
/// parent object.
197-
pub fn migrations<'a>(&'a self) -> MigrationTable<'a> {
198-
MigrationTable::<'a>::new_from_table(&self.inner.migrations)
199-
}
200-
201-
/// Return an iterator over the migration events.
202-
/// See [`MigrationTable::iter`] for details.
203-
pub fn migrations_iter<'a>(
204-
&'a self,
205-
decode_metadata: bool,
206-
) -> crate::migration_table::MigrationTableIterator<'a> {
207-
crate::table_iterator::make_table_iterator::<MigrationTable<'a>>(
208-
self.migrations(),
209-
decode_metadata,
210-
)
211-
}
212-
213-
/// Get reference to the [``NodeTable``](crate::NodeTable).
214-
/// Lifetime of return value is tied to (this)
215-
/// parent object.
216-
pub fn nodes<'a>(&'a self) -> NodeTable<'a> {
217-
NodeTable::<'a>::new_from_table(&self.inner.nodes)
218-
}
219-
220-
/// Return an iterator over the nodes.
221-
/// See [`NodeTable::iter`] for details.
222-
pub fn nodes_iter<'a>(
223-
&'a self,
224-
decode_metadata: bool,
225-
) -> crate::node_table::NodeTableIterator<'a> {
226-
crate::table_iterator::make_table_iterator::<NodeTable<'a>>(self.nodes(), decode_metadata)
227-
}
228-
229-
/// Get reference to the [``SiteTable``](crate::SiteTable).
230-
/// Lifetime of return value is tied to (this)
231-
/// parent object.
232-
pub fn sites<'a>(&'a self) -> SiteTable<'a> {
233-
SiteTable::<'a>::new_from_table(&self.inner.sites)
234-
}
235-
236-
/// Return an iterator over the sites.
237-
/// See [`SiteTable::iter`] for details.
238-
pub fn sites_iter<'a>(
239-
&'a self,
240-
decode_metadata: bool,
241-
) -> crate::site_table::SiteTableIterator<'a> {
242-
crate::table_iterator::make_table_iterator::<SiteTable<'a>>(self.sites(), decode_metadata)
243-
}
244-
245-
/// Get reference to the [``MutationTable``](crate::MutationTable).
246-
/// Lifetime of return value is tied to (this)
247-
/// parent object.
248-
pub fn mutations<'a>(&'a self) -> MutationTable<'a> {
249-
MutationTable::<'a>::new_from_table(&self.inner.mutations)
250-
}
251-
252-
/// Return an iterator over the mutations.
253-
/// See [`MutationTable::iter`] for details.
254-
pub fn mutations_iter<'a>(
255-
&'a self,
256-
decode_metadata: bool,
257-
) -> crate::mutation_table::MutationTableIterator<'a> {
258-
crate::table_iterator::make_table_iterator::<MutationTable<'a>>(
259-
self.mutations(),
260-
decode_metadata,
261-
)
262-
}
263-
264-
/// Get reference to the [``PopulationTable``](crate::PopulationTable).
265-
/// Lifetime of return value is tied to (this)
266-
/// parent object.
267-
pub fn populations<'a>(&'a self) -> PopulationTable<'a> {
268-
PopulationTable::<'a>::new_from_table(&self.inner.populations)
269-
}
270-
271-
/// Return an iterator over the populations.
272-
/// See [`PopulationTable::iter`] for details.
273-
pub fn populations_iter<'a>(
274-
&'a self,
275-
decode_metadata: bool,
276-
) -> crate::population_table::PopulationTableIterator<'a> {
277-
crate::table_iterator::make_table_iterator::<PopulationTable<'a>>(
278-
self.populations(),
279-
decode_metadata,
280-
)
281-
}
282-
283162
/// Add a row to the edge table
284163
pub fn add_edge(
285164
&mut self,
@@ -610,6 +489,36 @@ impl TableCollection {
610489
}
611490
}
612491

492+
impl TableAccess for TableCollection {
493+
fn edges(&self) -> EdgeTable {
494+
EdgeTable::new_from_table(&self.inner.edges)
495+
}
496+
497+
fn individuals(&self) -> IndividualTable {
498+
IndividualTable::new_from_table(&self.inner.individuals)
499+
}
500+
501+
fn migrations(&self) -> MigrationTable {
502+
MigrationTable::new_from_table(&self.inner.migrations)
503+
}
504+
505+
fn nodes(&self) -> NodeTable {
506+
NodeTable::new_from_table(&self.inner.nodes)
507+
}
508+
509+
fn sites(&self) -> SiteTable {
510+
SiteTable::new_from_table(&self.inner.sites)
511+
}
512+
513+
fn mutations(&self) -> MutationTable {
514+
MutationTable::new_from_table(&self.inner.mutations)
515+
}
516+
517+
fn populations(&self) -> PopulationTable {
518+
PopulationTable::new_from_table(&self.inner.populations)
519+
}
520+
}
521+
613522
#[cfg(test)]
614523
mod test {
615524
use super::*;

src/traits.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//! Traits related to user-facing types
2+
3+
use crate::edge_table::EdgeTableIterator;
4+
use crate::individual_table::IndividualTableIterator;
5+
use crate::migration_table::MigrationTableIterator;
6+
use crate::mutation_table::MutationTableIterator;
7+
use crate::node_table::NodeTableIterator;
8+
use crate::population_table::PopulationTableIterator;
9+
use crate::site_table::SiteTableIterator;
10+
use crate::table_iterator::make_table_iterator;
11+
use crate::EdgeTable;
12+
use crate::IndividualTable;
13+
use crate::MigrationTable;
14+
use crate::MutationTable;
15+
use crate::NodeTable;
16+
use crate::PopulationTable;
17+
use crate::SiteTable;
18+
19+
/// Immutable access to tables.
20+
///
21+
/// For objects that contain the full suite of tables,
22+
/// implementing this trait provides immutable access
23+
/// to their data.
24+
///
25+
/// For most types, the provided implementations of `_iter`
26+
/// methods should do.
27+
///
28+
/// # Examples
29+
///
30+
/// ```
31+
/// use tskit::TableAccess;
32+
///
33+
/// let mut tables = tskit::TableCollection::new(1.).unwrap();
34+
/// // The borrows are immuatble, so we can
35+
/// // take multiple table references from the same object.
36+
/// let e = tables.edges();
37+
/// let n = tables.nodes();
38+
/// ```
39+
///
40+
/// The borrow checker will keep you from getting in trouble:
41+
///
42+
/// ```compile_fail
43+
/// use tskit::TableAccess;
44+
///
45+
/// let mut tables = tskit::TableCollection::new(1.).unwrap();
46+
/// let e = tables.edges();
47+
/// tables.add_edge(0.0, 1.0, 0, 1).unwrap();
48+
/// let p = e.parent(0).unwrap(); // FAIL!
49+
/// ```
50+
pub trait TableAccess {
51+
/// Get reference to the [``EdgeTable``](crate::EdgeTable).
52+
fn edges(&self) -> EdgeTable;
53+
54+
/// Return an iterator over the edges.
55+
/// See [`EdgeTable::iter`] for details.
56+
fn edges_iter(&self, decode_metadata: bool) -> EdgeTableIterator {
57+
make_table_iterator::<EdgeTable>(self.edges(), decode_metadata)
58+
}
59+
60+
/// Get reference to the [``NodeTable``](crate::NodeTable).
61+
fn nodes(&self) -> NodeTable;
62+
63+
/// Return an iterator over the nodes.
64+
/// See [`NodeTable::iter`] for details.
65+
fn nodes_iter(&self, decode_metadata: bool) -> NodeTableIterator {
66+
make_table_iterator::<NodeTable>(self.nodes(), decode_metadata)
67+
}
68+
69+
/// Get reference to the [``MutationTable``](crate::MutationTable).
70+
fn mutations(&self) -> MutationTable;
71+
72+
/// Return an iterator over the mutations.
73+
/// See [`MutationTable::iter`] for details.
74+
fn mutations_iter(&self, decode_metadata: bool) -> MutationTableIterator {
75+
make_table_iterator::<MutationTable>(self.mutations(), decode_metadata)
76+
}
77+
78+
/// Get reference to the [``SiteTable``](crate::SiteTable).
79+
fn sites(&self) -> SiteTable;
80+
81+
/// Return an iterator over the sites.
82+
/// See [`SiteTable::iter`] for details.
83+
fn sites_iter(&self, decode_metadata: bool) -> SiteTableIterator {
84+
make_table_iterator::<SiteTable>(self.sites(), decode_metadata)
85+
}
86+
87+
/// Get reference to the [``PopulationTable``](crate::PopulationTable).
88+
fn populations(&self) -> PopulationTable;
89+
90+
/// Return an iterator over the populations.
91+
/// See [`PopulationTable::iter`] for details.
92+
fn populations_iter(&self, decode_metadata: bool) -> PopulationTableIterator {
93+
make_table_iterator::<PopulationTable>(self.populations(), decode_metadata)
94+
}
95+
96+
/// Get reference to the [``MigrationTable``](crate::MigrationTable).
97+
fn migrations(&self) -> MigrationTable;
98+
99+
/// Return an iterator over the migration events.
100+
/// See [`MigrationTable::iter`] for details.
101+
fn migrations_iter(&self, decode_metadata: bool) -> MigrationTableIterator {
102+
make_table_iterator::<MigrationTable>(self.migrations(), decode_metadata)
103+
}
104+
105+
/// Get reference to the [``IndividualTable``](crate::IndividualTable).
106+
fn individuals(&self) -> IndividualTable;
107+
108+
/// Return an iterator over the individuals.
109+
/// See [`IndividualTable::iter`] for details.
110+
fn individuals_iter(&self, decode_metadata: bool) -> IndividualTableIterator {
111+
make_table_iterator::<IndividualTable>(self.individuals(), decode_metadata)
112+
}
113+
}

src/trees.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
use crate::bindings as ll_bindings;
22
use crate::error::TskitError;
33
use crate::ffi::{TskitTypeAccess, WrapTskitType};
4+
use crate::EdgeTable;
5+
use crate::IndividualTable;
6+
use crate::MigrationTable;
7+
use crate::MutationTable;
8+
use crate::NodeTable;
9+
use crate::PopulationTable;
10+
use crate::SiteTable;
11+
use crate::TableAccess;
412
use crate::{tsk_flags_t, tsk_id_t, tsk_size_t, TableCollection, TSK_NULL};
513
use bitflags::bitflags;
614
use ll_bindings::{tsk_tree_free, tsk_treeseq_free};
@@ -825,6 +833,36 @@ impl TreeSequence {
825833
}
826834
}
827835

836+
impl TableAccess for TreeSequence {
837+
fn edges(&self) -> EdgeTable {
838+
EdgeTable::new_from_table(unsafe { &(*self.inner.tables).edges })
839+
}
840+
841+
fn individuals(&self) -> IndividualTable {
842+
IndividualTable::new_from_table(unsafe { &(*self.inner.tables).individuals })
843+
}
844+
845+
fn migrations(&self) -> MigrationTable {
846+
MigrationTable::new_from_table(unsafe { &(*self.inner.tables).migrations })
847+
}
848+
849+
fn nodes(&self) -> NodeTable {
850+
NodeTable::new_from_table(unsafe { &(*self.inner.tables).nodes })
851+
}
852+
853+
fn sites(&self) -> SiteTable {
854+
SiteTable::new_from_table(unsafe { &(*self.inner.tables).sites })
855+
}
856+
857+
fn mutations(&self) -> MutationTable {
858+
MutationTable::new_from_table(unsafe { &(*self.inner.tables).mutations })
859+
}
860+
861+
fn populations(&self) -> PopulationTable {
862+
PopulationTable::new_from_table(unsafe { &(*self.inner.tables).populations })
863+
}
864+
}
865+
828866
#[cfg(test)]
829867
mod test_trees {
830868
use super::*;

0 commit comments

Comments
 (0)