Skip to content

Commit

Permalink
feat: impl several traits for all "input" newtypes.
Browse files Browse the repository at this point in the history
* Add, Sub, Mul, Div and PartialEq for Self and f64.
* use macros to impl From to/from f64 for these types
  • Loading branch information
molpopgen committed Sep 18, 2023
1 parent 88a6c57 commit d4dea5e
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 48 deletions.
17 changes: 12 additions & 5 deletions demes/src/cloning_rate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,23 @@ impl TryFrom<f64> for CloningRate {
impl_newtype_traits!(CloningRate);

/// Input value for [`CloningRate`], used when loading or building graphs.
///
/// # Examples
///
/// ```
/// let t = demes::InputCloningRate::from(1.0);
/// assert_eq!(t, 1.0);
/// let t = t - 1.0;
/// assert_eq!(t, 0.0);
/// let t = 1.0 + t;
/// assert_eq!(t, 1.0);
/// ```
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, PartialOrd)]
#[repr(transparent)]
#[serde(from = "f64")]
pub struct InputCloningRate(f64);

impl From<f64> for InputCloningRate {
fn from(value: f64) -> Self {
Self(value)
}
}
impl_input_newtype_traits!(InputCloningRate);

impl TryFrom<InputCloningRate> for CloningRate {
type Error = DemesError;
Expand Down
23 changes: 12 additions & 11 deletions demes/src/deme_size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,23 @@ impl TryFrom<f64> for DemeSize {
impl_newtype_traits!(DemeSize);

/// Input value for [`DemeSize`], used when loading or building graphs.
///
/// # Examples
///
/// ```
/// let t = demes::InputDemeSize::from(1.0);
/// assert_eq!(t, 1.0);
/// let t = t - 1.0;
/// assert_eq!(t, 0.0);
/// let t = 1.0 + t;
/// assert_eq!(t, 1.0);
/// ```
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, PartialOrd)]
#[repr(transparent)]
#[serde(from = "f64")]
pub struct InputDemeSize(f64);

impl From<f64> for InputDemeSize {
fn from(value: f64) -> Self {
Self(value)
}
}
impl_input_newtype_traits!(InputDemeSize);

impl TryFrom<InputDemeSize> for DemeSize {
type Error = DemesError;
Expand All @@ -88,9 +95,3 @@ impl TryFrom<InputDemeSize> for DemeSize {
Ok(rv)
}
}

impl From<InputDemeSize> for f64 {
fn from(value: InputDemeSize) -> Self {
value.0
}
}
58 changes: 58 additions & 0 deletions demes/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,61 @@ macro_rules! impl_newtype_traits {
}
};
}

macro_rules! impl_input_newtype_arithmetic {
($type: ty, $op: ident, $fn: ident) => {
impl std::ops::$op for $type {
type Output = Self;
fn $fn(self, value: Self) -> Self::Output {
self.0.$fn(value.0).into()
}
}

impl std::ops::$op<f64> for $type {
type Output = Self;
fn $fn(self, value: f64) -> Self::Output {
self.0.$fn(value).into()
}
}

impl std::ops::$op<$type> for f64 {
type Output = Self;
fn $fn(self, value: $type) -> Self::Output {
self.$fn(value.0).into()
}
}
};
}

macro_rules! impl_input_newtype_traits {
($type: ty) => {
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 PartialEq<$type> for f64 {
fn eq(&self, other: &$type) -> bool {
self.eq(&other.0)
}
}

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

impl_input_newtype_arithmetic!($type, Add, add);
impl_input_newtype_arithmetic!($type, Sub, sub);
impl_input_newtype_arithmetic!($type, Mul, mul);
impl_input_newtype_arithmetic!($type, Div, div);
};
}
15 changes: 10 additions & 5 deletions demes/src/migration_rate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,21 @@ impl TryFrom<f64> for MigrationRate {
/// ## Using [`GraphBuilder`](crate::GraphBuilder)
///
/// * [`GraphBuilder::migration`](crate::GraphBuilder::add_migration)
///
/// ```
/// let t = demes::InputMigrationRate::from(0.1);
/// assert_eq!(t, 0.1);
/// let t = t - 1.0;
/// assert_eq!(t, 0.1 - 1.0);
/// let t = 1.0 + t;
/// assert_eq!(t, 0.1 - 1.0 + 1.0);
/// ```
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
#[repr(transparent)]
#[serde(from = "f64")]
pub struct InputMigrationRate(f64);

impl From<f64> for InputMigrationRate {
fn from(value: f64) -> Self {
Self(value)
}
}
impl_input_newtype_traits!(InputMigrationRate);

impl TryFrom<InputMigrationRate> for MigrationRate {
type Error = DemesError;
Expand Down
23 changes: 12 additions & 11 deletions demes/src/proportion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,23 @@ impl TryFrom<f64> for Proportion {
impl_newtype_traits!(Proportion);

/// Input value for [`Proportion`], used when loading or building graphs.
///
/// # Examples
///
/// ```
/// let t = demes::InputProportion::from(1.0);
/// assert_eq!(t, 1.0);
/// let t = t - 1.0;
/// assert_eq!(t, 0.0);
/// let t = 1.0 + t;
/// assert_eq!(t, 1.0);
/// ```
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, PartialOrd)]
#[repr(transparent)]
#[serde(from = "f64")]
pub struct InputProportion(f64);

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

impl From<InputProportion> for f64 {
fn from(value: InputProportion) -> Self {
value.0
}
}
impl_input_newtype_traits!(InputProportion);

impl TryFrom<InputProportion> for Proportion {
type Error = DemesError;
Expand Down
17 changes: 12 additions & 5 deletions demes/src/selfing_rate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,23 @@ impl TryFrom<f64> for SelfingRate {
}

/// Input value for [`SelfingRate`], used when loading or building graphs.
///
/// # Examples
///
/// ```
/// let t = demes::InputSelfingRate::from(1.0);
/// assert_eq!(t, 1.0);
/// let t = t - 1.0;
/// assert_eq!(t, 0.0);
/// let t = 1.0 + t;
/// assert_eq!(t, 1.0);
/// ```
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, PartialOrd)]
#[repr(transparent)]
#[serde(from = "f64")]
pub struct InputSelfingRate(f64);

impl From<f64> for InputSelfingRate {
fn from(value: f64) -> Self {
Self(value)
}
}
impl_input_newtype_traits!(InputSelfingRate);

impl TryFrom<InputSelfingRate> for SelfingRate {
type Error = DemesError;
Expand Down
23 changes: 12 additions & 11 deletions demes/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ impl TryFrom<f64> for Time {
}

/// Input value for [`Time`], used when loading or building graphs.
///
/// # Examples
///
/// ```
/// let t = demes::InputTime::from(1.0);
/// assert_eq!(t, 1.0);
/// let t = t - 1.0;
/// assert_eq!(t, 0.0);
/// let t = 1.0 + t;
/// assert_eq!(t, 1.0);
/// ```
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, PartialOrd)]
#[repr(transparent)]
#[serde(try_from = "TimeTrampoline")]
Expand Down Expand Up @@ -117,17 +128,7 @@ impl InputTime {
}
}

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

impl From<InputTime> for f64 {
fn from(value: InputTime) -> Self {
value.0
}
}
impl_input_newtype_traits!(InputTime);

impl TryFrom<InputTime> for Time {
type Error = DemesError;
Expand Down

0 comments on commit d4dea5e

Please sign in to comment.