Expand description
Command line argument parsing with serde
.
This library allows parsing command line arguments into types implementing Deserialize
.
Included are all of the typical features you’d find in an command line argument parsing
library, including help generation, help customization, version support, and flexible parsing
options.
Unlike other argument parsing libraries, serde_args
uses serde
’s traits to define the
command line interface. No builder or derive interface is provided; instead, any object
implementing Deserialize
can be used. This means that you can use serde
’s own derive macros
(that you are likely already familiar with) or implement the Deserialize
trait by hand to
define your command line interface.
serde_args
defines an unambiguous deserialization format through internal Deserializer
s;
therefore it should be noted that not every command line interface can be represented using it.
Notably, optional positional parameters are not supported at all, nor are default command
values. The format defined here requires that all positional arguments (those without a -
or --
preceeding them) be required arguments, and that all other arguments be preceeded with
either a -
or --
(including compound types). See the format specification
for more details.
§Parsing Arguments
To use serde_args
for your own command line argument parsing, you must first define a type
implementing serde
’s Deserialize
trait. This can be done using serde
’s derive macro or
by implementing the trait by hand. For example, a simple program could be defined as:
use serde::Deserialize;
use std::path::PathBuf;
#[derive(Deserialize)]
#[serde(expecting = "An example program")]
struct Args {
path: PathBuf,
#[serde(alias = "f")]
force: bool,
}
fn main() {
let args: Args = match serde_args::from_env() {
Ok(args) => args,
Err(error) => {
println!("{error}");
return;
}
};
// Execute your program with `args`...
}
Command-based interfaces can be defined using enums
:
use serde::Deserialize;
use std::path::PathBuf;
#[derive(Deserialize)]
#[serde(expecting = "A command-based interface")]
#[serde(rename_all = "kebab-case")]
enum Command {
Add {
path: PathBuf,
},
Commit {
#[serde(alias = "m")]
message: Option<String>,
},
Push {
#[serde(alias = "f")]
force: bool,
},
}
fn main() {
let command: Command = match serde_args::from_env() {
Ok(command) => command,
Err(error) => {
println!("{error}");
return;
}
};
// Execute your program with `command`...
}
For simple use cases you can also use existing types that
already implement Deserialize
:
fn main() {
let value: String = match serde_args::from_env() {
Ok(value) => value,
Err(error) => {
println!("{error}");
return;
}
};
// Execute your program with `value`...
}
Note that the only way to deserialize using this crate is through from_env()
and
from_env_seed()
. No public Deserializer
is provided.
§Error Formatting
On failure, from_env()
will return an Error
. This will occur when the provided type is
incompatible with this crate (see Supported serde
Attributes
for common reasons why types are not compatible), when the user has input command line
arguments that cannot be parsed into the provided type, or when the user requests the generated
help message (either through the --help
flag or by providing no arguments). In any case, the
returned Error
implements the Display
trait and is able to be printed and displayed to
the user.
For example, a program taking a single unsigned integer value as a parameter would print an error that occurred like so:
if let Err(error) = serde_args::from_env::<usize>() {
println!("{error}");
}
To print an error that is formatted with ANSI color sequences, use the “alternate” form of
printing with the #
flag:
if let Err(error) = serde_args::from_env::<usize>() {
println!("{error:#}");
}
§Customization
serde_args
allows for customizing in the form of messages to be displayed in help output and
the displaying of version information. These are most easily customized using the
#[generate]
attribute (requires the macros
feature). This macro must be combined with
serde's
Deserialize` derive macro.
§Custom Help Messages
Descriptions for each of your fields or variants can be automatically imported from your struct
or enum’s doc comment using #[generate]
with doc_help
as a parameter:
use serde::Deserialize;
use std::path::PathBuf;
/// An example program.
#[serde_args::generate(doc_help)]
#[derive(Deserialize)]
struct Args {
/// The path to operate on.
path: PathBuf,
/// Whether the program's behavior should be forced.
#[serde(alias = "f")]
force: bool,
}
fn main() {
let args: Args = match serde_args::from_env() {
Ok(args) => args,
Err(error) => {
println!("{error}");
return;
}
};
// Execute your program with `args`...
}
§Version Information
To automatically make the version of your crate available through a --version
flag, use
#[generate]
with version
as a parameter:
use serde::Deserialize;
#[serde_args::generate(version)]
#[derive(Deserialize)]
struct Args {
foo: String,
bar: bool,
}
fn main() {
let args: Args = match serde_args::from_env() {
Ok(args) => args,
Err(error) => {
println!("{error}");
return;
}
};
// Execute your program with `args`...
}
§Customization Without Deriving
To provide these customization options without deriving, see
expecting()
Option Specification.
§Supported serde
Attributes
Nearly all serde
attributes are supported. Those that are not supported are those that
require a self-describing deserializer (the format defined by serde_args
is not
self-describing). Specifically, the following attributes will not work:
#[serde(flatten)]
#[serde(tag = "type")]
- Doesn’t work for enums, but it will work for structs.#[serde(tag = "t", content = "c")]
#[serde(untagged)]
- Not allowed on enums or on variants.#[serde(other)]
Aside from the above list, all other attributes are supported. Some attributes are especially useful for defining command line interfaces, including:
#[serde(alias)]
- Useful for defining multiple names for optional fields or command variants.#[serde(expecting)]
- Can be used to define a description for your program. Whatever is provided here will be output at the top of the generated help message.- Note that many users will want to use
#[serde_args::generate(doc_help)]
to automatically populate this message from the container’s doc comment instead.
- Note that many users will want to use
#[serde(rename_all)]
- Useful for renaming all field names or enum variants to kebab-case, which is common for command-line tools.
Modules§
- specification
- A full specification of the format defined by
serde_args
.
Structs§
- Error
- An error encountered during deserialization.
Functions§
- from_
env - Deserialize from
env::args()
. - from_
env_ seed - Deserialize from
env::args()
using a seed.
Attribute Macros§
- generate
macros
- Add on for
#[derive(Deserialize)]
to addserde_args
-specific information.