Skip to content

deref to delegate #409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ serde_json = {version = "1.0.67", optional = true}
bincode = {version = "1.3.1", optional = true}
tskit-derive = {version = "0.2.0", path = "tskit-derive", optional = true}
mbox = "0.6.0"
delegate = "0.8.0"

[dev-dependencies]
anyhow = {version = "1.0.66"}
Expand Down
115 changes: 115 additions & 0 deletions src/_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,121 @@ macro_rules! build_table_column_slice_mut_getter {
};
}

macro_rules! delegate_table_view_api {
() => {
delegate::delegate! {
to self.views {
/// Get reference to the [``EdgeTable``](crate::EdgeTable).
pub fn edges(&self) -> &crate::EdgeTable;
/// Get reference to the [``IndividualTable``](crate::IndividualTable).
pub fn individuals(&self) -> &crate::IndividualTable;
/// Get reference to the [``MigrationTable``](crate::MigrationTable).
pub fn migrations(&self) -> &crate::MigrationTable;
/// Get reference to the [``MutationTable``](crate::MutationTable).
pub fn mutations(&self) -> &crate::MutationTable;
/// Get reference to the [``NodeTable``](crate::NodeTable).
pub fn nodes(&self) -> &crate::NodeTable;
/// Get reference to the [``PopulationTable``](crate::PopulationTable).
pub fn populations(&self) -> &crate::PopulationTable;
/// Get reference to the [``SiteTable``](crate::SiteTable).
pub fn sites(&self) -> &crate::SiteTable;

#[cfg(feature = "provenance")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "provenance")))]
/// Get reference to the [``ProvenanceTable``](crate::provenance::ProvenanceTable)
pub fn provenances(&self) -> &crate::provenance::ProvenanceTable ;

/// Return an iterator over the individuals.
pub fn individuals_iter(&self) -> impl Iterator<Item = crate::IndividualTableRow> + '_;
/// Return an iterator over the nodes.
pub fn nodes_iter(&self) -> impl Iterator<Item = crate::NodeTableRow> + '_;
/// Return an iterator over the edges.
pub fn edges_iter(&self) -> impl Iterator<Item = crate::EdgeTableRow> + '_;
/// Return an iterator over the migrations.
pub fn migrations_iter(&self) -> impl Iterator<Item = crate::MigrationTableRow> + '_;
/// Return an iterator over the mutations.
pub fn mutations_iter(&self) -> impl Iterator<Item = crate::MutationTableRow> + '_;
/// Return an iterator over the populations.
pub fn populations_iter(&self) -> impl Iterator<Item = crate::PopulationTableRow> + '_;
/// Return an iterator over the sites.
pub fn sites_iter(&self) -> impl Iterator<Item = crate::SiteTableRow> + '_;

#[cfg(feature = "provenance")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "provenance")))]
/// Return an iterator over provenances
pub fn provenances_iter(&self,) -> impl Iterator<Item = crate::provenance::ProvenanceTableRow> + '_;

/// Obtain a vector containing the indexes ("ids")
/// of all nodes for which [`crate::TSK_NODE_IS_SAMPLE`]
/// is `true`.
///
/// The provided implementation dispatches to
/// [`crate::NodeTable::samples_as_vector`].
pub fn samples_as_vector(&self) -> Vec<crate::NodeId>;

/// Obtain a vector containing the indexes ("ids") of all nodes
/// satisfying a certain criterion.
///
/// The provided implementation dispatches to
/// [`crate::NodeTable::create_node_id_vector`].
///
/// # Parameters
///
/// * `f`: a function. The function is passed the current table
/// collection and each [`crate::node_table::NodeTableRow`].
/// If `f` returns `true`, the index of that row is included
/// in the return value.
///
/// # Examples
///
/// Get all nodes with time > 0.0:
///
/// ```
/// use tskit::bindings::tsk_id_t;
///
/// let mut tables = tskit::TableCollection::new(100.).unwrap();
/// tables
/// .add_node(tskit::TSK_NODE_IS_SAMPLE, 0.0, tskit::PopulationId::NULL,
/// tskit::IndividualId::NULL)
/// .unwrap();
/// tables
/// .add_node(tskit::TSK_NODE_IS_SAMPLE, 1.0, tskit::PopulationId::NULL,
/// tskit::IndividualId::NULL)
/// .unwrap();
/// let samples = tables.create_node_id_vector(
/// |row: &tskit::NodeTableRow| row.time > 0.,
/// );
/// assert_eq!(samples[0], 1);
///
/// // Get all nodes that have a mutation:
///
/// // fn node_has_mutation(
/// // // dyn trait here means this
/// // // will work with TreeSequence, too.
/// // tables_type: &dyn std::ops::Deref<Target=tskit::table_views::TableViews>,
/// // row: &tskit::NodeTableRow,
/// // ) -> bool {
/// // for mrow in tables_type.mutations_iter() {
/// // if mrow.node == row.id {
/// // return true;
/// // }
/// // }
/// // false
/// // }
///
/// // // Get all nodes that have a mutation:
///
/// // tables.add_mutation(0, 0, tskit::MutationId::NULL, 0.0, None).unwrap();
/// // let samples_with_mut = tables.create_node_id_vector(
/// // |row: &tskit::NodeTableRow| node_has_mutation(&tables, row));
/// // assert_eq!(samples_with_mut[0], 0);
/// ```
pub fn create_node_id_vector(&self, f: impl FnMut(&crate::NodeTableRow) -> bool) -> Vec<crate::NodeId>;
}
}
};
}

