From a61ac3fca376785c080d712f85456eab4b5cf416 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sat, 25 Jan 2020 11:00:29 -0500 Subject: [PATCH] Refactor arg parsing to separate file --- src/args.rs | 166 ++++++++++++++++++++++++++++++++++++++++++++++++ src/function.rs | 166 ------------------------------------------------ src/lib.rs | 1 + src/mixin.rs | 2 +- 4 files changed, 168 insertions(+), 167 deletions(-) create mode 100644 src/args.rs diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..8885f06 --- /dev/null +++ b/src/args.rs @@ -0,0 +1,166 @@ +use std::collections::BTreeMap; +use std::iter::Peekable; + +use crate::common::Symbol; +use crate::utils::devour_whitespace; +use crate::{Token, TokenKind}; + +#[derive(Debug, Clone, Eq, PartialEq)] +pub(crate) struct FuncArgs(pub Vec); + +#[derive(Debug, Clone, Eq, PartialEq)] +pub(crate) struct FuncArg { + pub name: String, + pub default: Option>, +} + +impl FuncArgs { + pub const fn new() -> Self { + FuncArgs(Vec::new()) + } +} + +#[derive(Debug, Clone, std::default::Default)] +pub(crate) struct CallArgs(pub BTreeMap>); + +impl CallArgs { + pub fn new() -> Self { + CallArgs(BTreeMap::new()) + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + pub fn get(&self, val: &str) -> Option<&Vec> { + self.0.get(val) + } +} + +pub(crate) fn eat_func_args>(toks: &mut Peekable) -> FuncArgs { + let mut args: Vec = Vec::new(); + + devour_whitespace(toks); + while let Some(Token { kind, .. }) = toks.next() { + let name = match kind { + TokenKind::Variable(v) => v, + TokenKind::Symbol(Symbol::CloseParen) => break, + _ => todo!(), + }; + let mut default: Vec = Vec::new(); + devour_whitespace(toks); + let kind = match toks.next() { + Some(Token { kind, .. }) => kind, + _ => todo!("unexpected eof"), + }; + match kind { + TokenKind::Symbol(Symbol::Colon) => { + devour_whitespace(toks); + while let Some(tok) = toks.peek() { + match &tok.kind { + TokenKind::Symbol(Symbol::Comma) => { + toks.next(); + args.push(FuncArg { + name, + default: Some(default), + }); + break; + } + TokenKind::Symbol(Symbol::CloseParen) => { + args.push(FuncArg { + name, + default: Some(default), + }); + break; + } + _ => { + let tok = toks.next().expect("we know this exists!"); + default.push(tok) + } + } + } + } + TokenKind::Symbol(Symbol::Period) => todo!("handle varargs"), + TokenKind::Symbol(Symbol::CloseParen) => { + args.push(FuncArg { + name, + default: if default.is_empty() { + None + } else { + Some(default) + }, + }); + break; + } + TokenKind::Symbol(Symbol::Comma) => args.push(FuncArg { + name, + default: None, + }), + _ => {} + } + devour_whitespace(toks); + } + devour_whitespace(toks); + if let Some(Token { + kind: TokenKind::Symbol(Symbol::OpenCurlyBrace), + .. + }) = toks.next() + { + } else { + todo!("expected `{{` after mixin args") + } + FuncArgs(args) +} + +pub(crate) fn eat_call_args>(toks: &mut Peekable) -> CallArgs { + let mut args: BTreeMap> = BTreeMap::new(); + devour_whitespace(toks); + let mut name: Option = None; + let mut val = Vec::new(); + while let Some(Token { kind, pos }) = toks.next() { + match kind { + TokenKind::Variable(v) => name = Some(v), + TokenKind::Symbol(Symbol::Colon) => { + devour_whitespace(toks); + while let Some(tok) = toks.peek() { + match &tok.kind { + TokenKind::Symbol(Symbol::Comma) => { + toks.next(); + args.insert(name.clone().unwrap(), val.clone()); + if let Some(ref mut s) = name { + s.clear(); + } + val.clear(); + break; + } + TokenKind::Symbol(Symbol::CloseParen) => { + args.insert(name.clone().unwrap(), val.clone()); + break; + } + _ => val.push(toks.next().expect("we know this exists!")), + } + } + } + TokenKind::Symbol(Symbol::CloseParen) => { + match name { + Some(name) => args.insert(name, val), + None => args.insert(format!("{}", args.len()), val), + }; + break; + } + TokenKind::Symbol(Symbol::Comma) => { + match name { + Some(ref name) => args.insert(name.clone(), val.clone()), + None => args.insert(format!("{}", args.len()), val.clone()), + }; + if let Some(ref mut s) = name { + s.clear(); + } + val.clear(); + } + _ => val.push(Token { kind, pos }), + } + devour_whitespace(toks); + } + CallArgs(args) +} diff --git a/src/function.rs b/src/function.rs index 8885f06..e69de29 100644 --- a/src/function.rs +++ b/src/function.rs @@ -1,166 +0,0 @@ -use std::collections::BTreeMap; -use std::iter::Peekable; - -use crate::common::Symbol; -use crate::utils::devour_whitespace; -use crate::{Token, TokenKind}; - -#[derive(Debug, Clone, Eq, PartialEq)] -pub(crate) struct FuncArgs(pub Vec); - -#[derive(Debug, Clone, Eq, PartialEq)] -pub(crate) struct FuncArg { - pub name: String, - pub default: Option>, -} - -impl FuncArgs { - pub const fn new() -> Self { - FuncArgs(Vec::new()) - } -} - -#[derive(Debug, Clone, std::default::Default)] -pub(crate) struct CallArgs(pub BTreeMap>); - -impl CallArgs { - pub fn new() -> Self { - CallArgs(BTreeMap::new()) - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn get(&self, val: &str) -> Option<&Vec> { - self.0.get(val) - } -} - -pub(crate) fn eat_func_args>(toks: &mut Peekable) -> FuncArgs { - let mut args: Vec = Vec::new(); - - devour_whitespace(toks); - while let Some(Token { kind, .. }) = toks.next() { - let name = match kind { - TokenKind::Variable(v) => v, - TokenKind::Symbol(Symbol::CloseParen) => break, - _ => todo!(), - }; - let mut default: Vec = Vec::new(); - devour_whitespace(toks); - let kind = match toks.next() { - Some(Token { kind, .. }) => kind, - _ => todo!("unexpected eof"), - }; - match kind { - TokenKind::Symbol(Symbol::Colon) => { - devour_whitespace(toks); - while let Some(tok) = toks.peek() { - match &tok.kind { - TokenKind::Symbol(Symbol::Comma) => { - toks.next(); - args.push(FuncArg { - name, - default: Some(default), - }); - break; - } - TokenKind::Symbol(Symbol::CloseParen) => { - args.push(FuncArg { - name, - default: Some(default), - }); - break; - } - _ => { - let tok = toks.next().expect("we know this exists!"); - default.push(tok) - } - } - } - } - TokenKind::Symbol(Symbol::Period) => todo!("handle varargs"), - TokenKind::Symbol(Symbol::CloseParen) => { - args.push(FuncArg { - name, - default: if default.is_empty() { - None - } else { - Some(default) - }, - }); - break; - } - TokenKind::Symbol(Symbol::Comma) => args.push(FuncArg { - name, - default: None, - }), - _ => {} - } - devour_whitespace(toks); - } - devour_whitespace(toks); - if let Some(Token { - kind: TokenKind::Symbol(Symbol::OpenCurlyBrace), - .. - }) = toks.next() - { - } else { - todo!("expected `{{` after mixin args") - } - FuncArgs(args) -} - -pub(crate) fn eat_call_args>(toks: &mut Peekable) -> CallArgs { - let mut args: BTreeMap> = BTreeMap::new(); - devour_whitespace(toks); - let mut name: Option = None; - let mut val = Vec::new(); - while let Some(Token { kind, pos }) = toks.next() { - match kind { - TokenKind::Variable(v) => name = Some(v), - TokenKind::Symbol(Symbol::Colon) => { - devour_whitespace(toks); - while let Some(tok) = toks.peek() { - match &tok.kind { - TokenKind::Symbol(Symbol::Comma) => { - toks.next(); - args.insert(name.clone().unwrap(), val.clone()); - if let Some(ref mut s) = name { - s.clear(); - } - val.clear(); - break; - } - TokenKind::Symbol(Symbol::CloseParen) => { - args.insert(name.clone().unwrap(), val.clone()); - break; - } - _ => val.push(toks.next().expect("we know this exists!")), - } - } - } - TokenKind::Symbol(Symbol::CloseParen) => { - match name { - Some(name) => args.insert(name, val), - None => args.insert(format!("{}", args.len()), val), - }; - break; - } - TokenKind::Symbol(Symbol::Comma) => { - match name { - Some(ref name) => args.insert(name.clone(), val.clone()), - None => args.insert(format!("{}", args.len()), val.clone()), - }; - if let Some(ref mut s) = name { - s.clear(); - } - val.clear(); - } - _ => val.push(Token { kind, pos }), - } - devour_whitespace(toks); - } - CallArgs(args) -} diff --git a/src/lib.rs b/src/lib.rs index 23c390f..21ffb29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,6 +58,7 @@ use crate::selector::{Attribute, Selector}; use crate::style::Style; use crate::utils::{devour_whitespace, eat_variable_value, IsComment, IsWhitespace}; +mod args; mod color; mod common; mod css; diff --git a/src/mixin.rs b/src/mixin.rs index 3e72e7b..9c7d4fa 100644 --- a/src/mixin.rs +++ b/src/mixin.rs @@ -2,7 +2,7 @@ use std::iter::Peekable; use std::vec::IntoIter; use crate::common::{Pos, Scope, Symbol}; -use crate::function::{eat_call_args, eat_func_args, CallArgs, FuncArgs}; +use crate::args::{eat_call_args, eat_func_args, CallArgs, FuncArgs}; use crate::selector::Selector; use crate::utils::devour_whitespace; use crate::{eat_expr, Expr, RuleSet, Stmt, Token, TokenKind};