Skip to content
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
21 changes: 14 additions & 7 deletions src/_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,20 @@ macro_rules! handle_metadata_return {
macro_rules! raw_metadata_getter_for_tables {
($idtype: ty) => {
fn raw_metadata<I: Into<$idtype>>(&self, row: I) -> Option<&[u8]> {
$crate::sys::tsk_ragged_column_access::<'_, u8, $idtype, _, _>(
row.into(),
self.as_ref().metadata,
self.num_rows(),
self.as_ref().metadata_offset,
self.as_ref().metadata_length,
)
assert!(
(self.num_rows() == 0 && self.as_ref().metadata_length == 0)
|| (!self.as_ref().metadata.is_null()
&& !self.as_ref().metadata_offset.is_null())
);
unsafe {
$crate::sys::tsk_ragged_column_access::<'_, u8, $idtype, _, _>(
row.into(),
self.as_ref().metadata,
self.num_rows(),
self.as_ref().metadata_offset,
self.as_ref().metadata_length,
)
}
}
};
}
Expand Down
44 changes: 36 additions & 8 deletions src/edge_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,15 @@ impl EdgeTable {
/// * `Some(parent)` if `u` is valid.
/// * `None` otherwise.
pub fn parent<E: Into<EdgeId> + Copy>(&self, row: E) -> Option<NodeId> {
sys::tsk_column_access::<NodeId, _, _, _>(row.into(), self.as_ref().parent, self.num_rows())
assert!(self.num_rows() == 0 || !self.as_ref().parent.is_null());
// SAFETY: either the column is empty or the point is not NULL
unsafe {
sys::tsk_column_access::<NodeId, _, _, _>(
row.into(),
self.as_ref().parent,
self.num_rows(),
)
}
}

/// Return the ``child`` value from row ``row`` of the table.
Expand All @@ -233,7 +241,15 @@ impl EdgeTable {
/// * `Some(child)` if `u` is valid.
/// * `None` otherwise.
pub fn child<E: Into<EdgeId> + Copy>(&self, row: E) -> Option<NodeId> {
sys::tsk_column_access::<NodeId, _, _, _>(row.into(), self.as_ref().child, self.num_rows())
assert!(self.num_rows() == 0 || !self.as_ref().child.is_null());
// SAFETY: either the column is empty or the point is not NULL
unsafe {
sys::tsk_column_access::<NodeId, _, _, _>(
row.into(),
self.as_ref().child,
self.num_rows(),
)
}
}

/// Return the ``left`` value from row ``row`` of the table.
Expand All @@ -243,7 +259,15 @@ impl EdgeTable {
/// * `Some(position)` if `u` is valid.
/// * `None` otherwise.
pub fn left<E: Into<EdgeId> + Copy>(&self, row: E) -> Option<Position> {
sys::tsk_column_access::<Position, _, _, _>(row.into(), self.as_ref().left, self.num_rows())
assert!(self.num_rows() == 0 || !self.as_ref().left.is_null());
// SAFETY: either the column is empty or the point is not NULL
unsafe {
sys::tsk_column_access::<Position, _, _, _>(
row.into(),
self.as_ref().left,
self.num_rows(),
)
}
}

/// Return the ``right`` value from row ``row`` of the table.
Expand All @@ -253,11 +277,15 @@ impl EdgeTable {
/// * `Some(position)` if `u` is valid.
/// * `None` otherwise.
pub fn right<E: Into<EdgeId> + Copy>(&self, row: E) -> Option<Position> {
sys::tsk_column_access::<Position, _, _, _>(
row.into(),
self.as_ref().right,
self.num_rows(),
)
assert!(self.num_rows() == 0 || !self.as_ref().right.is_null());
// SAFETY: either the column is empty or the point is not NULL
unsafe {
sys::tsk_column_access::<Position, _, _, _>(
row.into(),
self.as_ref().right,
self.num_rows(),
)
}
}

/// Retrieve decoded metadata for a `row`.
Expand Down
54 changes: 35 additions & 19 deletions src/individual_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,15 @@ impl IndividualTable {
/// * `Some(flags)` if `row` is valid.
/// * `None` otherwise.
pub fn flags<I: Into<IndividualId> + Copy>(&self, row: I) -> Option<IndividualFlags> {
sys::tsk_column_access::<IndividualFlags, _, _, _>(
row.into(),
self.as_ref().flags,
self.num_rows(),
)
assert!(self.num_rows() == 0 || !self.as_ref().flags.is_null());
// SAFETY: either the column is empty or the point is not NULL
unsafe {
sys::tsk_column_access::<IndividualFlags, _, _, _>(
row.into(),
self.as_ref().flags,
self.num_rows(),
)
}
}

/// Return the locations for a given row.
Expand All @@ -223,13 +227,19 @@ impl IndividualTable {
/// * `Some(location)` if `row` is valid.
/// * `None` otherwise.
pub fn location<I: Into<IndividualId> + Copy>(&self, row: I) -> Option<&[Location]> {
sys::tsk_ragged_column_access(
row.into(),
self.as_ref().location,
self.num_rows(),
self.as_ref().location_offset,
self.as_ref().location_length,
)
assert!(
(self.num_rows() == 0 && self.as_ref().location_length == 0)
|| (!self.as_ref().location.is_null() && !self.as_ref().location_offset.is_null())
);
unsafe {
sys::tsk_ragged_column_access(
row.into(),
self.as_ref().location,
self.num_rows(),
self.as_ref().location_offset,
self.as_ref().location_length,
)
}
}

/// Return the parents for a given row.
Expand All @@ -239,13 +249,19 @@ impl IndividualTable {
/// * `Some(parents)` if `row` is valid.
/// * `None` otherwise.
pub fn parents<I: Into<IndividualId> + Copy>(&self, row: I) -> Option<&[IndividualId]> {
sys::tsk_ragged_column_access(
row.into(),
self.as_ref().parents,
self.num_rows(),
self.as_ref().parents_offset,
self.as_ref().parents_length,
)
assert!(
(self.num_rows() == 0 && self.as_ref().parents_length == 0)
|| (!self.as_ref().parents.is_null() && !self.as_ref().location_offset.is_null())
);
unsafe {
sys::tsk_ragged_column_access(
row.into(),
self.as_ref().parents,
self.num_rows(),
self.as_ref().parents_offset,
self.as_ref().parents_length,
)
}
}

/// Return the metadata for a given row.
Expand Down
74 changes: 56 additions & 18 deletions src/migration_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,16 @@ impl MigrationTable {
/// * `Some(position)` if `row` is valid.
/// * `None` otherwise.
pub fn left<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<Position> {
sys::tsk_column_access::<Position, _, _, _>(row.into(), self.as_ref().left, self.num_rows())
assert!(self.num_rows() == 0 || !self.as_ref().time.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<Position, _, _, _>(
row.into(),
self.as_ref().left,
self.num_rows(),
)
}
}

/// Return the right coordinate for a given row.
Expand All @@ -247,11 +256,16 @@ impl MigrationTable {
/// * `Some(positions)` if `row` is valid.
/// * `None` otherwise.
pub fn right<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<Position> {
sys::tsk_column_access::<Position, _, _, _>(
row.into(),
self.as_ref().right,
self.num_rows(),
)
assert!(self.num_rows() == 0 || !self.as_ref().right.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<Position, _, _, _>(
row.into(),
self.as_ref().right,
self.num_rows(),
)
}
}

/// Return the node for a given row.
Expand All @@ -261,7 +275,16 @@ impl MigrationTable {
/// * `Some(node)` if `row` is valid.
/// * `None` otherwise.
pub fn node<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<NodeId> {
sys::tsk_column_access::<NodeId, _, _, _>(row.into(), self.as_ref().node, self.num_rows())
assert!(self.num_rows() == 0 || !self.as_ref().node.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<NodeId, _, _, _>(
row.into(),
self.as_ref().node,
self.num_rows(),
)
}
}

/// Return the source population for a given row.
Expand All @@ -271,11 +294,16 @@ impl MigrationTable {
/// * `Some(population)` if `row` is valid.
/// * `None` otherwise.
pub fn source<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<PopulationId> {
sys::tsk_column_access::<PopulationId, _, _, _>(
row.into(),
self.as_ref().source,
self.num_rows(),
)
assert!(self.num_rows() == 0 || !self.as_ref().time.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<PopulationId, _, _, _>(
row.into(),
self.as_ref().source,
self.num_rows(),
)
}
}

/// Return the destination population for a given row.
Expand All @@ -285,11 +313,16 @@ impl MigrationTable {
/// * `Some(population)` if `row` is valid.
/// * `None` otherwise.
pub fn dest<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<PopulationId> {
sys::tsk_column_access::<PopulationId, _, _, _>(
row.into(),
self.as_ref().dest,
self.num_rows(),
)
assert!(self.num_rows() == 0 || !self.as_ref().dest.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<PopulationId, _, _, _>(
row.into(),
self.as_ref().dest,
self.num_rows(),
)
}
}

/// Return the time of the migration event for a given row.
Expand All @@ -299,7 +332,12 @@ impl MigrationTable {
/// * `Some(time)` if `row` is valid.
/// * `None` otherwise.
pub fn time<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<Time> {
sys::tsk_column_access::<Time, _, _, _>(row.into(), self.as_ref().time, self.num_rows())
assert!(self.num_rows() == 0 || !self.as_ref().time.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<Time, _, _, _>(row.into(), self.as_ref().time, self.num_rows())
}
}

/// Retrieve decoded metadata for a `row`.
Expand Down
67 changes: 52 additions & 15 deletions src/mutation_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,16 @@ impl MutationTable {
/// Will return [``IndexError``](crate::TskitError::IndexError)
/// if ``row`` is out of range.
pub fn site<M: Into<MutationId> + Copy>(&self, row: M) -> Option<SiteId> {
sys::tsk_column_access::<SiteId, _, _, _>(row.into(), self.as_ref().site, self.num_rows())
assert!(self.num_rows() == 0 || !self.as_ref().site.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<SiteId, _, _, _>(
row.into(),
self.as_ref().site,
self.num_rows(),
)
}
}

/// Return the ``node`` value from row ``row`` of the table.
Expand All @@ -243,7 +252,16 @@ impl MutationTable {
/// Will return [``IndexError``](crate::TskitError::IndexError)
/// if ``row`` is out of range.
pub fn node<M: Into<MutationId> + Copy>(&self, row: M) -> Option<NodeId> {
sys::tsk_column_access::<NodeId, _, _, _>(row.into(), self.as_ref().node, self.num_rows())
assert!(self.num_rows() == 0 || !self.as_ref().node.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<NodeId, _, _, _>(
row.into(),
self.as_ref().node,
self.num_rows(),
)
}
}

/// Return the ``parent`` value from row ``row`` of the table.
Expand All @@ -253,11 +271,16 @@ impl MutationTable {
/// Will return [``IndexError``](crate::TskitError::IndexError)
/// if ``row`` is out of range.
pub fn parent<M: Into<MutationId> + Copy>(&self, row: M) -> Option<MutationId> {
sys::tsk_column_access::<MutationId, _, _, _>(
row.into(),
self.as_ref().parent,
self.num_rows(),
)
assert!(self.num_rows() == 0 || !self.as_ref().parent.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<MutationId, _, _, _>(
row.into(),
self.as_ref().parent,
self.num_rows(),
)
}
}

/// Return the ``time`` value from row ``row`` of the table.
Expand All @@ -267,7 +290,12 @@ impl MutationTable {
/// Will return [``IndexError``](crate::TskitError::IndexError)
/// if ``row`` is out of range.
pub fn time<M: Into<MutationId> + Copy>(&self, row: M) -> Option<Time> {
sys::tsk_column_access::<Time, _, _, _>(row.into(), self.as_ref().time, self.num_rows())
assert!(self.num_rows() == 0 || !self.as_ref().time.is_null());
// SAFETY: either the column is empty or the pointer is not null,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_column_access::<Time, _, _, _>(row.into(), self.as_ref().time, self.num_rows())
}
}

/// Get the ``derived_state`` value from row ``row`` of the table.
Expand All @@ -281,13 +309,22 @@ impl MutationTable {
/// Will return [``IndexError``](crate::TskitError::IndexError)
/// if ``row`` is out of range.
pub fn derived_state<M: Into<MutationId>>(&self, row: M) -> Option<&[u8]> {
sys::tsk_ragged_column_access(
row.into(),
self.as_ref().derived_state,
self.num_rows(),
self.as_ref().derived_state_offset,
self.as_ref().derived_state_length,
)
assert!(
(self.num_rows() == 0 && self.as_ref().derived_state_length == 0)
|| (!self.as_ref().derived_state.is_null()
&& !self.as_ref().derived_state_offset.is_null())
);
// SAFETY: either both columns are empty or both pointers at not NULL,
// in which case the correct lengths are from the low-level objects
unsafe {
sys::tsk_ragged_column_access(
row.into(),
self.as_ref().derived_state,
self.num_rows(),
self.as_ref().derived_state_offset,
self.as_ref().derived_state_length,
)
}
}

/// Retrieve decoded metadata for a `row`.
Expand Down
Loading
Loading