#newtype #macro #wrapper #derive #custom-derive

no-std newtype_derive

此软件包提供了用于推导新类型结构的常见特质的宏。

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

Download history 5294/week @ 2024-03-04 5241/week @ 2024-03-11 4341/week @ 2024-03-18 5348/week @ 2024-03-25 5228/week @ 2024-04-01 4879/week @ 2024-04-08 4653/week @ 2024-04-15 5634/week @ 2024-04-22 4941/week @ 2024-04-29 4196/week @ 2024-05-06 5855/week @ 2024-05-13 4247/week @ 2024-05-20 4142/week @ 2024-05-27 4135/week @ 2024-06-03 4427/week @ 2024-06-10 3682/week @ 2024-06-17

每月下载量 16,637
用于 168 软件包(直接使用 24 个)

MIT/Apache

42KB
948

此软件包提供了一些宏,用于推导“newtype”包装器(即只有一个元素的元组结构)的多种特质的实现。也就是说,给定一个恰好有一个字段的元组结构(例如,structBuckets(i32)),这些宏将推导出诸如 AddNegIndexDerefFrom 等特质的“显然”实现。

所有这些宏都设计为与 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 为例

  • NewtypeAddimplAdd<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(*): 以上两种

在所有情况下,实现都会展开新类型,将请求转发到包装值的实现,然后重新将结果包装在新类型中。

其他操作符

NewtypeDerefNewtypeDerefMut 只支持无参数形式,并实现相应的特质,使新类型结构解引用到包装值的指针。

NewtypeIndexNewtypeIndexMut 必须用作 NewtypeIndex(usize),其中参数用于索引的类型。调用将转发到包装值的实现。

格式化

std::fmt 中的格式化特质的派生宏将转发到包装值的实现。

杂项

NewtypeFrom 实现 std::convert::From 两次:一次用于将包装类型转换为新类型,另一次用于将新类型转换为包装类型。

NewtypeProductNewtypeSum 可选地支持指定 &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