38 个版本

0.18.4 2024 年 5 月 24 日
0.18.3 2024 年 1 月 21 日
0.18.2 2023 年 12 月 26 日
0.18.0 2023 年 9 月 1 日
0.5.1 2020 年 11 月 12 日

#43Rust 模式

Download history 219303/week @ 2024-05-03 236983/week @ 2024-05-10 238206/week @ 2024-05-17 238709/week @ 2024-05-24 268979/week @ 2024-05-31 282376/week @ 2024-06-07 247855/week @ 2024-06-14 248317/week @ 2024-06-21 260791/week @ 2024-06-28 265459/week @ 2024-07-05 272117/week @ 2024-07-12 265008/week @ 2024-07-19 270692/week @ 2024-07-26 254839/week @ 2024-08-02 310462/week @ 2024-08-09 281734/week @ 2024-08-16

1,172,817 每月下载量
838 个 crate (75 直接) 中使用

MIT/Apache

34KB
246

Ouroboros

Ouroboros on Crates.IO Documentation

Rust 简单的自引用结构体生成。MIT / Apache 2.0 双授权。

虽然这个包与 no_std 兼容,但它仍然需要 alloc 包。

版本说明

  • 版本 0.18.0 现在正确拒绝编译对 with_mut 的不安全使用,但需要 Rust 1.63 或更高版本。
  • 版本 0.17.0 重新引入了类型参数支持,但需要至少 Rust 工具链的 1.60 版本。
  • 版本 0.16.0 修复了一个潜在的稳健性问题,但删除了模板参数支持。
  • 版本 0.13.0 及以后的版本包含了对导致未定义行为的额外情况的检查。
  • 版本 0.11.0 及以后的版本对 derive 宏施加了限制,早期版本允许以可能导致未定义行为的错误方式使用它们。
  • 版本 0.10.0 及以后的版本自动将每个字段装箱。这是为了防止未定义行为,但副作用是使库更容易使用。

测试位于 examples/ 文件夹中,因为它们需要在 ouroboros 之外的 crate 中,以便 self_referencing 宏能正常工作。

use ouroboros::self_referencing;

#[self_referencing]
struct MyStruct {
    int_data: i32,
    float_data: f32,
    #[borrows(int_data)]
    // the 'this lifetime is created by the #[self_referencing] macro
    // and should be used on all references marked by the #[borrows] macro
    int_reference: &'this i32,
    #[borrows(mut float_data)]
    float_reference: &'this mut f32,
}

fn main() {
    // The builder is created by the #[self_referencing] macro 
    // and is used to create the struct
    let mut my_value = MyStructBuilder {
        int_data: 42,
        float_data: 3.14,

        // Note that the name of the field in the builder 
        // is the name of the field in the struct + `_builder` 
        // ie: {field_name}_builder
        // the closure that assigns the value for the field will be passed 
        // a reference to the field(s) defined in the #[borrows] macro
	
        int_reference_builder: |int_data: &i32| int_data,
        float_reference_builder: |float_data: &mut f32| float_data,
    }.build();

    // The fields in the original struct can not be accessed directly
    // The builder creates accessor methods which are called borrow_{field_name}()

    // Prints 42
    println!("{:?}", my_value.borrow_int_data());
    // Prints 3.14
    println!("{:?}", my_value.borrow_float_reference());
    // Sets the value of float_data to 84.0
    my_value.with_mut(|fields| {
        **fields.float_reference = (**fields.int_reference as f32) * 2.0;
    });

    // We can hold on to this reference...
    let int_ref = *my_value.borrow_int_reference();
    println!("{:?}", *int_ref);
    // As long as the struct is still alive.
    drop(my_value);
    // This will cause an error!
    // println!("{:?}", *int_ref);
}

依赖关系

~0.8–1.3MB
~27K SLoC