use crate::metadata;
use crate::metadata::MutationMetadata;
use crate::sys;
use crate::SizeType;
use crate::Time;
use crate::TskitError;
use crate::{MutationId, NodeId, SiteId};
use sys::bindings as ll_bindings;
#[derive(Debug, Default)]
#[repr(transparent)]
pub struct MutationTable {
table_: sys::MutationTable,
}
impl MutationTable {
pub(crate) unsafe fn new_from_table(
mutations: *mut ll_bindings::tsk_mutation_table_t,
) -> Result<Self, TskitError> {
let ptr = std::ptr::NonNull::new(mutations).unwrap();
let table_ = unsafe { sys::MutationTable::new_borrowed(ptr) };
Ok(MutationTable { table_ })
}
pub(crate) fn as_ref(&self) -> &ll_bindings::tsk_mutation_table_t {
self.table_.as_ref()
}
pub fn num_rows(&self) -> SizeType {
self.as_ref().num_rows.into()
}
pub fn site<M: Into<MutationId> + Copy>(&self, row: M) -> Option<SiteId> {
self.table_.site(row.into())
}
pub fn node<M: Into<MutationId> + Copy>(&self, row: M) -> Option<NodeId> {
self.table_.node(row.into())
}
pub fn parent<M: Into<MutationId> + Copy>(&self, row: M) -> Option<MutationId> {
self.table_.parent(row.into())
}
pub fn time<M: Into<MutationId> + Copy>(&self, row: M) -> Option<Time> {
self.table_.time(row.into())
}
pub fn derived_state<M: Into<MutationId>>(&self, row: M) -> Option<&[u8]> {
self.table_.derived_state(row.into())
}
pub fn metadata<T: metadata::MutationMetadata>(
&self,
row: impl Into<MutationId>,
) -> 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::Mutation<'_>> {
self.table_.iter()
}
pub fn row<M: Into<MutationId> + Copy>(&self, r: M) -> Option<crate::Mutation<'_>> {
self.table_.row(r.into())
}
build_table_column_slice_getter!(
=> node, node_slice, NodeId);
build_table_column_slice_getter!(
=> node, node_slice_raw, crate::sys::bindings::tsk_id_t);
build_table_column_slice_getter!(
=> site, site_slice, SiteId);
build_table_column_slice_getter!(
=> site, site_slice_raw, crate::sys::bindings::tsk_id_t);
build_table_column_slice_getter!(
=> time, time_slice, Time);
build_table_column_slice_getter!(
=> time, time_slice_raw, f64);
build_table_column_slice_getter!(
=> parent, parent_slice, MutationId);
build_table_column_slice_getter!(
=> parent, parent_slice_raw, crate::sys::bindings::tsk_id_t);
pub fn node_column(&self) -> impl crate::TableColumn<MutationId, NodeId> + '_ {
crate::table_column::OpaqueTableColumn(self.node_slice())
}
pub fn site_column(&self) -> impl crate::TableColumn<MutationId, SiteId> + '_ {
crate::table_column::OpaqueTableColumn(self.site_slice())
}
pub fn time_column(&self) -> impl crate::TableColumn<MutationId, Time> + '_ {
crate::table_column::OpaqueTableColumn(self.time_slice())
}
pub fn parent_column(&self) -> impl crate::TableColumn<MutationId, MutationId> + '_ {
crate::table_column::OpaqueTableColumn(self.parent_slice())
}
pub fn clear(&mut self) -> Result<i32, TskitError> {
handle_tsk_return_value!(self.table_.clear())
}
pub fn add_row<S, N, P, T>(
&mut self,
site: S,
node: N,
parent: P,
time: T,
derived_state: Option<&[u8]>,
) -> Result<MutationId, TskitError>
where
S: Into<SiteId>,
N: Into<NodeId>,
P: Into<MutationId>,
T: Into<Time>,
{
let rv = self.table_.add_row(
site.into().into(),
node.into().into(),
parent.into().into(),
time.into().into(),
derived_state,
)?;
handle_tsk_return_value!(rv, rv.into())
}
pub fn add_row_with_metadata<S, N, P, T, M>(
&mut self,
site: S,
node: N,
parent: P,
time: T,
derived_state: Option<&[u8]>,
metadata: &M,
) -> Result<MutationId, TskitError>
where
S: Into<SiteId>,
N: Into<NodeId>,
P: Into<MutationId>,
T: Into<Time>,
M: MutationMetadata,
{
let md = crate::metadata::EncodedMetadata::new(metadata)?;
let rv = self.table_.add_row_with_metadata(
site.into().into(),
node.into().into(),
parent.into().into(),
time.into().into(),
derived_state,
md.as_slice(),
)?;
handle_tsk_return_value!(rv, rv.into())
}
}