Skip to content

Commit

Permalink
Add NAN and ZERO (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
yunjhongwu authored Jan 3, 2024
1 parent 4354884 commit d05c2ed
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ println!("{}", timestamp); // Timestamp(1701620628123456789)
- **Derive trait `StrongType`:** Create a named strong type.
- The macro automatically implement common traits like `Clone`, `Debug`, `Default`, `PartialEq`, `PartialOrd`, `Send`, and `Sync`. It also implements `Display` by default, unless overridden by the custom_display attribute.
- Conditionally, based on the underlying data type, traits like `Copy`, `Eq`, `Ord`, `Hash` may also be implemented. For primitive data types like `i32` or `bool`, these additional traits will be automatically included.
- Numeric types, both integer and floating-point, also implement constants `MIN`, `MAX`. Additionally, for floating-point types, the method `nan()` is implemented.
- Numeric types, both integer and floating-point, also implement constants `MIN`, `MAX`, and `ZERO`. Additionally, for floating-point types, `NAN` is implemented.

- **Attributes:** Adding the following attributes to `#[strong_type(...)]` allows for additional features:
- `auto_operators`: Automatically implements relevant arithmetic (for numeric types) or logical (for boolean types) operators.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use proc_macro2::TokenStream;
use quote::quote;

pub(crate) fn implement_min_max(name: &syn::Ident, value_type: &syn::Ident) -> TokenStream {
pub(crate) fn implement_constants(name: &syn::Ident, value_type: &syn::Ident) -> TokenStream {
quote! {
impl #name {
const MIN: Self = Self(#value_type::MIN);
const MAX: Self = Self(#value_type::MAX);
const ZERO: Self = Self(0 as #value_type);
}
}
}
4 changes: 2 additions & 2 deletions strong-type-derive/src/detail/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ mod basic_primitive;
mod basic_string;
mod bit_ops;
mod bool_ops;
mod constants;
mod display;
mod hash;
mod min_max;
mod nan;
mod negate;
mod underlying_type;
Expand All @@ -18,9 +18,9 @@ pub(crate) use basic_primitive::implement_basic_primitive;
pub(crate) use basic_string::implement_basic_string;
pub(crate) use bit_ops::implement_bit_shift;
pub(crate) use bool_ops::implement_bool_ops;
pub(crate) use constants::implement_constants;
pub(crate) use display::implement_display;
pub(crate) use hash::implement_hash;
pub(crate) use min_max::implement_min_max;
pub(crate) use nan::implement_nan;
pub(crate) use negate::implement_negate;
pub(crate) use underlying_type::{get_type_group, get_type_ident, UnderlyingTypeGroup};
Expand Down
4 changes: 1 addition & 3 deletions strong-type-derive/src/detail/nan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use quote::quote;
pub(crate) fn implement_nan(name: &syn::Ident, value_type: &syn::Ident) -> TokenStream {
quote! {
impl #name {
fn nan() -> Self {
Self(#value_type::NAN)
}
const NAN: Self = Self(#value_type::NAN);

fn is_nan(&self) -> bool {
self.0.is_nan()
Expand Down
6 changes: 3 additions & 3 deletions strong-type-derive/src/strong_type.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::detail::{
get_attributes, get_type_group, get_type_ident, implement_arithmetic, implement_basic,
implement_basic_primitive, implement_basic_string, implement_bit_shift, implement_bool_ops,
implement_display, implement_hash, implement_min_max, implement_nan, implement_negate,
implement_constants, implement_display, implement_hash, implement_nan, implement_negate,
is_struct_valid, StrongTypeAttributes, UnderlyingTypeGroup,
};
use proc_macro2::TokenStream;
Expand Down Expand Up @@ -31,12 +31,12 @@ pub(super) fn expand_strong_type(input: DeriveInput) -> TokenStream {
match &group {
UnderlyingTypeGroup::Int | UnderlyingTypeGroup::UInt => {
ast.extend(implement_basic_primitive(name, value_type));
ast.extend(implement_min_max(name, value_type));
ast.extend(implement_constants(name, value_type));
ast.extend(implement_hash(name));
}
UnderlyingTypeGroup::Float => {
ast.extend(implement_basic_primitive(name, value_type));
ast.extend(implement_min_max(name, value_type));
ast.extend(implement_constants(name, value_type));
ast.extend(implement_nan(name, value_type));
}
UnderlyingTypeGroup::Bool => {
Expand Down
19 changes: 14 additions & 5 deletions strong-type-tests/tests/strong_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,27 @@ mod tests {
}

#[test]
fn test_min_max() {
fn test_constants() {
#[derive(StrongType)]
struct Second(i32);

assert_eq!(Second::MAX.value(), i32::MAX);
assert_eq!(Second::MIN.value(), i32::MIN);
assert_eq!(Second::ZERO.value(), 0i32);

#[derive(StrongType)]
struct Meter(f64);
struct State(u8);

assert_eq!(State::MAX.value(), u8::MAX);
assert_eq!(State::MIN.value(), u8::MIN);
assert_eq!(State::ZERO.value(), 0u8);

#[derive(StrongType)]
struct Meter(f32);

assert_eq!(Meter::MAX.value(), f64::MAX);
assert_eq!(Meter::MIN.value(), f64::MIN);
assert_eq!(Meter::MAX.value(), f32::MAX);
assert_eq!(Meter::MIN.value(), f32::MIN);
assert_eq!(Meter::ZERO.value(), 0f32);
}

#[test]
Expand Down Expand Up @@ -207,7 +216,7 @@ mod tests {
#[derive(StrongType)]
struct Meter(f64);

let y = Meter::nan();
let y = Meter::NAN;
assert!(y.is_nan());
assert!(y.value().is_nan());

Expand Down

0 comments on commit d05c2ed

Please sign in to comment.