use crate::metadata;
use crate::metadata::SiteMetadata;
use crate::sys;
use crate::sys::bindings as ll_bindings;
use crate::Position;
use crate::SiteId;
use crate::SizeType;
use crate::TskitError;
#[derive(Debug, Default)]
#[repr(transparent)]
pub struct SiteTable {
table_: sys::SiteTable,
}
impl SiteTable {
pub(crate) unsafe fn new_from_table(
sites: *mut ll_bindings::tsk_site_table_t,
) -> Result<Self, TskitError> {
let ptr = std::ptr::NonNull::new(sites).unwrap();
let table_ = unsafe { sys::SiteTable::new_borrowed(ptr) };
Ok(SiteTable { table_ })
}
pub(crate) fn as_ref(&self) -> &ll_bindings::tsk_site_table_t {
self.table_.as_ref()
}
pub fn num_rows(&self) -> SizeType {
self.as_ref().num_rows.into()
}
pub fn position<S: Into<SiteId> + Copy>(&self, row: S) -> Option<Position> {
self.table_.position(row.into())
}
pub fn ancestral_state<S: Into<SiteId>>(&self, row: S) -> Option<&[u8]> {
self.table_.ancestral_state(row.into())
}
pub fn metadata<T: metadata::SiteMetadata>(
&self,
row: impl Into<SiteId>,
) -> Option<Result<T, TskitError>> {
let buffer = self.table_.raw_metadata(row)?;
Some(decode_metadata_row!(T, buffer).map_err(TskitError::from))
}
pub fn iter(&self) -> impl Iterator<Item = crate::Site<'_>> {
self.table_.iter()
}
pub fn row<S: Into<SiteId> + Copy>(&self, r: S) -> Option<super::Site<'_>> {
self.table_.row(r.into())
}
build_table_column_slice_getter!(
=> position, position_slice, Position);
build_table_column_slice_getter!(
=> position, position_slice_raw, f64);
pub fn position_column(&self) -> impl crate::TableColumn<SiteId, Position> + '_ {
crate::table_column::OpaqueTableColumn(self.position_slice())
}
pub fn clear(&mut self) -> Result<i32, TskitError> {
handle_tsk_return_value!(self.table_.clear())
}
pub fn add_row<P: Into<Position>>(
&mut self,
position: P,
ancestral_state: Option<&[u8]>,
) -> Result<SiteId, TskitError> {
let rv = self
.table_
.add_row(position.into().into(), ancestral_state)?;
handle_tsk_return_value!(rv, rv.into())
}
pub fn add_row_with_metadata<P: Into<Position>, M: SiteMetadata>(
&mut self,
position: P,
ancestral_state: Option<&[u8]>,
metadata: &M,
) -> Result<SiteId, TskitError> {
let md = crate::metadata::EncodedMetadata::new(metadata)?;
let rv = self.table_.add_row_with_metadata(
position.into().into(),
ancestral_state,
md.as_slice(),
)?;
handle_tsk_return_value!(rv, rv.into())
}
}