paw_structopt/
lib.rs

1//! Structopt adapter for the [Paw crate].
2//!
3//! [Paw crate]: https://docs.rs/paw
4//!
5//! ## Examples
6//! ```
7//! use std::io::prelude::*;
8//! use std::net::TcpListener;
9//!
10//! #[derive(paw_structopt::StructOpt, structopt::StructOpt)]
11//! struct Args {
12//!     /// Port to listen on.
13//!     #[structopt(short = "p", long = "port", env = "PORT", default_value = "8080")]
14//!     port: u16,
15//!     /// Address to listen on.
16//!     #[structopt(short = "a", long = "address", default_value = "127.0.0.1")]
17//!     address: String,
18//! }
19//!
20//! #[paw::main]
21//! fn main(args: Args) -> Result<(), std::io::Error> {
22//!     let listener = TcpListener::bind((args.address.as_str(), args.port))?;
23//!     println!("listening on {}", listener.local_addr()?);
24//!     for stream in listener.incoming() {
25//!         stream?.write(b"hello world!")?;
26//!     }
27//!     Ok(())
28//! }
29//! ```
30
31#![recursion_limit = "512"]
32#![warn(missing_debug_implementations, nonstandard_style, rust_2018_idioms)]
33
34extern crate proc_macro;
35
36use proc_macro::TokenStream;
37use quote::quote;
38use syn::{parse_macro_input, DeriveInput};
39
40#[proc_macro_derive(StructOpt)]
41pub fn structopt(input: TokenStream) -> TokenStream {
42    let input = parse_macro_input!(input as DeriveInput);
43    let name = &input.ident;
44
45    let result = quote! {
46        impl paw::ParseArgs for #name {
47            /// Error type.
48            type Error = std::io::Error;
49
50            /// Try to parse an input to a type.
51            fn parse_args() -> Result<Self, Self::Error> {
52                Ok(<#name as structopt::StructOpt>::from_args())
53            }
54        }
55    };
56
57    result.into()
58}