use crate::sys::bindings as ll_bindings;
use crate::RawFlags;
use super::bindings::tsk_flags_t;
use std::ops::BitAnd;
use std::ops::BitAndAssign;
use std::ops::BitOr;
use std::ops::BitOrAssign;
use std::ops::BitXor;
use std::ops::BitXorAssign;
macro_rules! make_constant_self {
($(#[$attr:meta])* => $name: ident, $constant: ident) => {
$(#[$attr])*
pub const $name: Self = Self(ll_bindings::$constant);
}
}
macro_rules! impl_from_for_flag_types {
($flagstype: ty) => {
impl From<$crate::RawFlags> for $flagstype {
fn from(value: $crate::RawFlags) -> Self {
Self(value)
}
}
};
}
macro_rules! flag_builder_api {
($(#[$attr:meta])* => $name: ident, $flag: ident) => {
$(#[$attr])*
pub fn $name(self) -> Self {
self | Self::$flag
}
};
}
macro_rules! bits {
() => {
pub fn bits(&self) -> RawFlags {
self.0
}
};
}
macro_rules! all {
() => {
pub fn all() -> Self {
Self(RawFlags::MAX)
}
};
}
macro_rules! contains {
() => {
pub fn contains<I>(&self, bit: I) -> bool
where
I: Into<Self> + Copy,
{
(self.0 & bit.into().0) != 0
}
};
}
macro_rules! impl_bit_ops {
($type: ty) => {
impl BitXorAssign for $type {
fn bitxor_assign(&mut self, rhs: Self) {
self.0 ^= rhs.0
}
}
impl BitAndAssign for $type {
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0
}
}
impl BitOrAssign for $type {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0
}
}
impl BitXor for $type {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output {
Self(self.0 ^ rhs.0)
}
}
impl BitOr for $type {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0)
}
}
impl BitAnd for $type {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
Self(self.0 & rhs.0)
}
}
};
}
macro_rules! flags_api {
($type: ty) => {
impl_from_for_flag_types!($type);
impl_bit_ops!($type);
};
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct SimplificationOptions(RawFlags);
impl SimplificationOptions {
make_constant_self!(=> FILTER_SITES, TSK_SIMPLIFY_FILTER_SITES);
make_constant_self!(
=> FILTER_POPULATIONS, TSK_SIMPLIFY_FILTER_POPULATIONS);
make_constant_self!(
=> FILTER_INDIVIDUALS,TSK_SIMPLIFY_FILTER_INDIVIDUALS);
make_constant_self!(
=> REDUCE_TO_SITE_TOPOLOGY,TSK_SIMPLIFY_REDUCE_TO_SITE_TOPOLOGY);
make_constant_self!(
=> KEEP_UNARY,TSK_SIMPLIFY_KEEP_UNARY);
make_constant_self!(
=> KEEP_INPUT_ROOTS, TSK_SIMPLIFY_KEEP_INPUT_ROOTS);
make_constant_self!(
=> KEEP_UNARY_IN_INDIVIDUALS,TSK_SIMPLIFY_KEEP_UNARY_IN_INDIVIDUALS);
flag_builder_api!(
=> keep_input_roots, KEEP_INPUT_ROOTS);
flag_builder_api!(
=> keep_unary, KEEP_UNARY);
flag_builder_api!(
=> keep_unary_in_individuals, KEEP_UNARY_IN_INDIVIDUALS);
flag_builder_api!(
=> filter_populations, FILTER_POPULATIONS);
flag_builder_api!(
=> filter_sites, FILTER_SITES);
flag_builder_api!(
=> reduce_to_site_topology, REDUCE_TO_SITE_TOPOLOGY);
flag_builder_api!(
=> filter_individuals, FILTER_INDIVIDUALS);
bits!();
all!();
contains!();
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct TableClearOptions(RawFlags);
impl TableClearOptions {
make_constant_self!(=> CLEAR_METADATA_SCHEMAS,TSK_CLEAR_METADATA_SCHEMAS);
make_constant_self!(=> CLEAR_TS_METADATA_SCHEMA, TSK_CLEAR_TS_METADATA_AND_SCHEMA);
make_constant_self!(=> CLEAR_PROVENANCE,TSK_CLEAR_PROVENANCE);
flag_builder_api!(
=> clear_metadata_schema, CLEAR_METADATA_SCHEMAS);
flag_builder_api!(
=> clear_ts_metadata_and_schema, CLEAR_TS_METADATA_SCHEMA);
flag_builder_api!(
=> clear_provenance, CLEAR_PROVENANCE);
bits!();
all!();
contains!();
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct TableEqualityOptions(RawFlags);
impl TableEqualityOptions {
make_constant_self!(=> IGNORE_METADATA,TSK_CMP_IGNORE_METADATA);
make_constant_self!(=>IGNORE_TS_METADATA, TSK_CMP_IGNORE_TS_METADATA);
make_constant_self!(=> IGNORE_PROVENANCE,TSK_CMP_IGNORE_PROVENANCE);
make_constant_self!(=> IGNORE_TIMESTAMPS,TSK_CMP_IGNORE_TIMESTAMPS);
flag_builder_api!(
=> ignore_metadata, IGNORE_METADATA);
flag_builder_api!(
=> ignore_ts_metadata, IGNORE_TS_METADATA);
flag_builder_api!(
=> ignore_provenance, IGNORE_PROVENANCE);
flag_builder_api!(
=> ignore_timestamps, IGNORE_TIMESTAMPS);
bits!();
all!();
contains!();
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct TableSortOptions(RawFlags);
impl TableSortOptions {
make_constant_self!(
=> NO_CHECK_INTEGRITY, TSK_NO_CHECK_INTEGRITY);
flag_builder_api!(
=> no_check_integrity, NO_CHECK_INTEGRITY);
bits!();
all!();
contains!();
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct IndividualTableSortOptions(RawFlags);
impl IndividualTableSortOptions {
bits!();
all!();
contains!();
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct TreeFlags(RawFlags);
impl TreeFlags {
make_constant_self!(
=> SAMPLE_LISTS,TSK_SAMPLE_LISTS);
make_constant_self!(
=> NO_SAMPLE_COUNTS,TSK_NO_SAMPLE_COUNTS);
flag_builder_api!(
=> sample_lists, SAMPLE_LISTS);
flag_builder_api!(
=> no_sample_counts, NO_SAMPLE_COUNTS);
bits!();
all!();
contains!();
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct TableOutputOptions(RawFlags);
impl TableOutputOptions {
bits!();
all!();
contains!();
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct TreeSequenceFlags(RawFlags);
impl TreeSequenceFlags {
make_constant_self!(
=> BUILD_INDEXES, TSK_TS_INIT_BUILD_INDEXES);
flag_builder_api!(
=> build_indexes, BUILD_INDEXES);
bits!();
all!();
contains!();
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct TableIntegrityCheckFlags(RawFlags);
impl TableIntegrityCheckFlags {
make_constant_self!(
=> CHECK_EDGE_ORDERING, TSK_CHECK_EDGE_ORDERING);
make_constant_self!(
=> CHECK_SITE_ORDERING, TSK_CHECK_SITE_ORDERING);
make_constant_self!(
=> CHECK_SITE_DUPLICATES, TSK_CHECK_SITE_DUPLICATES);
make_constant_self!(
=> CHECK_MUTATION_ORDERING, TSK_CHECK_MUTATION_ORDERING);
make_constant_self!(
=> CHECK_INDIVIDUAL_ORDERING, TSK_CHECK_INDIVIDUAL_ORDERING);
make_constant_self!(
=> CHECK_MIGRATION_ORDERING, TSK_CHECK_MIGRATION_ORDERING);
make_constant_self!(
=> CHECK_INDEXES, TSK_CHECK_INDEXES);
make_constant_self!(
=> CHECK_TREES, TSK_CHECK_TREES);
flag_builder_api!(
=> check_edge_ordering, CHECK_EDGE_ORDERING);
flag_builder_api!(
=> check_site_ordering, CHECK_SITE_ORDERING);
flag_builder_api!(
=> check_individual_ordering, CHECK_INDIVIDUAL_ORDERING);
flag_builder_api!(
=> check_mutation_ordering, CHECK_MUTATION_ORDERING);
flag_builder_api!(
=> check_migration_ordering, CHECK_MIGRATION_ORDERING);
flag_builder_api!(
=> check_site_duplicates, CHECK_SITE_DUPLICATES);
flag_builder_api!(
=> check_indexes, CHECK_INDEXES);
flag_builder_api!(
=> check_trees, CHECK_TREES);
bits!();
all!();
contains!();
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NodeFlags(tsk_flags_t);
impl NodeFlags {
make_constant_self!(
=> IS_SAMPLE, TSK_NODE_IS_SAMPLE);
pub fn new_sample() -> Self {
Self::default().mark_sample()
}
pub fn mark_sample(self) -> Self {
Self(self.0 | Self::IS_SAMPLE.0)
}
pub fn is_sample(&self) -> bool {
self.contains(Self::IS_SAMPLE)
}
bits!();
all!();
contains!();
pub fn toggle<I: Into<Self>>(&mut self, bit: I) {
self.bitxor_assign(bit.into());
}
pub fn remove<I>(&mut self, bit: I)
where
I: Into<Self>,
{
self.0 &= !bit.into().0
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct IndividualFlags(RawFlags);
impl IndividualFlags {
bits!();
all!();
contains!();
}
flags_api!(SimplificationOptions);
flags_api!(TableClearOptions);
flags_api!(TableEqualityOptions);
flags_api!(TreeSequenceFlags);
flags_api!(TableSortOptions);
flags_api!(TreeFlags);
flags_api!(IndividualTableSortOptions);
flags_api!(TableIntegrityCheckFlags);
flags_api!(TableOutputOptions);
flags_api!(NodeFlags);
impl From<RawFlags> for IndividualFlags {
fn from(flags: RawFlags) -> Self {
Self(flags)
}
}
#[derive(Copy, Clone, Default, Debug)]
pub struct MutationParentsFlags(tsk_flags_t);
impl From<MutationParentsFlags> for tsk_flags_t {
fn from(value: MutationParentsFlags) -> Self {
value.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_looks_like_zero() {
let n = NodeFlags::default();
assert_eq!(n.bits(), 0);
let s = SimplificationOptions::default();
assert_eq!(s.bits(), 0);
}
#[test]
fn node_is_not_sample() {
let n = NodeFlags::default();
assert!(!n.is_sample());
}
#[test]
fn node_is_sample() {
let n = NodeFlags::new_sample();
assert!(n.is_sample());
}
}