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