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};
#[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 = crate::Node<'_>> {
self.table_.iter()
}
pub fn row<N: Into<NodeId> + Copy>(&self, r: N) -> Option<crate::Node<'_>> {
self.table_.row(r.into())
}
pub fn samples_as_vector(&self) -> Vec<NodeId> {
self.iter()
.filter(|row| row.flags().contains(NodeFlags::IS_SAMPLE))
.map(|row| row.id())
.collect::<Vec<_>>()
}
#[deprecated(
since = "0.16.2",
note = "Prefer NodeTable::iter and iterator operations"
)]
pub fn create_node_id_vector<'t>(
&'t self,
mut f: impl FnMut(&crate::Node<'t>) -> 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,
),
}
}
}