Crate cconst [] [src]

Build-time evaluated expressions

cconst allows defining constants at build time of any type that implements the Copy trait. Values are generated through build.rs:

// build.rs
#[macro_use]
extern crate cconst;

use std::net::Ipv4Addr;

let mut cs = CopyConsts::new();
cs.add_const("default_ns", "::std::net::Ipv4Addr", {
    Ipv4Addr::new(8, 8, 8, 8)
});
cs.write_code().unwrap();

Once set up, they can be included using the cconst! macro:

// main.rs
#[macro_use]
extern crate cconst;

include!(cconst!(default_ns));

fn main() {
    println!("default_ns: {:?}", default_ns());
}

Internals

cconst works by serializing the value defined in build.rs into byte-slice literals and including those where applicable. The example above results in roughly the following generated code:

#[inline]
fn default_ns() -> &'static ::std::net::Ipv4Addr {
    const BUF: &[u8] = &[0x08, 0x08, 0x08, 0x08, ];
    unsafe { &*(BUF.as_ptr() as *const ::std::net::Ipv4Addr) }
}

Calling default_ns() should result in an inlined pointer cast and little, if any overhead.

Caveats

Due to the nature of the code generation used, the type supplied to the add_const!-macro should be fully qualified, i.e. start with a ::. If not, it must be visible at the include! call site.

While Copy indicates that the type can freely be copied, if any resources are held by the type outside of what the compiler knows, the type cannot be compile generated.

Types that have the same names but are different will result in undefined behaviour with possibly catastrophic results. This will most likely occur when the build_dependencies and dependencies versions of a required crate differ.

TODO

  • [ ] #[no_std] support

Macros

add_const

Creates a constant for inclusion using cconst!.

cconst

Imports a stored constant

Structs

CopyConsts

Manage build.rs constructed constants