diff --git a/Cargo.lock b/Cargo.lock index 97d9105..e6358f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,187 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "anyhow" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + [[package]] name = "parsing" version = "0.1.0" +dependencies = [ + "anyhow", + "pest", + "pest_derive", +] + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +dependencies = [ + "maplit", + "pest", + "sha-1", +] + +[[package]] +name = "proc-macro2" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "sha-1" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "syn" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" diff --git a/Cargo.toml b/Cargo.toml index e572f76..239098a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,6 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +pest = "2.1.3" +pest_derive = "2.1.0" +anyhow = "1.0.32" diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/grammar.rs b/src/grammar.rs new file mode 100644 index 0000000..7d1b246 --- /dev/null +++ b/src/grammar.rs @@ -0,0 +1,48 @@ +use crate::nested_type::Type; +use ::anyhow::Result; + +use pest::{iterators::Pair, Parser}; + +#[derive(Parser)] +#[grammar = "grammar/type.pest"] +pub struct TypeParser; + +fn parse_type_array(pair: Pair) -> Result>> { + let mut inner_rules = pair.into_inner(); + let types = inner_rules.map( |pair| parse_type_object(pair).unwrap_or_default().into()).collect(); + Ok(types) +} + +fn parse_type_object(pair: Pair) -> Result { + // verify that it's a type object ? + let mut inner_rules = pair.into_inner(); + let repr = inner_rules + .next() + .expect("Malformed parsing") + .as_str(); + let subtypes = match inner_rules.next() { + Some(a) => parse_type_array(a)?, + None => vec![] + }; + Ok(Type { + repr: repr.into(), + subtypes: subtypes, + }) +} + +fn parse_nested_type(pair: Pair) -> Result{ + match pair.as_rule() { + Rule::type_object => parse_type_object(pair), + _ => unreachable!(), + } +} + +pub fn parse(s: String) -> Result { + let t = match TypeParser::parse(Rule::nested_type, s.as_str())?.next() { + Some(v) => v, + //TODO: return a custom error + None => panic!("nothing have been parsed"), + }; + + Ok(parse_nested_type(t)?) +} diff --git a/src/grammar/type.pest b/src/grammar/type.pest new file mode 100644 index 0000000..d060d30 --- /dev/null +++ b/src/grammar/type.pest @@ -0,0 +1,7 @@ +nested_type = _{SOI ~ type_object ~ EOI} + +type_object = { type_name ~ (type_array)? } +type_array = { "[" ~ type_object ~ ("," ~ type_object)* ~ "]" } + +type_name = { ( ASCII_ALPHA | ASCII_DIGIT )+ } +WHITESPACE = _{ " " } diff --git a/src/main.rs b/src/main.rs index e7a11a9..b1f1f16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,36 @@ -fn main() { - println!("Hello, world!"); +mod grammar; +mod nested_type; + +use grammar::parse; +use nested_type::Type; +use ::std::env; + +use ::anyhow::Result; + +#[macro_use] +extern crate pest_derive; +extern crate pest; + +fn main() -> Result<()> { + let a = Type { + repr: "NestedType".into(), + ..Default::default() + }; + let b = Type { + repr: "MainType".into(), + subtypes: vec![a.clone().into(), a.clone().into()], + }; + println!("this is my python type : {}", b.to_python()); + println!("this is my cpp type : {}", b.to_cpp()); + + let nested_type = match env::args().nth(1) { + Some(t) => t, + None => "Dict[str, int]".into(), + }; + println!( + "I parse an awesome nested_type : {}", + parse(nested_type.into())?.to_python() + ); + + Ok(()) } diff --git a/src/nested_type.rs b/src/nested_type.rs new file mode 100644 index 0000000..e171744 --- /dev/null +++ b/src/nested_type.rs @@ -0,0 +1,47 @@ +#[derive(Debug, Default, Clone)] +pub struct Type { + pub subtypes: Vec>, + pub repr: String, +} + +impl Type { + + /// A function to print a Type struct as a python String + /// + /// # Examples + /// + /// Creating a simple type and converting it into a python type String + /// ``` + /// let my_type = Type{repr: "Type".into(), ..Default::default()}; + /// my_type.to_python() + /// ``` + pub fn to_python(&self) -> String { + match self.subtypes.len() { + 0 => format!("{}", self.repr), + _ => format!( + "{}[{}]", + self.repr, + self.subtypes + .iter() + .map(|s| s.to_python()) + .collect::>() + .join(", ") + ), + } + } + + pub fn to_cpp(&self) -> String { + match self.subtypes.len() { + 0 => format!("{}", self.repr), + _ => format!( + "{}<{}>", + self.repr, + self.subtypes + .iter() + .map(|s| s.to_python()) + .collect::>() + .join(", ") + ), + } + } +}