#[cfg(test)]
mod test {
use crate::error::TskitError;
Expand Down
31 changes: 14 additions & 17 deletions src/table_collection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ops::{Deref, DerefMut};
use delegate::delegate;
use std::vec;

use crate::bindings as ll_bindings;
Expand Down Expand Up @@ -76,20 +76,6 @@ impl Drop for TableCollection {
}
}

impl Deref for TableCollection {
type Target = crate::table_views::TableViews;

fn deref(&self) -> &Self::Target {
&self.views
}
}

impl DerefMut for TableCollection {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.views
}
}

/// Returns a pointer to an uninitialized tsk_table_collection_t
pub(crate) fn uninit_table_collection() -> MBox<ll_bindings::tsk_table_collection_t> {
let temp = unsafe {
Expand Down Expand Up @@ -797,8 +783,10 @@ impl TableCollection {
idmap: bool,
) -> Result<Option<&[NodeId]>, TskitError> {
if idmap {
self.idmap
.resize(usize::try_from(self.nodes().num_rows())?, NodeId::NULL);
self.idmap.resize(
usize::try_from(self.views.nodes().num_rows())?,
NodeId::NULL,
);
}
let rv = unsafe {
ll_bindings::tsk_table_collection_simplify(
Expand Down Expand Up @@ -1232,4 +1220,13 @@ impl TableCollection {
};
handle_tsk_return_value!(rv)
}

delegate! {
to self.views {
/// Get mutable reference to the [``NodeTable``](crate::NodeTable).
pub fn nodes_mut(&mut self) -> &mut crate::NodeTable;
}
}

delegate_table_view_api!();
}
36 changes: 18 additions & 18 deletions src/table_views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,26 +222,26 @@ impl TableViews {
///
/// // Get all nodes that have a mutation:
///
/// fn node_has_mutation(
/// // dyn trait here means this
/// // will work with TreeSequence, too.
/// tables_type: &dyn std::ops::Deref<Target=tskit::table_views::TableViews>,
/// row: &tskit::NodeTableRow,
/// ) -> bool {
/// for mrow in tables_type.mutations_iter() {
/// if mrow.node == row.id {
/// return true;
/// }
/// }
/// false
/// }
/// // fn node_has_mutation(
/// // // dyn trait here means this
/// // // will work with TreeSequence, too.
/// // tables_type: &dyn std::ops::Deref<Target=tskit::table_views::TableViews>,
/// // row: &tskit::NodeTableRow,
/// // ) -> bool {
/// // for mrow in tables_type.mutations_iter() {
/// // if mrow.node == row.id {
/// // return true;
/// // }
/// // }
/// // false
/// // }
///
/// // Get all nodes that have a mutation:
/// // // Get all nodes that have a mutation:
///
/// tables.add_mutation(0, 0, tskit::MutationId::NULL, 0.0, None).unwrap();
/// let samples_with_mut = tables.create_node_id_vector(
/// |row: &tskit::NodeTableRow| node_has_mutation(&tables, row));
/// assert_eq!(samples_with_mut[0], 0);
/// // tables.add_mutation(0, 0, tskit::MutationId::NULL, 0.0, None).unwrap();
/// // let samples_with_mut = tables.create_node_id_vector(
/// // |row: &tskit::NodeTableRow| node_has_mutation(&tables, row));
/// // assert_eq!(samples_with_mut[0], 0);
/// ```
pub fn create_node_id_vector(
&self,
Expand Down
10 changes: 2 additions & 8 deletions src/trees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,6 @@ impl Drop for TreeSequence {
}
}

impl std::ops::Deref for TreeSequence {
type Target = crate::table_views::TableViews;

fn deref(&self) -> &Self::Target {
&self.views
}
}

impl TreeSequence {
/// Create a tree sequence from a [`TableCollection`].
/// In general, [`TableCollection::tree_sequence`] may be preferred.
Expand Down Expand Up @@ -545,6 +537,8 @@ impl TreeSequence {
};
handle_tsk_return_value!(rv, crate::ProvenanceId::from(rv))
}

delegate_table_view_api!();
}

impl TryFrom<TableCollection> for TreeSequence {
Expand Down