13 个版本
| 0.2.3 | 2024 年 2 月 28 日 |
|---|---|
| 0.2.1 | 2023 年 9 月 22 日 |
| 0.1.0 | 2023 年 1 月 10 日 |
| 0.0.7 | 2022 年 6 月 29 日 |
| 0.0.3 | 2021 年 7 月 20 日 |
在 Rust 模式 中排名 1654
每月下载量 30
用于 bsalib
105KB
1.5K SLoC
newtype-derive-2018
newtype-derive 的现代分支。
此软件包提供用于为新类型结构体推导常见特征的宏。
所有这些宏都旨在与 macro-attr-2018 软件包一起使用,尽管它们可以独立使用。
lib.rs:
此软件包提供几个宏,用于为 "newtype" 包装器(即仅有一个非零大小元素的元组结构)推导各种特征的实现。也就是说,给定一个只有一个字段(例如 struct Buckets(i32))的元组结构(或一个字段后跟任意数量的零大小字段),这些宏将推导出 "显然" 的特征实现,如 Add、Neg、Index、Deref 等等。
所有这些宏都旨在与 macro-attr-2018 软件包一起使用,尽管它们可以独立使用。
示例
创建一个简单的整数包装器,具有一些算术运算符
use macro_attr_2018::macro_attr;
use newtype_derive_2018::*;
macro_attr! {
#[derive(NewtypeAdd!, NewtypeMul!(i32))]
pub struct Happy(pub i32);
}
// Let's add some happy little ints.
let a = Happy(6);
let b = Happy(7);
let c = (a + b) * 3;
let d: i32 = c.0;
assert_eq!(d, 39);
创建一个围绕智能指针的 "deref 透明" 包装器
use macro_attr_2018::macro_attr;
use newtype_derive_2018::*;
macro_attr! {
#[derive(NewtypeDeref!, NewtypeDerefMut!)]
pub struct I32Array(Vec<i32>);
}
let arr = I32Array(vec![1, 2, 3]);
assert_eq!(&*arr, &[1, 2, 3]);
概述
此软件包提供宏,用于为新类型结构体推导以下特征的实现
- 二元算术运算符:
Add、BitAnd、BitOr、BitXor、Div、Mul、Rem、Sub、Shl、Shr,以及相应的*Assign特征。 - 一元算术运算符:
Neg、Not。 - 其他运算符:
Deref、DerefMut、Index、IndexMut。 - 格式化:
Binary,Debug,Display,LowerExp,LowerHex,Octal,Pointer,UpperExp,UpperHex。
所有这些宏都命名为 Newtype$Trait。
所有这些宏都支持泛型新类型结构体。默认情况下,不生成泛型参数的界限。要添加约束,请在宏参数末尾添加where子句。例如
macro_attr! {
#[derive(NewtypeAdd!(where T: Add<Output=T>))]
#[derive(NewtypeAdd!(&self, &Self where T: Add<Output=T>))]
#[derive(NewtypeSub!(* where T: Sub<Output=T>))]
pub struct Dummy<T: Copy>(T);
}
二进制算术运算符
每个二进制算术运算符都接受几种派生形式。以在结构体 T 上使用 Add 为例
| 属性 | 生成的实现 |
|---|---|
NewtypeAdd |
impl Add<T, Output=T> for T |
NewtypeAdd(&self) |
impl<'a> Add<T, Output=T> for &'a T |
NewtypeAdd(U) |
impl Add<U, Output=T> for T |
NewtypeAdd(&self,U) |
impl<'a> Add<U, Output=T> for &'a T |
NewtypeAdd(*) |
T 和 &T 的所有四种组合 |
*Assign 变体只接受零个或一个参数。例如
| 属性 | 生成的实现 |
|---|---|
NewtypeAddAssign |
impl AddAssign<T> for T |
NewtypeAddAssign(U) |
impl Add<U> for T |
NewtypeAddAssign(*) |
为 T 和 &T 实现。 |
在所有情况下,实现都会展开新类型(如果需要),转发到封装值的实现,然后在新类型中重新封装结果。
一元算术运算符
每个二进制算术运算符都接受几种派生形式。以在结构体 T 上使用 Neg 为例
| 属性 | 生成的实现 |
|---|---|
NewtypeNeg |
impl Neg<Output=T> for T |
NewtypeNeg(&self) |
impl<'a> Neg<Output=T> for &'a T |
NewtypeNeg(*) |
以上两种 |
在所有情况下,实现都会展开新类型,转发到封装值的实现,然后在新类型中重新封装结果。
其他运算符
NewtypeDeref 和 NewtypeDerefMut 只支持无参数形式。调用会转发到封装值的实现。
NewtypeIndex 和 NewtypeIndexMut 必须用作 NewtypeIndex(usize),其中参数是用于索引的类型。调用会转发到封装值的实现。
格式化
std::fmt 中的格式化特质的派生宏会转发到封装值的实现。
不使用 macro_attr! 使用
尽管设计用于与 macro_attr! 一起使用,但此包中的所有宏都可以不使用它来使用。以下
use macro_attr_2018::macro_attr;
use newtype_derive_2018::*;
macro_attr! {
#[derive(Copy, Clone, Debug, NewtypeAdd!, NewtypeAdd!(f32))]
pub struct Meters(pub f32);
}
#
也可以写成
use newtype_derive_2018::*;
#[derive(Copy, Clone, Debug)]
pub struct Meters(pub f32);
NewtypeAdd! { () pub struct Meters(pub f32); }
NewtypeAdd! { (f32) pub struct Meters(pub f32); }
#
依赖关系
~48KB