use crate::metadata;
use crate::metadata::MigrationMetadata;
use crate::sys;
use crate::Position;
use crate::SizeType;
use crate::Time;
use crate::TskitError;
use crate::{MigrationId, NodeId, PopulationId};
use sys::bindings as ll_bindings;
#[derive(Debug, Default)]
#[repr(transparent)]
pub struct MigrationTable {
table_: sys::MigrationTable,
}
impl MigrationTable {
pub(crate) unsafe fn new_from_table(
migrations: *mut ll_bindings::tsk_migration_table_t,
) -> Result<Self, TskitError> {
let ptr = std::ptr::NonNull::new(migrations).unwrap();
let table_ = unsafe { sys::MigrationTable::new_borrowed(ptr) };
Ok(MigrationTable { table_ })
}
pub(crate) fn as_ref(&self) -> &ll_bindings::tsk_migration_table_t {
self.table_.as_ref()
}
pub fn num_rows(&self) -> SizeType {
self.as_ref().num_rows.into()
}
pub fn left<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<Position> {
self.table_.left(row.into())
}
pub fn right<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<Position> {
self.table_.right(row.into())
}
pub fn node<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<NodeId> {
self.table_.node(row.into())
}
pub fn source<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<PopulationId> {
self.table_.source(row.into())
}
pub fn dest<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<PopulationId> {
self.table_.dest(row.into())
}
pub fn time<M: Into<MigrationId> + Copy>(&self, row: M) -> Option<Time> {
self.table_.time(row.into())
}
pub fn metadata<T: metadata::MigrationMetadata>(
&self,
row: impl Into<MigrationId>,
) -> Option<Result<T, TskitError>> {
let buffer = self.table_.raw_metadata(row)?;
Some(decode_metadata_row!(T, buffer).map_err(|e| e.into()))
}
pub fn iter(&self) -> impl Iterator<Item = crate::Migration<'_>> {
self.table_.iter()
}
pub fn row<M: Into<MigrationId> + Copy>(&self, r: M) -> Option<crate::Migration<'_>> {
self.table_.row(r.into())
}
build_table_column_slice_getter!(
=> left, left_slice, Position);
build_table_column_slice_getter!(
=> left, left_slice_raw, f64);
build_table_column_slice_getter!(
=> right, right_slice, Position);
build_table_column_slice_getter!(
=> right, right_slice_raw, f64);
build_table_column_slice_getter!(
=> time, time_slice, Time);
build_table_column_slice_getter!(
=> time, time_slice_raw, f64);
build_table_column_slice_getter!(
=> node, node_slice, NodeId);
build_table_column_slice_getter!(
=> node, node_slice_raw, ll_bindings::tsk_id_t);
build_table_column_slice_getter!(
=> source, source_slice, PopulationId);
build_table_column_slice_getter!(
=> source, source_slice_raw, ll_bindings::tsk_id_t);
build_table_column_slice_getter!(
=> dest, dest_slice, PopulationId);
build_table_column_slice_getter!(
=> dest, dest_slice_raw, ll_bindings::tsk_id_t);
pub fn left_column(&self) -> impl crate::TableColumn<MigrationId, Position> + '_ {
crate::table_column::OpaqueTableColumn(self.left_slice())
}
pub fn right_column(&self) -> impl crate::TableColumn<MigrationId, Position> + '_ {
crate::table_column::OpaqueTableColumn(self.right_slice())
}
pub fn node_column(&self) -> impl crate::TableColumn<MigrationId, NodeId> + '_ {
crate::table_column::OpaqueTableColumn(self.node_slice())
}
pub fn time_column(&self) -> impl crate::TableColumn<MigrationId, Time> + '_ {
crate::table_column::OpaqueTableColumn(self.time_slice())
}
pub fn source_column(&self) -> impl crate::TableColumn<MigrationId, PopulationId> + '_ {
crate::table_column::OpaqueTableColumn(self.source_slice())
}
pub fn dest_column(&self) -> impl crate::TableColumn<MigrationId, PopulationId> + '_ {
crate::table_column::OpaqueTableColumn(self.dest_slice())
}
pub fn clear(&mut self) -> Result<i32, TskitError> {
handle_tsk_return_value!(self.table_.clear())
}
pub fn add_row<LEFT, RIGHT, N, SOURCE, DEST, T>(
&mut self,
span: (LEFT, RIGHT),
node: N,
source_dest: (SOURCE, DEST),
time: T,
) -> Result<MigrationId, TskitError>
where
LEFT: Into<Position>,
RIGHT: Into<Position>,
N: Into<NodeId>,
SOURCE: Into<PopulationId>,
DEST: Into<PopulationId>,
T: Into<Time>,
{
let rv = self.table_.add_row(
(span.0.into().into(), span.1.into().into()),
node.into().into(),
source_dest.0.into().into(),
source_dest.1.into().into(),
time.into().into(),
)?;
handle_tsk_return_value!(rv, rv.into())
}
pub fn add_row_with_metadata<LEFT, RIGHT, N, SOURCE, DEST, T, M>(
&mut self,
span: (LEFT, RIGHT),
node: N,
source_dest: (SOURCE, DEST),
time: T,
metadata: &M,
) -> Result<MigrationId, TskitError>
where
LEFT: Into<Position>,
RIGHT: Into<Position>,
N: Into<NodeId>,
SOURCE: Into<PopulationId>,
DEST: Into<PopulationId>,
T: Into<Time>,
M: MigrationMetadata,
{
let md = crate::metadata::EncodedMetadata::new(metadata)?;
let rv = self.table_.add_row_with_metadata(
(span.0.into().into(), span.1.into().into()),
node.into().into(),
source_dest.0.into().into(),
source_dest.1.into().into(),
time.into().into(),
md.as_slice(),
)?;
handle_tsk_return_value!(rv, rv.into())
}
}