1 unstable release
0.1.0 | May 15, 2024 |
---|
#1687 in Rust patterns
16KB
167 lines
Perforate
Perforate generates variants of a struct to allow a struct field to be "split" from the rest of the struct as in a split borrow.
This is similar in effect to using mem::take or one of the other replacement functions, except it can be performed on fields that don't implement Default or when a suitable placeholer can't be constructed.
Usage
Perforate an owned struct on the stack.
use perforate::Perforate;
#[derive(Perforate)]
#[repr(C)]
pub struct TestStruct {
#[perforate]
one: String,
two: u64,
}
let test_struct = TestStruct{one: "one".to_string(), two: 42};
let (perforated, one) = test_struct.perforate_one();
assert_eq!(core::mem::size_of::<TestStruct>(), core::mem::size_of_val(&perforated));
assert_eq!(perforated.two, 42);
assert_eq!(one, "one");
let original = perforated.replace_perf(one);
assert_eq!(original.two, 42);
assert_eq!(original.one, "one");
Or perforate a struct in an owned box.
use perforate::Perforate;
#[derive(Perforate)]
#[repr(C)]
pub struct TestStruct {
#[perforate]
one: String,
two: u64,
}
let test_struct = Box::new(TestStruct{one: "one".to_string(), two: 42});
let (perforated_box, one) = TestStruct::boxed_perforate_one(test_struct);
assert_eq!(perforated_box.two, 42);
assert_eq!(one, "one");
let original_box = TestStruct::boxed_replace_one(perforated_box, one);
assert_eq!(original_box.two, 42);
assert_eq!(original_box.one, "one");
Caveats
If a struct has generic parameters or lifetimes that are used only by a field marked with the #[perforate]
attribute, you must add a PhantomData to your struct to prevent compile errors. In addition, you cannot perforate a field with a generic type parameter on stable
until the issue is merged.
You may access the other "unperforated" fields of the perforated struct, however the perforated version of the struct is a new type and does not have any of the trait implementations from its progenitor. This includes a custom Drop trait. So if your struct needs special cleanup behavior you must reassemble it before dropping.
Dependencies
~235–670KB
~16K SLoC