Skip to content

Destructure Rust structs that implement Drop.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

arturoc/derive_destructure

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Crates.io Build Status

derive_destructure

This crate allows you to destructure structs that implement Drop.

If you've ever struggled with error E0509 "cannot move out of type T, which implements the Drop trait" then this crate may be for you.

To use this crate, put this in your lib.rs or main.rs:

#[macro_use]
extern crate derive_destructure;

Then you have 2 ways to use this crate:

Option 1: #[derive(destructure)]

If you mark a struct with #[derive(destructure)], then you can destructure it using

let (field_1, field_2, ...) = my_struct.destructure();

This turns the struct into a tuple of its fields without running the struct's drop() method. You can then happily move elements out of this tuple.

Note: in Rust, a tuple of 1 element is denoted as (x,), not (x).

Option 2: #[derive(remove_trait_impls)]

If you mark your struct with #[derive(remove_trait_impls)], then you can do

let my_struct = my_struct.remove_trait_impls();

The result is a struct with the same fields, but it implements no traits (except automatically-implemented traits like Sync and Send). In particular, it doesn't implement Drop, so you can move fields out of it.

The name of the resulting struct is the original name plus the suffix WithoutTraitImpls. For example, Foo becomes FooWithoutTraitImpls. But you usually don't need to write out this name.

#[derive(remove_trait_impls)] works on enums too.

Example:

#[macro_use]
extern crate derive_destructure;

#[derive(destructure, remove_trait_impls)]
struct ImplementsDrop {
    some_str: String,
    some_int: i32
}

impl Drop for ImplementsDrop {
    fn drop(&mut self) {
        panic!("We don't want to drop this");
    }
}

fn main() {
    // Using destructure():
    let x = ImplementsDrop {
        some_str: "foo".to_owned(),
        some_int: 4
    };
    let (some_str, some_int) = x.destructure();
    // x's drop() method never gets called

    // Using remove_trait_impls():
    let x = ImplementsDrop {
        some_str: "foo".to_owned(),
        some_int: 4
    };
    let x = x.remove_trait_impls();
    // this x doesn't implement drop,
    // so we can move fields out of it
    drop(x.some_str);
    println!("{}", x.some_int);
}

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Destructure Rust structs that implement Drop.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%