#projection #proc-macro #pin #cell #project

no-std projecture

无需 proc macros 的简单任意类型投影

4 个版本

0.0.4 2022年10月5日
0.0.3 2022年7月15日
0.0.2 2022年7月4日
0.0.1 2022年6月15日

#1100Rust 模式

MIT 许可证

77KB
1.5K SLoC

Projecture

目前处于概念验证阶段,并且内部使用大量尚未经过实战考验的不安全代码,因此请在使用时自行承担风险。如果您熟悉不安全 Rust,我将非常感激您进行稳定性审查。

允许执行几乎任意的类型投影。与其他执行类似功能的 crate 相比,它更加通用,无需程序宏,并且不对目标结构施加额外的要求,如果目标结构位于外部 crate 中,则该 crate 不必明确添加对这种投影的支持(pin 投影是例外)。

尽管目前这个 crate 还不支持枚举,但将来会添加。

目前可以执行以下类型的投影:

  • 解构投影(类似于常规 let <pattern>,但也支持解引用模式,并且当结构体实现了 Drop(只是没有被调用)时也能工作。
    注意:由于声明宏的限制,目前未提及的字段将被泄露。
  • 引用投影(类似于 let <pattern> 中的 match 语法,但也支持解引用模式)
  • Pin 投影
  • Cell 投影
  • MaybeUninit 投影
  • Atomic(来自 atomic crate)投影
  • Option 投影(与其他类型的投影一起工作)
  • RefCell 保护投影
  • 原始指针投影(*const T*mut TNonNull<T>

还增加了两种可投影指针类型

  • generic::GenericPointer - 允许编写泛型引用类型的代码。
  • OwningRef - 语义上拥有数据的引用(有时在各种提案中称为 &own T)。在nightly版本(带有 nightly 功能)中,它允许你创建接受 Self 值的对象安全特例。

在可能的情况下,投影还可以通过一个 Deref 来进行(包括通过 DerefOwned 来按值解引用)。

以下是你可以做什么的概述,有关更多用法详情,请查看 project! 宏。

#    use std::cell::Cell;
#    use std::marker::PhantomPinned;
#    use std::pin::Pin;
#    use std::rc::Rc;
#    use atomic::Atomic;
#    use projecture::project;
#    use projecture::pin_projectable;
    struct Foo {
        a: Bar,
        b: Rc<Cell<Bar>>,
        c: Pin<Box<Bar>>,
        d: Atomic<Bar>,
    }

    struct Bar(usize,PhantomPinned);
    // needed only for pin projections
    pin_projectable!(Bar);

    fn test(arg: &Foo) {
        project!(
        let Foo {
            a: Bar (e, ..),
            b: *Bar{ 0: cell },
            c: *Bar (_, f) ,
            d: Bar(atomic, ..),
        } = arg);
        let _: &usize = e;
        let _: &Cell<usize> = cell;
        let _: Pin<& PhantomPinned> = f;
        let _: &Atomic<usize> = atomic;

        let _: &usize = project!(arg -> a -> 0);
        let _: &Cell<usize> = project!(arg -> b -> 0);
        let _: Pin<& PhantomPinned> = project!(arg -> c -> 1);
        let _: &Atomic<usize> = project!(arg -> d -> 0);
    }

此外,还允许依赖的crate通过特例定义自己的投影。例如,查看 atomic 模块中透明字段包装器的投影或 Pin 在自定义引用类型上的投影。

MSRV: 1.54
许可协议:MIT

依赖项