5 个版本
使用旧的 Rust 2015
0.1.6 | 2016 年 7 月 20 日 |
---|---|
0.1.4 | 2016 年 1 月 18 日 |
0.1.3 | 2015 年 12 月 1 日 |
0.1.2 | 2015 年 9 月 16 日 |
0.1.1 | 2015 年 8 月 16 日 |
在 Rust 模式 中排名 #2588
每月下载量 16,637 次
用于 168 个 软件包(直接使用 24 个)
42KB
948 行
此软件包提供了一些宏,用于推导“newtype”包装器(即只有一个元素的元组结构)的多种特质的实现。也就是说,给定一个恰好有一个字段的元组结构(例如,structBuckets(i32)
),这些宏将推导出诸如 Add
、Neg
、Index
、Deref
、From
等特质的“显然”实现。
所有这些宏都设计为与 custom_derive
软件包一起使用,尽管它们可以独立于它使用。
示例
创建一个简单的整数包装器,具有一些算术运算符
#[macro_use] extern crate custom_derive;
#[macro_use] extern crate newtype_derive;
custom_derive! {
#[derive(NewtypeFrom, NewtypeAdd, NewtypeMul(i32))]
pub struct Happy(i32);
}
// Let's add some happy little ints.
let a = Happy::from(6);
let b = Happy::from(7);
let c = (a + b) * 3;
let d: i32 = c.into();
assert_eq!(d, 39);
创建一个围绕类型的“deref 透明”包装器
#[macro_use] extern crate custom_derive;
#[macro_use] extern crate newtype_derive;
custom_derive! {
#[derive(NewtypeFrom,
NewtypeDeref, NewtypeDerefMut,
NewtypeIndex(usize), NewtypeIndexMut(usize)
)]
pub struct I32Array(Vec<i32>);
}
let mut arr = I32Array::from(vec![1, 2, 3]);
arr.push(4);
arr[2] = 5;
assert_eq!(&**arr, &[1, 2, 5, 4]);
assert_eq!(arr.len(), 4);
概述
此软件包提供宏以推导新类型结构以下特质的实现
- 二元算术运算符:加、位与、位或、位异或、除、乘、余、减、左移、右移,以及相应的 *Assign 特质。
- 一元算术运算符:负、非。
- 其他运算符:Deref、DerefMut、Index、IndexMut。
- 格式化:二进制、调试、显示、下指数、下十六进制、八进制、指针、上指数、上十六进制。
- 其他:From。
- 不稳定:One、Product、Sum、Zero(需要
std-unstable
功能)。
所有这些宏都命名为 Newtype$Trait
。
这些宏目前都不支持泛型新类型结构。
二元算术运算符
每个二元算术运算符接受几种推导形式。以下以在结构 T
上使用 Add
为例
NewtypeAdd
:implAdd<T, Output=T>forT
NewtypeAdd(&self)
:impl<'a> Add<&'a T, Output=T> for &'a T
NewtypeAdd(U)
:implAdd<U, Output=T> for T
NewtypeAdd(&self, U)
:impl<'a> Add<U, Output=T> for &'a T
NewtypeAdd(*)
: 所有四种组合T
和&T
二元算术运算符的 *Assign
变体只接受零个或一个参数。例如
NewtypeAddAssign
:implAddAssign<T> for T
NewtypeAddAssign(&Self)
:impl<'a> Add<&'a T> for &'a T
NewtypeAddAssign(U)
:implAdd<U> for T
NewtypeAddAssign(*)
: 实现T
和&T
.
在所有情况下,实现都会解包新类型(如果需要),然后将结果重新包裹在新类型中。
一元算术运算符
每个二元算术运算符都接受几种推导形式。以下以在结构体 T
上使用 Neg
为例
NewtypeNeg
:implNeg<Output=T> for T
NewtypeNeg(&self)
:impl<'a> Neg<Output=T> for &'a T
NewtypeNeg(*)
: 以上两种
在所有情况下,实现都会展开新类型,将请求转发到包装值的实现,然后重新将结果包装在新类型中。
其他操作符
NewtypeDeref
和 NewtypeDerefMut
只支持无参数形式,并实现相应的特质,使新类型结构解引用到包装值的指针。
NewtypeIndex
和 NewtypeIndexMut
必须用作 NewtypeIndex(usize)
,其中参数用于索引的类型。调用将转发到包装值的实现。
格式化
std::fmt
中的格式化特质的派生宏将转发到包装值的实现。
杂项
NewtypeFrom
实现 std::convert::From
两次:一次用于将包装类型转换为新类型,另一次用于将新类型转换为包装类型。
NewtypeProduct
和 NewtypeSum
可选地支持指定 &Self
作为参数以生成接受借用指针迭代器(例如,NewtypeSum(&Self)
)的实现。
不使用 custom_derive!
使用
尽管设计用于与 custom_derive!
一起使用,但此存储库中的所有宏都可以不使用它而使用。以下
custom_derive! {
#[derive(Copy, Clone, Debug, NewtypeFrom, NewtypeAdd, NewtypeAdd(f32))]
pub struct Meters(f32);
}
也可以写成
#[derive(Copy, Clone, Debug)]
pub struct Meters(f32);
NewtypeFrom! { () pub struct Meters(f32); }
NewtypeAdd! { () pub struct Meters(f32); }
NewtypeAdd! { (f32) pub struct Meters(f32); }
无运行时依赖项
~11KB