Skip to content

Commit

Permalink
refactor: move newtype definitions to sys module.
Browse files Browse the repository at this point in the history
* re-export and document them from main crate.
  • Loading branch information
molpopgen committed Apr 30, 2024
1 parent 7a36294 commit 0568250
Show file tree
Hide file tree
Showing 5 changed files with 557 additions and 535 deletions.
271 changes: 0 additions & 271 deletions src/_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,277 +65,6 @@ macro_rules! iterator_for_nodeiterator {
};
}

macro_rules! impl_id_traits {
($idtype: ty) => {
impl $idtype {
/// NULL value for this type.
pub const NULL: $idtype = Self($crate::sys::TSK_NULL);

/// Return `true` is `self == Self::NULL`
pub fn is_null(&self) -> bool {
*self == Self::NULL
}

/// Convenience function to convert to usize.
///
/// Works via [`TryFrom`].
///
/// # Returns
///
/// * `None` if the underlying value is negative.
/// * `Some(usize)` otherwise.
pub fn to_usize(&self) -> Option<usize> {
usize::try_from(*self).ok()
}

/// Convenience function to convert to usize.
/// Implemented via `as`.
/// Negative values with therefore wrap.
pub fn as_usize(&self) -> usize {
self.0 as usize
}
}

impl std::fmt::Display for $idtype {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self == Self::NULL {
false => write!(f, "{}", self.0),
true => write!(f, "NULL"),
}
}
}

impl From<$crate::sys::bindings::tsk_id_t> for $idtype {
fn from(value: $crate::sys::bindings::tsk_id_t) -> Self {
Self(value)
}
}

impl TryFrom<$idtype> for usize {
type Error = crate::TskitError;
fn try_from(value: $idtype) -> Result<Self, Self::Error> {
match value.0.try_into() {
Ok(value) => Ok(value),
Err(_) => Err(crate::TskitError::RangeError(format!(
"could not convert {:?} to usize",
value
))),
}
}
}

impl From<$idtype> for $crate::sys::bindings::tsk_id_t {
fn from(value: $idtype) -> Self {
value.0
}
}

impl TryFrom<$idtype> for $crate::SizeType {
type Error = $crate::TskitError;

fn try_from(value: $idtype) -> Result<Self, Self::Error> {
$crate::SizeType::try_from(value.0)
}
}

impl PartialEq<$crate::sys::bindings::tsk_id_t> for $idtype {
fn eq(&self, other: &$crate::sys::bindings::tsk_id_t) -> bool {
self.0 == *other
}
}

impl PartialEq<$idtype> for $crate::sys::bindings::tsk_id_t {
fn eq(&self, other: &$idtype) -> bool {
*self == other.0
}
}

impl PartialOrd<$crate::sys::bindings::tsk_id_t> for $idtype {
fn partial_cmp(
&self,
other: &$crate::sys::bindings::tsk_id_t,
) -> Option<std::cmp::Ordering> {
self.0.partial_cmp(other)
}
}

impl PartialOrd<$idtype> for $crate::sys::bindings::tsk_id_t {
fn partial_cmp(&self, other: &$idtype) -> Option<std::cmp::Ordering> {
self.partial_cmp(&other.0)
}
}

impl Default for $idtype {
fn default() -> Self {
Self::NULL
}
}
};
}

macro_rules! impl_size_type_comparisons_for_row_ids {
($idtype: ty) => {
impl PartialEq<$idtype> for $crate::SizeType {
fn eq(&self, other: &$idtype) -> bool {
self.0 == other.0 as $crate::sys::bindings::tsk_size_t
}
}

impl PartialEq<$crate::SizeType> for $idtype {
fn eq(&self, other: &$crate::SizeType) -> bool {
(self.0 as $crate::sys::bindings::tsk_size_t) == other.0
}
}

impl PartialOrd<$idtype> for $crate::SizeType {
fn partial_cmp(&self, other: &$idtype) -> Option<std::cmp::Ordering> {
self.0
.partial_cmp(&(other.0 as $crate::sys::bindings::tsk_size_t))
}
}

impl PartialOrd<$crate::SizeType> for $idtype {
fn partial_cmp(&self, other: &$crate::SizeType) -> Option<std::cmp::Ordering> {
(self.0 as $crate::sys::bindings::tsk_size_t).partial_cmp(&other.0)
}
}
};
}

macro_rules! impl_f64_newtypes {
($type: ty) => {
impl std::fmt::Display for $type {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

impl PartialEq<f64> for $type {
fn eq(&self, other: &f64) -> bool {
self.0.eq(other)
}
}

impl PartialEq<$type> for f64 {
fn eq(&self, other: &$type) -> bool {
self.eq(&other.0)
}
}

impl PartialOrd<f64> for $type {
fn partial_cmp(&self, other: &f64) -> Option<std::cmp::Ordering> {
self.0.partial_cmp(other)
}
}

impl PartialOrd<$type> for f64 {
fn partial_cmp(&self, other: &$type) -> Option<std::cmp::Ordering> {
self.partial_cmp(&other.0)
}
}

impl From<f64> for $type {
fn from(value: f64) -> Self {
Self(value)
}
}

impl From<$type> for f64 {
fn from(value: $type) -> Self {
value.0
}
}

impl std::ops::Sub for $type {
type Output = Self;

fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 - rhs.0)
}
}

impl std::ops::SubAssign for $type {
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0
}
}

impl std::ops::Add for $type {
type Output = Self;

fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}

impl std::ops::AddAssign for $type {
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0
}
}

impl std::ops::Mul for $type {
type Output = Self;

fn mul(self, rhs: Self) -> Self::Output {
Self(self.0 * rhs.0)
}
}

impl std::ops::MulAssign for $type {
fn mul_assign(&mut self, rhs: Self) {
self.0.mul_assign(&rhs.0)
}
}

impl std::ops::Div for $type {
type Output = Self;

fn div(self, rhs: Self) -> Self::Output {
Self(self.0 / rhs.0)
}
}

impl std::ops::DivAssign for $type {
fn div_assign(&mut self, rhs: Self) {
self.0.div_assign(&rhs.0)
}
}
};
}

macro_rules! impl_time_position_arithmetic {
($lhs: ty, $rhs:ty) => {
impl std::ops::Mul<$rhs> for $lhs {
type Output = $lhs;

fn mul(self, other: $rhs) -> Self {
Self(self.0.mul(&other.0))
}
}

impl std::ops::MulAssign<$rhs> for $lhs {
fn mul_assign(&mut self, other: $rhs) {
self.0.mul_assign(&other.0)
}
}

impl std::ops::Div<$rhs> for $lhs {
type Output = $lhs;

fn div(self, other: $rhs) -> Self {
Self(self.0.div(&other.0))
}
}

impl std::ops::DivAssign<$rhs> for $lhs {
fn div_assign(&mut self, other: $rhs) {
self.0.div_assign(&other.0)
}
}
};
}

/// Convenience macro to handle implementing
/// [`crate::metadata::MetadataRoundtrip`]
#[macro_export]
Expand Down
Loading

0 comments on commit 0568250

Please sign in to comment.