use crate::metadata;
use crate::metadata::NodeMetadata;
use crate::sys;
use crate::sys::bindings as ll_bindings;
use crate::NodeFlags;
use crate::SizeType;
use crate::Time;
use crate::TskitError;
use crate::{IndividualId, NodeId, PopulationId};
use ll_bindings::tsk_id_t;
#[derive(Debug)]
pub struct NodeTableRow {
pub id: NodeId,
pub time: Time,
pub flags: NodeFlags,
pub population: PopulationId,
pub individual: IndividualId,
pub metadata: Option<Vec<u8>>,
}
impl PartialEq for NodeTableRow {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
&& self.flags == other.flags
&& self.population == other.population
&& self.individual == other.individual
&& crate::util::partial_cmp_equal(&self.time, &other.time)
&& self.metadata == other.metadata
}
}
fn make_node_table_row(table: &NodeTable, pos: tsk_id_t) -> Option<NodeTableRow> {
Some(NodeTableRow {
id: pos.into(),
time: table.time(pos)?,
flags: table.flags(pos)?,
population: table.population(pos)?,
individual: table.individual(pos)?,
metadata: table.table_.raw_metadata(pos).map(|m| m.to_vec()),
})
}
pub(crate) type NodeTableRefIterator<'a> = crate::table_iterator::TableIterator<&'a NodeTable>;
pub(crate) type NodeTableIterator = crate::table_iterator::TableIterator<NodeTable>;
impl Iterator for NodeTableRefIterator<'_> {
type Item = NodeTableRow;
fn next(&mut self) -> Option<Self::Item> {
let rv = make_node_table_row(self.table, self.pos);
self.pos += 1;
rv
}
}
impl Iterator for NodeTableIterator {
type Item = crate::node_table::NodeTableRow;
fn next(&mut self) -> Option<Self::Item> {
let rv = make_node_table_row(&self.table, self.pos);
self.pos += 1;
rv
}
}
#[derive(Debug)]
pub struct NodeTableRowView<'a> {
table: &'a NodeTable,
pub id: NodeId,
pub time: Time,
pub flags: NodeFlags,
pub population: PopulationId,
pub individual: IndividualId,
pub metadata: Option<&'a [u8]>,
}
impl<'a> NodeTableRowView<'a> {
fn new(table: &'a NodeTable) -> Self {
Self {
table,
id: NodeId::NULL,
time: f64::NAN.into(),
flags: 0.into(),
population: PopulationId::NULL,
individual: IndividualId::NULL,
metadata: None,
}
}
}
impl PartialEq for NodeTableRowView<'_> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
&& self.flags == other.flags
&& self.population == other.population
&& self.individual == other.individual
&& crate::util::partial_cmp_equal(&self.time, &other.time)
&& self.metadata == other.metadata
}
}
impl Eq for NodeTableRowView<'_> {}
impl PartialEq<NodeTableRow> for NodeTableRowView<'_> {
fn eq(&self, other: &NodeTableRow) -> bool {
self.id == other.id
&& self.flags == other.flags
&& self.population == other.population
&& self.individual == other.individual
&& crate::util::partial_cmp_equal(&self.time, &other.time)
&& optional_container_comparison!(self.metadata, other.metadata)
}
}
impl PartialEq<NodeTableRowView<'_>> for NodeTableRow {
fn eq(&self, other: &NodeTableRowView) -> bool {
self.id == other.id
&& self.flags == other.flags
&& self.population == other.population
&& self.individual == other.individual
&& crate::util::partial_cmp_equal(&self.time, &other.time)
&& optional_container_comparison!(self.metadata, other.metadata)
}
}
impl crate::StreamingIterator for NodeTableRowView<'_> {
type Item = Self;
row_lending_iterator_get!();
fn advance(&mut self) {
self.id = (i32::from(self.id) + 1).into();
self.time = self.table.time(self.id).unwrap_or_else(|| f64::NAN.into());
self.flags = self.table.flags(self.id).unwrap_or_else(|| 0.into());
self.population = self.table.population(self.id).unwrap_or(PopulationId::NULL);
self.individual = self.table.individual(self.id).unwrap_or(IndividualId::NULL);
self.metadata = self.table.table_.raw_metadata(self.id);
}
}
#[derive(Copy, Clone, Default, Eq, PartialEq, Debug)]
pub struct NodeDefaults {
pub flags: NodeFlags,
pub population: PopulationId,
pub individual: IndividualId,
}
#[derive(Debug, Clone)]
pub struct NodeDefaultsWithMetadata<M>
where
M: crate::metadata::NodeMetadata,
{
pub flags: NodeFlags,
pub population: PopulationId,
pub individual: IndividualId,
pub metadata: Option<M>,
}
impl<M> Default for NodeDefaultsWithMetadata<M>
where
M: crate::metadata::NodeMetadata,
{
fn default() -> Self {
Self {
flags: NodeFlags::default(),
population: PopulationId::default(),
individual: IndividualId::default(),
metadata: None,
}
}
}
mod private {
pub trait DefaultNodeDataMarker {}
impl DefaultNodeDataMarker for super::NodeDefaults {}
impl<M> DefaultNodeDataMarker for super::NodeDefaultsWithMetadata<M> where
M: crate::metadata::NodeMetadata
{
}
}
pub trait DefaultNodeData: private::DefaultNodeDataMarker {
fn flags(&self) -> NodeFlags;
fn population(&self) -> PopulationId;
fn individual(&self) -> IndividualId;
fn metadata(&self) -> Result<Option<Vec<u8>>, TskitError>;
}
impl DefaultNodeData for NodeDefaults {
fn flags(&self) -> NodeFlags {
self.flags
}
fn population(&self) -> PopulationId {
self.population
}
fn individual(&self) -> IndividualId {
self.individual
}
fn metadata(&self) -> Result<Option<Vec<u8>>, TskitError> {
Ok(None)
}
}
impl<M> DefaultNodeData for NodeDefaultsWithMetadata<M>
where
M: crate::metadata::NodeMetadata,
{
fn flags(&self) -> NodeFlags {
self.flags
}
fn population(&self) -> PopulationId {
self.population
}
fn individual(&self) -> IndividualId {
self.individual
}
fn metadata(&self) -> Result<Option<Vec<u8>>, TskitError> {
self.metadata.as_ref().map_or_else(
|| Ok(None),
|v| match v.encode() {
Ok(x) => Ok(Some(x)),
Err(e) => Err(e.into()),
},
)
}
}
#[cfg(doctest)]
struct NodeDefaultsWithMetadataNotCloneNotDebug;
#[derive(Debug, Default)]
#[repr(transparent)]
pub struct NodeTable {
table_: sys::NodeTable,
}
impl NodeTable {
pub fn new() -> Result<Self, TskitError> {
let table_ = sys::NodeTable::new(0)?;
Ok(Self { table_ })
}
pub(crate) unsafe fn new_from_table(
nodes: *mut ll_bindings::tsk_node_table_t,
) -> Result<Self, TskitError> {
let ptr = std::ptr::NonNull::new(nodes).unwrap();
let table_ = unsafe { sys::NodeTable::new_borrowed(ptr) };
Ok(NodeTable { table_ })
}
pub(crate) fn as_ref(&self) -> &ll_bindings::tsk_node_table_t {
self.table_.as_ref()
}
pub fn num_rows(&self) -> SizeType {
self.as_ref().num_rows.into()
}
pub fn time<N: Into<NodeId> + Copy>(&self, row: N) -> Option<Time> {
self.table_.time(row.into())
}
pub fn flags<N: Into<NodeId> + Copy>(&self, row: N) -> Option<NodeFlags> {
self.table_.flags(row.into())
}
pub fn population<N: Into<NodeId> + Copy>(&self, row: N) -> Option<PopulationId> {
self.table_.population(row.into())
}
pub fn deme<N: Into<NodeId> + Copy>(&self, row: N) -> Option<PopulationId> {
self.population(row)
}
pub fn individual<N: Into<NodeId> + Copy>(&self, row: N) -> Option<IndividualId> {
self.table_.individual(row.into())
}
pub fn metadata<T: metadata::NodeMetadata>(
&self,
row: impl Into<NodeId>,
) -> 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 = NodeTableRow> + '_ {
crate::table_iterator::make_table_iterator::<&NodeTable>(self)
}
pub fn lending_iter(&'_ self) -> NodeTableRowView<'_> {
NodeTableRowView::new(self)
}
pub fn row<N: Into<NodeId> + Copy>(&self, r: N) -> Option<NodeTableRow> {
let ri = r.into().into();
table_row_access!(ri, self, make_node_table_row)
}
pub fn row_view<N: Into<NodeId> + Copy>(&'_ self, r: N) -> Option<NodeTableRowView<'_>> {
let view = NodeTableRowView {
table: self,
id: r.into(),
time: self.time(r)?,
flags: self.flags(r)?,
population: self.population(r)?,
individual: self.individual(r)?,
metadata: self.table_.raw_metadata(r.into()),
};
Some(view)
}
pub fn samples_as_vector(&self) -> Vec<NodeId> {
self.create_node_id_vector(|row| row.flags.contains(NodeFlags::IS_SAMPLE))
}
pub fn create_node_id_vector(&self, mut f: impl FnMut(&NodeTableRow) -> bool) -> Vec<NodeId> {
self.iter()
.filter(|row| f(row))
.map(|row| row.id)
.collect::<Vec<_>>()
}
build_table_column_slice_getter!(
=> time, time_slice, Time);
build_table_column_slice_getter!(
=> time, time_slice_raw, f64);
build_table_column_slice_mut_getter!(
=> time, time_slice_mut, Time);
build_table_column_slice_mut_getter!(
=> time, time_slice_raw_mut, f64);
build_table_column_slice_getter!(
=> flags, flags_slice, NodeFlags);
build_table_column_slice_getter!(
=> flags, flags_slice_raw, ll_bindings::tsk_flags_t);
build_table_column_slice_mut_getter!(
=> flags, flags_slice_mut, NodeFlags);
build_table_column_slice_mut_getter!(
=> flags, flags_slice_raw_mut, ll_bindings::tsk_flags_t);
build_table_column_slice_getter!(
=> individual, individual_slice, IndividualId);
build_table_column_slice_getter!(
=> individual, individual_slice_raw, crate::sys::bindings::tsk_id_t);
build_table_column_slice_getter!(
=> population, population_slice, PopulationId);
build_table_column_slice_getter!(
=> population, population_slice_raw, crate::sys::bindings::tsk_id_t);
pub fn individual_column(&self) -> impl crate::TableColumn<NodeId, IndividualId> + '_ {
crate::table_column::OpaqueTableColumn(self.individual_slice())
}
pub fn population_column(&self) -> impl crate::TableColumn<NodeId, PopulationId> + '_ {
crate::table_column::OpaqueTableColumn(self.population_slice())
}
pub fn time_column(&self) -> impl crate::TableColumn<NodeId, Time> + '_ {
crate::table_column::OpaqueTableColumn(self.time_slice())
}
pub fn flags_column(&self) -> impl crate::TableColumn<NodeId, NodeFlags> + '_ {
crate::table_column::OpaqueTableColumn(self.flags_slice())
}
pub fn clear(&mut self) -> Result<i32, TskitError> {
handle_tsk_return_value!(self.table_.clear())
}
pub fn add_row<F, T, P, I>(
&mut self,
flags: F,
time: T,
population: P,
individual: I,
) -> Result<NodeId, TskitError>
where
F: Into<NodeFlags>,
T: Into<Time>,
P: Into<PopulationId>,
I: Into<IndividualId>,
{
self.table_.add_row(flags, time, population, individual)
}
pub fn add_row_with_metadata<F, T, P, I, M>(
&mut self,
flags: F,
time: T,
population: P,
individual: I,
metadata: &M,
) -> Result<NodeId, TskitError>
where
F: Into<NodeFlags>,
T: Into<Time>,
P: Into<PopulationId>,
I: Into<IndividualId>,
M: NodeMetadata,
{
let md = crate::metadata::EncodedMetadata::new(metadata)?;
self.table_
.add_row_with_metadata(flags, time, population, individual, md.as_slice())
}
pub fn add_row_with_defaults<T: Into<crate::Time>, D: crate::node_table::DefaultNodeData>(
&mut self,
time: T,
defaults: &D,
) -> Result<NodeId, TskitError> {
match defaults.metadata()? {
None => self.add_row(
defaults.flags(),
time,
defaults.population(),
defaults.individual(),
),
Some(md) => self.table_.add_row_with_metadata(
defaults.flags(),
time,
defaults.population(),
defaults.individual(),
&md,
),
}
}
}