Skip to main content

concat_flags

Function concat_flags 

Source
pub const fn concat_flags<const N: usize>(
    groups: &[&[&'static Flag<'static>]],
) -> [&'static Flag<'static>; N]
Expand description

Join groups of flag tables into one, at compile time.

This is how #[usage(flatten)] stays free. A flattened struct’s flags have to appear in the parent’s own table, and the parent’s macro expansion cannot see them — it has only a type. But it can name that type’s CommandArgs::COMMAND, and a const fn can read through it, so the two lists become one static array before the program runs. The parser then walks a single flat slice, exactly as it does for a command that declared everything itself: flatten costs nothing at run time.

Groups are laid out in the order given, which is what lets a flattened group sit between two of the parent’s own declarations — necessary for positional arguments, where order is the meaning.

N must be table_len of the same groups. It cannot be inferred, and a wrong one fails to compile rather than leaving the difference filled with padding.

use usage_argv::{concat_flags, table_len, Flag};

static FORCE: Flag = Flag { name: "force", longs: &["force"], ..Flag::BOOL };
static QUIET: Flag = Flag { name: "quiet", longs: &["quiet"], ..Flag::BOOL };
static SHARED: &[&Flag] = &[&QUIET];

const GROUPS: &[&[&Flag]] = &[&[&FORCE], SHARED];
static FLAGS: [&Flag; table_len(GROUPS)] = concat_flags(GROUPS);

assert_eq!(FLAGS.iter().map(|f| f.name).collect::<Vec<_>>(), ["force", "quiet"]);