1 unstable release

0.1.0 Jan 24, 2024

#978 in Command-line interface


1.5K SLoC

Create a "functional" command line argument parser in minutes.

See docs.rs for more details.


Fcla lets you create a "functional" command line argument parser in minutes. Simply start by creating an Args type, then annotate your types with #[derive(FromArgs)], before finally using the parse_cla function to parse your arguments. Ideal for small projects and rapid development.


The following example shows off most of what fcla can do:

use fcla::FromArgs;

#[derive(Debug, FromArgs)]
enum Args {
    Simple { first: Box<str>, second: i32 },
    Nested { nested: Nested },
    Optional { optional: Option<Box<str>> },
    Sequence { sequence: Vec<i32> },
    Mapping { map: std::collections::HashMap<i32, Box<str>> },
    Range { range: fcla::RangeDynamic<i32> },
    Custom { tree: Tree<Box<str>> },
    Complex { sequence: Vec<Tree<Box<str>>> },

#[derive(Debug, FromArgs)]
struct Nested {
    small: u8,
    medium: u16,
    large: u32,

#[derive(Debug, FromArgs)]
enum Tree<T> {
    Branch { left: Box<Self>, right: Box<Self> },

fn main() -> fcla::MainResult<()> {
    let args = fcla::parse_cla::<Args>()?.args;
    println!("{:?}", args);

You can run it with the following arguments:

  • Simple 'hello world' -1
  • Nested 128 32768 2147483648
  • Optional , word
  • Optional .
  • Sequence , 1 , -1 , 1E3 , -0.1E4 .
  • Mapping , 4 four , 3 three , 2 two , 1 one .
  • Range ,, 0 10
  • Range .,= 10
  • Custom Branch Branch Root hello Root world Branch Root from Branch Root fcla Root .
  • Complex , Branch Root nested Root types , Root example .


Fcla's grammar can be broken into four main parts.


Derived structs are parsed by parsing their fields in the order that they're declared in.

Derived enums are parsed by matching the first argument against the enum's variant names and then parsing the rest of the arguments into the corresponding variant struct.


Collections are parsed as a sequence of Option<T>s with zero or more Somes terminated by a None. Some is parsed as , and None is parsed as .. Lists and sets are composed of Ts whilst mappings are composed of [KeyValue<K, V>].

See the Args::as_iter method for more details.


Numbers are parsed using the same grammar as floats FromStr implementation but with the removal of the infinity and NaN cases. This means that 0.1e1 will successfully parse into a [u32].

See the [num] module for more details.


Bespoke types (such as IpAddr) are parsed according to some external grammar (for standard library types this is usually their FromStr implementations).


~28K SLoC