#traits #debug #serialization #const #embed #documentation #uneval-cow

build constuneval

Simple serializer to embed structs/tables as const Rust code using Debug trait

1 unstable release

0.1.0 Feb 20, 2021

#443 in Build Utils

MIT license

25KB
398 lines

constuneval

Try to serializes your data/tables to const rust code using Debug trait.

Why?

This crate was inspired by the this Github issue.

Usage

This crate can be used form your build script. It will try to serialize data/tables you provide to any file you specify. After that you can use include! to embed the generated code into your crate.

For full documentation see - https://docs.rs/constuneval

Credit

uneval and @burdges

License

MIT


lib.rs:

Simple Cow focussed serializer for generating const Rust code using Debug trait.

Usage

In general, to embed some code(tables/struct) into crate, you have to use the build script and include! macro. Inside the build script, you'll generate some code with one of the [to_file()][to_file], [to_string()][to_string] provided by constuneval, and then include the generated file, like this:

include!(concat!(env!(OUT_DIR), "/file_name.rs"));

Also this crate provides a fork of [UnevalCow] but with better serialization though Debug trait

How does it work?

To keep things simple all the formatting/serialization is done with help of Debug trait. For most types such as struct, enum, Vec, etc it works fine, but not for Deref like types like Cow as their Debug essentially deref before formatting. To address this crate also provides [UnevalCow] as a substitute to std::borrow::Cow.

Of course, we can't always directly construct the code for the desired value (more on this in the Limitations section below).

Example

use constuneval::{to_file, to_string, UnevalCow};
use std::fmt;

#[derive(Debug)]
pub struct FftDomain<F>
where
    [F]: 'static + ToOwned + fmt::Debug,
    <[F] as std::borrow::ToOwned>::Owned: fmt::Debug,
{
    pub some_table: UnevalCow<'static, [UnevalCow<'static, [F]>]>,
}

// some build time generated struct table
let fft_temp = FftDomain {
    some_table: UnevalCow::Owned(vec![
        UnevalCow::Owned(vec![1, 2, 3, 4, 5]),
        UnevalCow::Owned(vec![1, 2, 3, 4, 5]),
        UnevalCow::Owned(vec![1, 2, 3, 4, 5]),
        UnevalCow::Owned(vec![1, 2, 3, 4, 5]),
        UnevalCow::Owned(vec![1, 2, 3, 4, 5]),
        UnevalCow::Owned(vec![1, 2, 3, 4, 5]),
    ]),
};


to_file(
    std::path::Path::new("const_fft_tables.rs"),
    "FFT_TABLE",
    &fft_temp,
    Some("FftDomain<'static, i32>"),
)
.expect("Write Failed");

content of const_fft_tables.rs (after running rustfmt on it)

const FFT_TABLE: FftDomain<'static, i32> = FftDomain {
    some_table: UnevalCow::Borrowed(&[
        UnevalCow::Borrowed(&[1, 2, 3, 4, 5]),
        UnevalCow::Borrowed(&[1, 2, 3, 4, 5]),
        UnevalCow::Borrowed(&[1, 2, 3, 4, 5]),
        UnevalCow::Borrowed(&[1, 2, 3, 4, 5]),
        UnevalCow::Borrowed(&[1, 2, 3, 4, 5]),
        UnevalCow::Borrowed(&[1, 2, 3, 4, 5]),
    ]),
};

Now this file/code can be embed into crate using include! macro.

Limitations

There are some cases when constuneval will be unable to generate valid code. Namely:

  1. This serializer is intended for use with types with well implemented Debug trait. It may not work if Debug trait is producing invalid outputs.

No runtime deps