implement getopt parser - first try
This commit is contained in:
parent
c548fa250a
commit
845901f41d
|
@ -0,0 +1,109 @@
|
||||||
|
use crate::api::schema::*;
|
||||||
|
|
||||||
|
use failure::*;
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum RawArgument {
|
||||||
|
Separator,
|
||||||
|
Argument { value: String },
|
||||||
|
Option { name: String, value: Option<String> },
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_argument(arg: &str) -> RawArgument {
|
||||||
|
|
||||||
|
let chars: Vec<char> = arg.chars().collect();
|
||||||
|
|
||||||
|
let length = chars.len();
|
||||||
|
|
||||||
|
if length >= 2 && chars[0] == '-' && chars[1] == '-' {
|
||||||
|
|
||||||
|
if length == 2 { return RawArgument::Separator; }
|
||||||
|
|
||||||
|
for start in 2..length {
|
||||||
|
if chars[start] == '=' {
|
||||||
|
let name: String = chars[2..start].iter().collect();
|
||||||
|
let value: String = chars[start+1..length].iter().collect();
|
||||||
|
return RawArgument::Option { name, value: Some(value) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let name: String = chars[2..].iter().collect();
|
||||||
|
return RawArgument::Option { name: name, value: None }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RawArgument::Argument { value: arg.to_string() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_arguments(args: &Vec<String>, schema: &Schema) -> Value {
|
||||||
|
|
||||||
|
println!("ARGS {:?}", args);
|
||||||
|
|
||||||
|
let properties = match schema {
|
||||||
|
Schema::Object(ObjectSchema { properties, .. }) => properties,
|
||||||
|
_ => panic!("Expected Object Schema."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut data: Vec<(String, String)> = vec![];
|
||||||
|
let mut rest: Vec<String> = vec![];
|
||||||
|
|
||||||
|
let mut pos = 0;
|
||||||
|
|
||||||
|
let mut skip = false;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if skip {
|
||||||
|
rest.push(args[pos].clone());
|
||||||
|
} else {
|
||||||
|
match parse_argument(&args[pos]) {
|
||||||
|
RawArgument::Separator => {
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
RawArgument::Option { name, value } => {
|
||||||
|
match value {
|
||||||
|
None => {
|
||||||
|
if pos < args.len() {
|
||||||
|
if let RawArgument::Argument { value: next } = parse_argument(&args[pos+1]) {
|
||||||
|
pos += 1;
|
||||||
|
data.push((name, next));
|
||||||
|
} else {
|
||||||
|
if let Some(Schema::Boolean(jss_boolean)) = properties.get::<str>(&name) {
|
||||||
|
if let Some(default) = jss_boolean.default {
|
||||||
|
if default == false {
|
||||||
|
data.push((name, "true".to_string()));
|
||||||
|
} else {
|
||||||
|
panic!("negative Bool requires argument");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data.push((name, "true".to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(v) => {
|
||||||
|
data.push((name, v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RawArgument::Argument { value } => {
|
||||||
|
rest.push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 1;
|
||||||
|
if pos >= args.len() { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Options {:?}", data);
|
||||||
|
println!("REST {:?}", rest);
|
||||||
|
|
||||||
|
match parse_parameter_strings(&data, schema, true) {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(perror) => {
|
||||||
|
panic!(format!("{:?}", perror));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ pub mod api {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod getopts;
|
||||||
|
|
||||||
pub mod api3;
|
pub mod api3;
|
||||||
|
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -1,6 +1,13 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate apitest;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use apitest::api::schema::*;
|
||||||
use apitest::api::router::*;
|
use apitest::api::router::*;
|
||||||
use apitest::api::config::*;
|
use apitest::api::config::*;
|
||||||
use apitest::api::server::*;
|
use apitest::api::server::*;
|
||||||
|
use apitest::getopts;
|
||||||
|
|
||||||
//use failure::*;
|
//use failure::*;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
@ -13,6 +20,13 @@ use hyper;
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Fast Static Type Definitions 1");
|
println!("Fast Static Type Definitions 1");
|
||||||
|
|
||||||
|
let schema = parameter!{
|
||||||
|
name => ApiString!{ optional => false }
|
||||||
|
};
|
||||||
|
|
||||||
|
let args: Vec<String> = std::env::args().skip(1).collect();
|
||||||
|
getopts::parse_arguments(&args, &schema);
|
||||||
|
|
||||||
let addr = ([127, 0, 0, 1], 8007).into();
|
let addr = ([127, 0, 0, 1], 8007).into();
|
||||||
|
|
||||||
lazy_static!{
|
lazy_static!{
|
||||||
|
|
Loading…
Reference in New Issue