use crate::bindings as ll_bindings;
use crate::metadata;
use crate::sys;
use crate::SizeType;
use crate::Time;
use crate::{tsk_id_t, TskitError};
use crate::{MutationId, NodeId, SiteId};
#[derive(Debug)]
pub struct MutationTableRow {
pub id: MutationId,
pub site: SiteId,
pub node: NodeId,
pub parent: MutationId,
pub time: Time,
pub derived_state: Option<Vec<u8>>,
pub metadata: Option<Vec<u8>>,
}
impl PartialEq for MutationTableRow {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
&& self.site == other.site
&& self.node == other.node
&& self.parent == other.parent
&& crate::util::partial_cmp_equal(&self.time, &other.time)
&& self.derived_state == other.derived_state
&& self.metadata == other.metadata
}
}
fn make_mutation_table_row(table: &MutationTable, pos: tsk_id_t) -> Option<MutationTableRow> {
let index = ll_bindings::tsk_size_t::try_from(pos).ok()?;
match index {
i if i < table.num_rows() => {
let derived_state = table.derived_state(pos).map(|s| s.to_vec());
Some(MutationTableRow {
id: pos.into(),
site: table.site(pos)?,
node: table.node(pos)?,
parent: table.parent(pos)?,
time: table.time(pos)?,
derived_state,
metadata: table.raw_metadata(pos).map(|m| m.to_vec()),
})
}
_ => None,
}
}
pub(crate) type MutationTableRefIterator<'a> =
crate::table_iterator::TableIterator<&'a MutationTable>;
pub(crate) type MutationTableIterator = crate::table_iterator::TableIterator<MutationTable>;
impl<'a> Iterator for MutationTableRefIterator<'a> {
type Item = MutationTableRow;
fn next(&mut self) -> Option<Self::Item> {
let rv = make_mutation_table_row(self.table, self.pos);
self.pos += 1;
rv
}
}
impl Iterator for MutationTableIterator {
type Item = MutationTableRow;
fn next(&mut self) -> Option<Self::Item> {
let rv = make_mutation_table_row(&self.table, self.pos);
self.pos += 1;
rv
}
}
#[derive(Debug)]
pub struct MutationTableRowView<'a> {
table: &'a MutationTable,
pub id: MutationId,
pub site: SiteId,
pub node: NodeId,
pub parent: MutationId,
pub time: Time,
pub derived_state: Option<&'a [u8]>,
pub metadata: Option<&'a [u8]>,
}
impl<'a> MutationTableRowView<'a> {
fn new(table: &'a MutationTable) -> Self {
Self {
table,
id: MutationId::NULL,
site: SiteId::NULL,
node: NodeId::NULL,
parent: MutationId::NULL,
time: f64::NAN.into(),
derived_state: None,
metadata: None,
}
}
}
impl<'a> PartialEq for MutationTableRowView<'a> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
&& self.site == other.site
&& self.node == other.node
&& self.parent == other.parent
&& crate::util::partial_cmp_equal(&self.time, &other.time)
&& self.derived_state == other.derived_state
&& self.metadata == other.metadata
}
}
impl<'a> Eq for MutationTableRowView<'a> {}
impl<'a> PartialEq<MutationTableRow> for MutationTableRowView<'a> {
fn eq(&self, other: &MutationTableRow) -> bool {
self.id == other.id
&& self.site == other.site
&& self.node == other.node
&& self.parent == other.parent
&& crate::util::partial_cmp_equal(&self.time, &other.time)
&& optional_container_comparison!(self.derived_state, other.derived_state)
&& optional_container_comparison!(self.metadata, other.metadata)
}
}
impl PartialEq<MutationTableRowView<'_>> for MutationTableRow {
fn eq(&self, other: &MutationTableRowView) -> bool {
self.id == other.id
&& self.site == other.site
&& self.node == other.node
&& self.parent == other.parent
&& crate::util::partial_cmp_equal(&self.time, &other.time)
&& optional_container_comparison!(self.derived_state, other.derived_state)
&& optional_container_comparison!(self.metadata, other.metadata)
}
}
impl<'a> streaming_iterator::StreamingIterator for MutationTableRowView<'a> {
type Item = Self;
row_lending_iterator_get!();
fn advance(&mut self) {
self.id = (i32::from(self.id) + 1).into();
self.site = self.table.site(self.id).unwrap_or(SiteId::NULL);
self.node = self.table.node(self.id).unwrap_or(NodeId::NULL);
self.parent = self.table.parent(self.id).unwrap_or(MutationId::NULL);
self.time = self.table.time(self.id).unwrap_or_else(|| f64::NAN.into());
self.derived_state = self.table.derived_state(self.id);
self.metadata = self.table.raw_metadata(self.id);
}
}
#[derive(Debug)]
#[repr(transparent)]
pub struct MutationTable {
table_: sys::LLMutationTableRef,
}
impl MutationTable {
pub(crate) fn new_from_table(
mutations: *mut ll_bindings::tsk_mutation_table_t,
) -> Result<Self, TskitError> {
let table_ = sys::LLMutationTableRef::new_from_table(mutations)?;
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()
}
raw_metadata_getter_for_tables!(MutationId);
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())
}
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())
}
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(),
)
}
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())
}
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,
)
}
pub fn metadata<T: metadata::MutationMetadata>(
&self,
row: MutationId,
) -> Option<Result<T, TskitError>> {
let buffer = self.raw_metadata(row)?;
Some(decode_metadata_row!(T, buffer).map_err(|e| e.into()))
}
pub fn iter(&self) -> impl Iterator<Item = MutationTableRow> + '_ {
crate::table_iterator::make_table_iterator::<&MutationTable>(self)
}
pub fn lending_iter(&self) -> MutationTableRowView {
MutationTableRowView::new(self)
}
pub fn row<M: Into<MutationId> + Copy>(&self, r: M) -> Option<MutationTableRow> {
let ri = r.into().into();
table_row_access!(ri, self, make_mutation_table_row)
}
pub fn row_view<M: Into<MutationId> + Copy>(&self, r: M) -> Option<MutationTableRowView> {
let view = MutationTableRowView {
table: self,
id: r.into(),
site: self.site(r)?,
node: self.node(r)?,
parent: self.parent(r)?,
time: self.time(r)?,
derived_state: self.derived_state(r),
metadata: self.raw_metadata(r.into()),
};
Some(view)
}
build_table_column_slice_getter!(
=> node, node_slice, NodeId);
build_table_column_slice_getter!(
=> node, node_slice_raw, crate::tsk_id_t);
build_table_column_slice_getter!(
=> site, site_slice, SiteId);
build_table_column_slice_getter!(
=> site, site_slice_raw, crate::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::tsk_id_t);
}
build_owned_table_type!(
=> OwningMutationTable,
MutationTable,
crate::sys::LLOwningMutationTable,
crate::bindings::tsk_mutation_table_t
);
impl OwningMutationTable {
mutation_table_add_row!(=> add_row, self, self.as_mut_ptr());
mutation_table_add_row_with_metadata!(=> add_row_with_metadata, self, self.as_mut_ptr());
}