From b2c59e2a7f66495723fd53f0d70fb34470448a75 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio <jorge@japaric.io> Date: Tue, 18 Jul 2017 16:49:30 -0500 Subject: [PATCH] more typed: use Path / Ty instead of just "Tokens" --- src/check.rs | 25 +++++++++++++------------ src/lib.rs | 11 ++++++----- src/parse.rs | 16 ++++------------ src/util.rs | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 src/util.rs diff --git a/src/check.rs b/src/check.rs index 6988783..ea0b55f 100644 --- a/src/check.rs +++ b/src/check.rs @@ -1,15 +1,14 @@ use std::collections::HashMap; -use quote::Tokens; -use syn::Ident; +use syn::{Ident, Path}; use error::*; -use {Idents, Statics}; +use {util, Idents, Statics}; pub type Tasks = HashMap<Ident, Task>; pub struct App { - pub device: Tokens, + pub device: Path, pub idle: Idle, pub init: Init, pub resources: Statics, @@ -18,12 +17,12 @@ pub struct App { pub struct Idle { pub locals: Statics, - pub path: Tokens, + pub path: Path, pub resources: Idents, } pub struct Init { - pub path: Tokens, + pub path: Path, } pub struct Task { @@ -74,7 +73,7 @@ fn idle(idle: Option<::Idle>) -> Result<Idle> { } else { Idle { locals: Statics::new(), - path: quote!(idle), + path: util::mk_path("idle"), resources: Idents::new(), } }) @@ -91,21 +90,23 @@ fn init(init: Option<::Init>) -> Result<Init> { bail!("empty `init` field. It should be removed."); } } else { - Init { path: quote!(init) } + Init { + path: util::mk_path("init"), + } }) } -fn path(default: &str, path: Option<Tokens>) -> Result<Tokens> { +fn path(default: &str, path: Option<Path>) -> Result<Path> { Ok(if let Some(path) = path { ensure!( - path.as_str() != default, + path.segments.len() == 1 && + path.segments[0].ident.as_ref() != default, "this is the default value. It should be omitted." ); path } else { - let default = Ident::new(default); - quote!(#default) + util::mk_path(default) }) } diff --git a/src/lib.rs b/src/lib.rs index f010d68..4abe151 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,11 +10,12 @@ pub mod check; pub mod error; mod parse; +mod util; use std::collections::{HashMap, HashSet}; use quote::Tokens; -use syn::Ident; +use syn::{Ident, Path, Ty}; use error::*; @@ -26,7 +27,7 @@ pub type Tasks = HashMap<Ident, Task>; #[derive(Debug)] pub struct App { - pub device: Tokens, + pub device: Path, pub idle: Option<Idle>, pub init: Option<Init>, pub resources: Option<Statics>, @@ -36,14 +37,14 @@ pub struct App { /// `init` #[derive(Debug)] pub struct Init { - pub path: Option<Tokens>, + pub path: Option<Path>, } /// `idle` #[derive(Debug)] pub struct Idle { pub locals: Option<Statics>, - pub path: Option<Tokens>, + pub path: Option<Path>, pub resources: Option<Idents>, } @@ -58,7 +59,7 @@ pub struct Task { #[derive(Debug)] pub struct Static { pub expr: Tokens, - pub ty: Tokens, + pub ty: Ty, } impl App { diff --git a/src/parse.rs b/src/parse.rs index ebc279e..7c1a813 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -2,8 +2,7 @@ use std::collections::{HashMap, HashSet}; use std::iter::Peekable; use std::slice::Iter; -use quote::Tokens; -use syn::{self, DelimToken, Ident, IntTy, Lit, Token, TokenTree}; +use syn::{self, DelimToken, Ident, IntTy, Lit, Path, Token, TokenTree}; use error::*; @@ -234,12 +233,6 @@ fn static_(tts: &mut Iter<TokenTree>) -> Result<Static> { if let Some(tt) = tts.next() { if tt == &TokenTree::Token(Token::Eq) { break; - } else if tt == &TokenTree::Token(Token::Semi) { - fragments.push(tt); - bail!( - "expected a type, found Semicolon: `{}`", - quote!(#(#fragments)*) - ); } else { fragments.push(tt); } @@ -248,8 +241,7 @@ fn static_(tts: &mut Iter<TokenTree>) -> Result<Static> { } } - ensure!(!fragments.is_empty(), "type is missing"); - let ty = quote!(#(#fragments)*); + let ty = syn::parse_type(&format!("{}", quote!(#(#fragments)*)))?; let mut fragments = vec![]; loop { @@ -306,7 +298,7 @@ fn statics(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Statics> { }) } -fn path(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Tokens> { +fn path(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Path> { let mut fragments = vec![]; loop { @@ -323,7 +315,7 @@ fn path(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Tokens> { tts.next(); } - Ok(quote!(#(#fragments)*)) + Ok(syn::parse_path(&format!("{}", quote!(#(#fragments)*)))?) } fn task(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Task> { diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..21e5447 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,14 @@ +use syn::{Ident, Path, PathParameters, PathSegment}; + +/// Creates a path with contents `#ident` +pub fn mk_path(ident: &str) -> Path { + Path { + global: false, + segments: vec![ + PathSegment { + ident: Ident::new(ident), + parameters: PathParameters::none(), + }, + ], + } +} -- GitLab