From f5860a07a3a7bfe895d897e2b419ba89a715940b Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Sun, 18 May 2025 11:02:17 -0700 Subject: [PATCH] refactor: TableColumn trait for column access replaces concrete types added in #726, #730 BREAKING CHANGE: requires MSRV bump --- .github/workflows/tests.yml | 2 +- Cargo.toml | 2 +- src/edge_table.rs | 33 ++++++++--- src/lib.rs | 2 +- src/node_table.rs | 16 +++--- src/table_column.rs | 70 +++++------------------ src/traits.rs | 108 ++++++++++++++++++++++++++++++++++++ tests/test_tables.rs | 4 ++ 8 files changed, 162 insertions(+), 75 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9fb803212..2c48ea04b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -83,7 +83,7 @@ jobs: strategy: matrix: rust: - - 1.71.0 + - 1.75.0 steps: - uses: actions/checkout@v4.2.2 - uses: dtolnay/rust-toolchain@v1 diff --git a/Cargo.toml b/Cargo.toml index 099b9640a..a43a771d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ description = "rust interface to tskit" license = "MIT" homepage = "https://github.com/tskit-dev/tskit-rust" repository = "https://github.com/tskit-dev/tskit-rust" -rust-version = "1.71.0" +rust-version = "1.75.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lints.rust] diff --git a/src/edge_table.rs b/src/edge_table.rs index 93aefd92f..917fbec61 100644 --- a/src/edge_table.rs +++ b/src/edge_table.rs @@ -358,20 +358,37 @@ impl EdgeTable { /// Get the child column as a slice of the underlying integer type => child, child_slice_raw, ll_bindings::tsk_id_t); - pub fn parent_column(&self) -> crate::EdgeTableColumn { - crate::EdgeTableColumn::new(self.parent_slice()) + /// Table column with ergonomic indexing. + /// + /// # Examples + /// + /// ```rust + /// use tskit::TableColumn; + /// let mut edges = tskit::EdgeTable::new().unwrap(); + /// // left, right, parent, child + /// let edge: tskit::EdgeId = edges.add_row(0., 10., 1, 0).unwrap(); + /// let p = edges.parent_column(); + /// assert_eq!(p[edge], 1); + /// assert_eq!(p.get_with_id(edge), Some(&tskit::NodeId::from(1))); + /// assert!(p.get_with_id(tskit::EdgeId::NULL).is_none()) + /// ``` + pub fn parent_column(&self) -> impl crate::TableColumn + '_ { + crate::table_column::OpaqueTableColumn(self.parent_slice()) } - pub fn child_column(&self) -> crate::EdgeTableColumn { - crate::EdgeTableColumn::new(self.child_slice()) + /// Table column with ergonomic indexing. + pub fn child_column(&self) -> impl crate::TableColumn + '_ { + crate::table_column::OpaqueTableColumn(self.child_slice()) } - pub fn left_column(&self) -> crate::EdgeTableColumn { - crate::EdgeTableColumn::new(self.left_slice()) + /// Table column with ergonomic indexing. + pub fn left_column(&self) -> impl crate::TableColumn + '_ { + crate::table_column::OpaqueTableColumn(self.left_slice()) } - pub fn right_column(&self) -> crate::EdgeTableColumn { - crate::EdgeTableColumn::new(self.right_slice()) + /// Table column with ergonomic indexing. + pub fn right_column(&self) -> impl crate::TableColumn + '_ { + crate::table_column::OpaqueTableColumn(self.right_slice()) } /// Clear all data from the table diff --git a/src/lib.rs b/src/lib.rs index 1729df519..69f56154f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -117,7 +117,7 @@ pub use site_table::{SiteTable, SiteTableRow}; pub use sys::flags::*; pub use sys::NodeTraversalOrder; pub use table_collection::TableCollection; -pub use table_column::{EdgeTableColumn, NodeTableColumn}; +pub use traits::TableColumn; pub use traits::IndividualLocation; pub use traits::IndividualParents; pub use trees::{Tree, TreeSequence}; diff --git a/src/node_table.rs b/src/node_table.rs index 2462b20d8..0d4bb3667 100644 --- a/src/node_table.rs +++ b/src/node_table.rs @@ -807,20 +807,20 @@ impl NodeTable { /// Get the population column as a slice => population, population_slice_raw, crate::sys::bindings::tsk_id_t); - pub fn individual_column(&self) -> crate::table_column::NodeTableColumn { - crate::NodeTableColumn::new(self.individual_slice()) + pub fn individual_column(&self) -> impl crate::TableColumn + '_ { + crate::table_column::OpaqueTableColumn(self.individual_slice()) } - pub fn population_column(&self) -> crate::NodeTableColumn { - crate::NodeTableColumn::new(self.population_slice()) + pub fn population_column(&self) -> impl crate::TableColumn + '_ { + crate::table_column::OpaqueTableColumn(self.population_slice()) } - pub fn time_column(&self) -> crate::NodeTableColumn