Macro struct

Source
struct!() { /* proc-macro */ }
Expand description

Creates an instance of an anonymous struct.

Note: If two instances are created from two different r#struct! macros, they are guaranteed to belong to two distinct anonymous structs, even if they have exactly the same set of fields (both names and types). To obtain an instance with the same fields and type, you can clone an existing instance instead.

§Examples

Similar to how an instance of a normal struct is constructed, you can use this macro in the same way:

use anony::r#struct;

let address = "123 St. SW";

let o1 = r#struct! {
    name: "Alice",
    age: 28,
    address,
};

assert_eq!(o1.name, "Alice");
assert_eq!(o1.age, 28);
assert_eq!(o1.address, "123 St. SW");

// Other anonymous constructs are also allowed!
let _o2 = r#struct! {
    closure: || 3,
    future: async {
        let x = "Hello, world!".to_owned();
        std::future::ready(()).await;
        x.len()
    },
    anonymous: r#struct! {
        f1: 3.4,
        f2: Box::new("123"),
    },
};

You can move fields individually:

use anony::r#struct;

let address = "123 St. SW".to_owned();

let o1 = r#struct! {
    name: "Alice".to_owned(),
    age: 28,
    address,
};

let name = o1.name;
let age = o1.age;
let address = o1.address;

assert_eq!(name, "Alice");
assert_eq!(age, 28);
assert_eq!(address, "123 St. SW");

You can use project_ref for Pin<&_> and project_mut for Pin<&mut _>, similar to how you use the pin-project crate. The struct created by project_ref (but not project_mut) implements Clone and Copy:

use std::pin::pin;
use std::future::Future;
use std::task::Context;
use std::task::Poll;
use anony::r#struct;
use futures::task::noop_waker;

let o1 = r#struct! {
    fut: async {
        let s = "10011001001";
        s.matches("1").count()
    }
};

let o1 = pin!(o1);
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);

// Project to the `fut` field
assert_eq!(o1.project_mut().fut.poll(&mut cx), Poll::Ready(5));

§Implemented Traits

This struct implements the following traits if all of its fields also implement them:

  • All traits in std::cmp

  • Debug

    Behavior: The struct’s name is hidden; only field names and values are debugged.

  • Hash

  • Clone and Copy (the cloned instance is guaranteed to have the same type as the source)

  • Serialize (requires the serde feature)

    Behavior: The struct’s name is hidden; only field names and values are serialized. As a result, some data formats may not work, such as XML as it requires the struct’s name as a tag.

§Example Expansions

https://github.com/discreaminant2809/anony/blob/master/examples/expansions/anonymous_struct.rs