#强类型 #原始类型 #字符串 #过程宏

strong-type

用于命名和强类型化原始类型和字符串的过程宏

14 个版本 (破坏性更新)

0.12.0 2024 年 6 月 17 日
0.11.0 2024 年 4 月 14 日
0.10.0 2024 年 3 月 6 日
0.5.0 2023 年 12 月 27 日

362Rust 模式

Download history 184/week @ 2024-05-04 170/week @ 2024-05-11 19/week @ 2024-05-18 6/week @ 2024-05-25 2/week @ 2024-06-01 14/week @ 2024-06-08 178/week @ 2024-06-15 8/week @ 2024-06-22 47/week @ 2024-06-29 62/week @ 2024-07-27

每月 62 次下载

MIT/Apache

13KB
127

strong-type

strong-type 是一个 Rust 包,提供了宏来轻松创建具有命名和强类型的原始类型和字符串类型。强类型化有助于使代码更具表达性并减少错误,确保每种类型都按预期的方式使用。

use strong_type::StrongType;

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

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

功能

  • 派生 trait StrongType: 创建一个命名强类型。

    • 该宏自动实现常见的特质,如 CloneDebugDefaultPartialEqPartialOrdSendSync。它还默认实现了 Display,除非被自定义_display 属性覆盖。
    • 根据底层数据类型,条件性实现特质如 CopyEqOrdHash。对于如 i32bool 这样的原始数据类型,这些附加特质将被自动包含。
    • 数值类型,包括整数和浮点数,还实现了常量 MINMAXINFINITYNEG_INFINITYZERO。此外,对于浮点数类型,还实现了 NAN
  • 属性

    • 将以下属性添加到 #[strong_type(...)] 允许额外功能
      • auto_operators:自动实现相关算术(对于数值类型)或逻辑(对于布尔类型)运算符。
      • addable:自动实现 AddSub 和其他相关特质。该属性是 auto_operators 的严格子集。
      • 可伸缩:自动实现强类型结构体与其原始类型之间的MulDivRem和其他相关特质的实现。请注意,此属性不是auto_operators的子集。
      • 自定义显示:允许用户手动实现Display特质,提供默认显示格式的替代方案。
      • 转换:自动为底层类型实现FromInto特质。这是可选的,因为转换可能会使强类型不那么明显。
      • 底层:指定嵌套强类型的底层原始类型。

安装

strong-type添加到您的Cargo.toml

[dependencies]
strong-type = "0.12"

支持底层类型

  • 整数类型:i8i16i32i64i128isize
  • 无符号整数类型:u8u16u32u64u128usize
  • 浮点类型:f32f64
  • 布尔类型:bool
  • 字符
  • 字符串
  • 上述类型的强类型

示例

创建命名强类型

带有私有字段

use strong_type::StrongType;

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

let tag = Tag::new("dev");
const TAG: Tag = Tag::const_new("prod");

带有公共字段

use strong_type::StrongType;

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

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

演示类型区别

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

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

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

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

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

利用可散列性

use std::collections::HashSet;

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

let mut map = HashSet::<Tag>::new();
map.insert(Tag::new("dev"));
map.insert(Tag::new("prod"));
assert_eq!(map.len(), 2);

具有算术操作的命名整型类型

use strong_type::StrongType;

#[derive(StrongType)]
#[strong_type(auto_operators)]
struct Nanosecond(u32);

let x = Nanosecond::new(2);
let y = Nanosecond::new(3);
let z = Nanosecond::default();

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

#[derive(StrongType)]
#[strong_type(scalable)]
struct Millisecond(u32);

let x = Millisecond::new(2);

assert_eq!(x * 3, Millisecond(6));

具有逻辑操作的命名布尔类型

use strong_type::StrongType;

#[derive(StrongType)]
#[strong_type(auto_operators)]

struct IsTrue(bool);

let x = IsTrue::new(true);
let y = IsTrue::new(false);

assert_eq!(x & y, IsTrue::new(false));
assert_eq!(x | y, IsTrue::new(true));
assert_eq!(x ^ y, IsTrue::new(true));
assert_eq!(!x, IsTrue::new(false));

使用custom_display的自定义显示实现

use std::fmt::{Display, Formatter, Result};
use strong_type::StrongType;

#[derive(StrongType)]
#[strong_type(custom_display)]

struct Second(f64);

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

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

嵌套强类型

#[derive(StrongType)]
#[strong_type(auto_operators)]
struct Dollar(i32);

#[derive(StrongType)]
#[strong_type(auto_operators, underlying = i32)]
struct Cash(Dollar);

#[derive(StrongType)]
#[strong_type(underlying = i32)]
struct Coin(Cash);

注意事项

  • 当使用#[derive(StrongType)]时,特质的EqPartialEq使用impl实现。因此,StructuralEqStructuralPartialEq尚未实现,阻止了与强类型原语的模式匹配。
  • #[strong_type(scalable)]不适用于嵌套强类型。

依赖关系

~290–750KB
~18K SLoC