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}