strong-type 0.1.0

Procedural macros for naming and strong-typing pritimives and strings
Documentation
strong-type-0.1.0 has been yanked.

strong-type

strong-type is a Rust crate providing macros to create strongly typed and named values. It simplifies the process of defining types that are distinct at the type level but share underlying data structures.

use strong_type::StrongType;

#[derive(StrongType)]
struct Timestamp(i64);

let timestamp = Timestamp(1701620628123456789);
println!("{}", timestamp); // Timestamp(1701620628123456789)

Features

  • StrongType: Create a named strong type.
  • StrongNumericType: Extend StrongType with arithmetic operations.
  • custom_display: Allow users to manually implement Display instead of using the default display format.

Supported underlying types:

  • Both StrongType and StrongNumericType:
    • i8, i16, i32, i64, i128, isize
    • u8, u16, u32, u64, u128, usize
    • f32, f64
  • Only StrongType:
    • bool
    • char
    • String

Examples

Create a named strong type:

use strong_type::StrongType;

#[derive(StrongType)]
struct Tag(String);

let _ = Tag("dev".to_string());
let tag = Tag::new("dev");
let tag: Tag = "dev".into();

Strong type:

use strong_type::StrongType;
use std::any::Any;

#[derive(StrongType)]
struct Second(i32);

#[derive(StrongType)]
struct Minute(i32);

let x = Second(2);
let y = Second(3);
let z = Minute(3);

assert_eq!(x.type_id(), y.type_id()); // Same type: Second
assert_ne!(y.type_id(), z.type_id()); // Different type: Second versus Minute

Named type with arithmetic operations:

use strong_type::StrongNumericType;

#[derive(StrongNumericType)]
struct Second(i32);

let x = Second(2);
let y = Second(3);

assert_eq!(x.value(), 2);
assert_eq!(y.value(), 3);
assert!(x < y);
assert!(y >= x);
assert_eq!(x + y, Second(5));

Named type with custom_display:

use strong_type::StrongNumericType;

#[derive(StrongNumericType)]
#[custom_display]
struct Second(f64);

impl Display for Second {
   fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
      write!(f, "Mile({:.2})", &self.0)
   }
}

println!("{}", Second(std::f64::consts::E)); // "Second(2.72)"
println!("{:?}", Second(std::f64::consts::E)); // "Second { value: 2.718281828459045 }"