molt_argparse/
lib.rs

1//! Generates [molt](https://docs.rs/molt) argument parsers.
2//!
3//! Usage:
4//! ```no_run
5//! # struct NetlistDatabase {}
6//! use molt_argparse::molt_argparse;
7//!
8//! #[molt_argparse("{netlist} port_pin_list -period -name -comment:_ignored_comment -add")]
9//! fn sdc_create_clock(
10//!     netlist: &mut NetlistDatabase,
11//!     port_pin_list: Vec<i32>, period: f32, name: String, _ignored_comment: Option<String>, add: bool
12//! ) -> i32 {
13//!     port_pin_list.len() as i32
14//! }
15//! ```
16//!
17//! Tips:
18//! 
19//! * Braces enclosed parameter indicates the context to parse: `{netlist}`. There can be at most 1 such declaration, and it must be the first in declarations (but not necessarily in func arglist).
20//! * Identifiers indicate the corresponding function arguments: `port_pin_list`, in the order that they would appear.
21//! * Dash-started ones indicate key-value arguments `-period`, with option to rename it: `-comment:_ignored_comment`. If the value type is bool, it become a presence-or-not flag with no value followed.
22//! * All types must be compatible with molt's Value parsing/unparsing mechanism. The floating-type, integer-type, and boolean type are processed through corresponding `molt::as_*`, and all other types go through `molt::as_other`. `Vec<xx>` types are automatically parsed in a way like `MoltList`.
23//! * If any item is declared as `Option<SomeType>` in the function arguments, it would become optional. If not so, it is by default mandatory.
24//! * The return value definition can be any plain type or vector type, or `Option<>` types with None indicating error. There's no way to specify error status yet -- it is recommended to use some *last_error* mechanism.
25
26pub use molt_argparse_procmacro::molt_argparse;
27use molt_ng::Value;
28use std::str::FromStr;
29use std::fmt::{Display, self};
30
31/// the wrapper of a vector type.
32/// used for generic types implementing `FromStr` and `Display`.
33#[derive(Debug)]
34pub struct WrapVec<T>(pub Vec<T>);
35
36impl<T: FromStr> FromStr for WrapVec<T> {
37    type Err = <T as FromStr>::Err;
38    
39    fn from_str(s: &str) -> Result<Self, Self::Err> {
40        // suboptimal, but doesn't matter here.
41        // in the future, we hope molt will export more utilities
42        // from tokenizer and list parser.
43        Ok(WrapVec(
44            Value::from(s).to_list().unwrap().into_iter()
45                .map(|v| T::from_str(v.as_str()))
46                .collect::<Result<Vec<T>, Self::Err>>()?))
47    }
48}
49
50impl<T: Display> Display for WrapVec<T> {
51    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
52        // suboptimal, but doesn't matter here.
53        // in the future, we hope molt will export more utilities
54        // from tokenizer and list parser.
55        write!(f, "{}", Value::from(
56            self.0.iter().map(|v| Value::from(format!("{}", v)))
57                .collect::<Vec<Value>>()).as_str())
58    }
59}