#self-referential #structs #creation #macro

yanked self-ref

Allows the creation of self-referencing structs

Uses old Rust 2015

0.1.2 Apr 21, 2016
0.1.1 Apr 21, 2016
0.1.0 Apr 21, 2016

#32 in #self-referential

MIT license

7KB
60 lines

Self-Ref Build Status

This crate exposes the macro self_referencing!, which allows the creation of structs in which fields contain references to other fields in the same struct.

This is meant to be a temporary workaround for the problem described here: https://gist.github.com/tomaka/da8c374ce407e27d5dac

This crate will be discontinued if this pattern becomes possible with safe Rust code.

Documentation

Usage

Add to your Cargo.toml:

[dependencies]
self-ref = "0.1"

Use the macro like this:

#![allow(unused_variables)]

#[macro_use]
extern crate self_ref;

struct Galaxy<'a> {
    pub name: &'a str,
}

struct StarSystem<'a> {
    pub galaxy: &'a Galaxy<'a>,
    pub name: &'a str,
}

struct Star<'a> {
    pub system: &'a StarSystem<'a>,
    pub name: &'a str,
}

struct Assets<'a> {
    pub galaxy: Galaxy<'a>,
    pub system: StarSystem<'a>,
    pub star: Star<'a>,
}

fn main() {
    let assets = self_referencing!(Assets, {
        galaxy = Galaxy { name: "Milky Way" };
        system = StarSystem { galaxy: &galaxy, name: "Solar System", };
        star = Star { system: &system, name: "Sol", };
    });
    
    assert_eq!("Milky Way", assets.galaxy.name);
    assert_eq!("Solar System", assets.system.name);
    assert_eq!("Sol", assets.star.name);
    assert_eq!(assets.system.name, assets.star.system.name);
    assert_eq!(assets.galaxy.name, assets.system.galaxy.name);
    assert_eq!(assets.galaxy.name, assets.star.system.galaxy.name);
}

Safety

You must always assign values to all of the struct's fields. If you don't, the others will be uninitialized and can (and most likely will) cause crashes.

No runtime deps