Constdef on steroids: need nested things? I gotcha!

Published on Sep 29, 2021

Get the source code here↗, get the crate here↗ and read the docs here↗

The missing piece(s)

When the Constdef macro, as a part of the derived crate was released – there was a major drawback: tuples, nested arrays and nested tuples weren’t supported.

That was majorly because I didn’t need them at the time, but from the discussion on a Reddit post – it was clear that the community needs these things. Also, one user asked for supporting type paths for primitives, which the macro didn’t support. So, let’s change the reality!

Constdef gets steroids

With the latest release of the derived crate (0.4.2) – if you have a nested life – I gotcha! You can now do all sorts of crazy things like:

use derived::Constdef;

#[derive(Constdef)]
pub struct Constable {
    x: u8,
    boolean: bool,
    integer: i32,
    small_float: core::primitive::f32,
    big_float: std::primitive::f64,
    // arrays? check!
    num_array: [u8; 10],
    bool_array: [bool; 20],
    float_array: [f32; 30],
    // tuples? check!
    tuple: (u8, u16),
    // nested tuples? check!
    nested_tuple: ((u8, u8), u16),
    // nested arrays? check!
    nested_array: [[f32; 10]; 10],
    // tuples nested in arrays? check!
    nested_tuple_in_array: [(u8, u8); 10],
    // arrays nested in tuples? check!
    nested_array_in_tuple: (u8, [u8; 10]),
}

const CONSTABLE: Constable = Constable::default();

This means that all these tests will now compile and pass; yeah!

assert_eq!(CONSTABLE.x, 0);
assert!(!CONSTABLE.boolean);
assert_eq!(CONSTABLE.integer, 0);
assert_eq!(CONSTABLE.num_array, [0; 10]);
assert_eq!(CONSTABLE.bool_array, [false; 20]);
assert_eq!(CONSTABLE.float_array, [0.0; 30]);
assert_eq!(CONSTABLE.small_float, 0.0);
assert_eq!(CONSTABLE.big_float, 0.0);
assert_eq!(CONSTABLE.tuple, (0, 0));
assert_eq!(CONSTABLE.nested_tuple, ((0, 0), 0));
assert_eq!(CONSTABLE.nested_array, [[0.0; 10]; 10]);
assert_eq!(CONSTABLE.nested_tuple_in_array, [(0, 0); 10]);
assert_eq!(CONSTABLE.nested_array_in_tuple, (0, [0; 10]));

Behind the scenes

Try nesting the structures above even more and see how they all work beautifully! Like you can guess, the solution here was to simply recurse on every field type, climbing up the AST and substituting the requisite values, which may need further recursion for nested types. With these additions, the Constdef macro now supports most primitive types! If you bump into any issues, don’t hesitate to drop by an issue here!