From 720b1e9f226ae74ac3eae9e434909fe4713223a5 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sat, 18 Jan 2020 20:24:28 -0500 Subject: [PATCH] Reduce usage of `.clone()` --- src/main.rs | 40 +++++++++++++++++++++++++--------------- src/mixin.rs | 4 ++-- src/selector.rs | 35 +++++++++++++++-------------------- src/style.rs | 10 +++++----- src/utils.rs | 8 ++++---- 5 files changed, 51 insertions(+), 46 deletions(-) diff --git a/src/main.rs b/src/main.rs index 71dda26..be51a5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,7 +51,7 @@ use crate::common::{AtRule, Keyword, Op, Pos, Printer, Scope, Symbol, Whitespace use crate::css::Css; use crate::error::SassError; use crate::format::PrettyPrinter; -use crate::function::{eat_call_args, eat_func_args, CallArgs, FuncArgs}; +use crate::function::{eat_call_args, CallArgs}; use crate::imports::import; use crate::lexer::Lexer; use crate::mixin::Mixin; @@ -268,7 +268,7 @@ impl<'a> StyleSheetParser<'a> { fn parse_toplevel(mut self) -> SassResult<(Vec, Scope)> { let mut rules: Vec = Vec::new(); while let Some(Token { kind, .. }) = self.lexer.peek() { - match kind.clone() { + match kind { TokenKind::Ident(_) | TokenKind::Attribute(_) | TokenKind::Interpolation @@ -281,11 +281,15 @@ impl<'a> StyleSheetParser<'a> { self.lexer.next(); continue; } - TokenKind::Variable(name) => { - let Token { pos, .. } = self + TokenKind::Variable(_) => { + let Token { pos, kind } = self .lexer .next() - .expect("this cannot occur as we have already peeked"); + .expect("this must exist because we have already peeked"); + let name = match kind { + TokenKind::Variable(n) => n, + _ => unsafe { std::hint::unreachable_unchecked() }, + }; devour_whitespace(&mut self.lexer); if self .lexer @@ -300,8 +304,16 @@ impl<'a> StyleSheetParser<'a> { .unwrap_or_else(|err| self.error(err.0, err.1)); self.global_scope.vars.insert(name, val); } - TokenKind::MultilineComment(comment) => { - self.lexer.next(); + TokenKind::MultilineComment(_) => { + let comment = match self + .lexer + .next() + .expect("this must exist because we have already peeked") + .kind + { + TokenKind::MultilineComment(c) => c, + _ => unsafe { std::hint::unreachable_unchecked() }, + }; rules.push(Stmt::MultilineComment(comment)); } TokenKind::AtRule(AtRule::Import) => { @@ -460,7 +472,7 @@ fn eat_include>( devour_whitespace(toks); - let mut mixin = if let Some(m) = scope.mixins.get(&name) { + let mixin = if let Some(m) = scope.mixins.get(&name) { m.clone() } else { return Err((pos, "expected identifier")); @@ -521,18 +533,16 @@ pub(crate) fn eat_expr>( TokenKind::Symbol(Symbol::SemiColon) | TokenKind::Symbol(Symbol::CloseCurlyBrace) => { toks.next(); devour_whitespace(toks); - return Ok(Some(Expr::Style( - match Style::from_tokens(&values, scope) { - Ok(x) => x, - Err(_) => return Ok(None), - }, - ))); + return Ok(Some(Expr::Style(match Style::from_tokens(values, scope) { + Ok(x) => x, + Err(_) => return Ok(None), + }))); } TokenKind::Symbol(Symbol::OpenCurlyBrace) => { toks.next(); devour_whitespace(toks); return Ok(Some(Expr::Selector(Selector::from_tokens( - &mut values.iter().peekable(), + &mut values.into_iter().peekable(), scope, )))); } diff --git a/src/mixin.rs b/src/mixin.rs index 4e11875..1139c91 100644 --- a/src/mixin.rs +++ b/src/mixin.rs @@ -80,7 +80,7 @@ impl Mixin { Ok((name, Mixin::new(scope.clone(), args, body))) } - pub fn args(&mut self, args: &CallArgs) -> &mut Mixin { + pub fn args(mut self, args: &CallArgs) -> Mixin { for (idx, arg) in args.0.iter().enumerate() { if arg.is_named() { todo!("keyword args") @@ -99,7 +99,7 @@ impl Mixin { self } - pub fn call(&mut self, super_selector: &Selector) -> Result, (Pos, &'static str)> { + pub fn call(mut self, super_selector: &Selector) -> Result, (Pos, &'static str)> { self.eval(super_selector, &mut self.scope.clone()) } diff --git a/src/selector.rs b/src/selector.rs index 5e03d04..1cc3d78 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -3,8 +3,8 @@ use crate::utils::{devour_whitespace, eat_interpolation, IsWhitespace}; use crate::{Token, TokenKind}; use std::fmt::{self, Display}; use std::iter::Peekable; -use std::slice::Iter; use std::string::ToString; +use std::vec::IntoIter; #[derive(Clone, Debug, Eq, PartialEq)] pub struct Selector(pub Vec); @@ -175,7 +175,7 @@ impl<'a> SelectorParser<'a> { } } - fn all_selectors(&mut self, tokens: &'a mut Peekable>) -> Selector { + fn all_selectors(mut self, tokens: &'a mut Peekable>) -> Selector { self.tokens_to_selectors(tokens); // remove trailing whitespace while let Some(x) = self.selectors.pop() { @@ -184,10 +184,10 @@ impl<'a> SelectorParser<'a> { break; } } - Selector(self.selectors.clone()) + Selector(self.selectors) } - fn consume_pseudo_selector(&mut self, tokens: &'_ mut Peekable>) { + fn consume_pseudo_selector(&mut self, tokens: &'_ mut Peekable>) { if let Some(Token { kind: TokenKind::Ident(s), .. @@ -205,28 +205,27 @@ impl<'a> SelectorParser<'a> { break; } let tok = tokens.next().unwrap(); - toks.push(tok.kind.clone()); + toks.push(tok.kind); } tokens.next(); - self.selectors - .push(SelectorKind::PseudoParen(s.clone(), toks)) + self.selectors.push(SelectorKind::PseudoParen(s, toks)) } else { - self.selectors.push(SelectorKind::Pseudo(s.clone())) + self.selectors.push(SelectorKind::Pseudo(s)) } } else { todo!("expected ident after `:` in selector") } } - fn tokens_to_selectors(&mut self, tokens: &'_ mut Peekable>) { + fn tokens_to_selectors(&mut self, tokens: &'_ mut Peekable>) { while tokens.peek().is_some() { self.consume_selector(tokens) } } - fn consume_selector(&mut self, tokens: &'_ mut Peekable>) { + fn consume_selector(&mut self, tokens: &'_ mut Peekable>) { if devour_whitespace(tokens) { - if let Some(&&Token { + if let Some(Token { kind: TokenKind::Symbol(Symbol::Comma), .. }) = tokens.peek() @@ -239,10 +238,8 @@ impl<'a> SelectorParser<'a> { return; } if let Some(Token { kind, .. }) = tokens.next() { - match &kind { - TokenKind::Ident(ident) => { - self.selectors.push(SelectorKind::Element(ident.clone())) - } + match kind { + TokenKind::Ident(ident) => self.selectors.push(SelectorKind::Element(ident)), TokenKind::Unit(u) => self.selectors.push(SelectorKind::Element(u.to_string())), TokenKind::Symbol(Symbol::Period) => self.selectors.push(SelectorKind::Class), TokenKind::Symbol(Symbol::Hash) => self.selectors.push(SelectorKind::Id), @@ -254,11 +251,9 @@ impl<'a> SelectorParser<'a> { TokenKind::Symbol(Symbol::Mul) => self.selectors.push(SelectorKind::Universal), TokenKind::Symbol(Symbol::BitAnd) => self.selectors.push(SelectorKind::Super), TokenKind::Interpolation => self.tokens_to_selectors( - &mut eat_interpolation(tokens, self.scope).iter().peekable(), + &mut eat_interpolation(tokens, self.scope).into_iter().peekable(), ), - TokenKind::Attribute(attr) => { - self.selectors.push(SelectorKind::Attribute(attr.clone())) - } + TokenKind::Attribute(attr) => self.selectors.push(SelectorKind::Attribute(attr)), _ => todo!("unimplemented selector"), }; } @@ -267,7 +262,7 @@ impl<'a> SelectorParser<'a> { impl Selector { pub fn from_tokens<'a>( - tokens: &'a mut Peekable>, + tokens: &'a mut Peekable>, scope: &'a Scope, ) -> Selector { SelectorParser::new(scope).all_selectors(tokens) diff --git a/src/style.rs b/src/style.rs index 932f48c..43d9c11 100644 --- a/src/style.rs +++ b/src/style.rs @@ -3,7 +3,7 @@ use crate::utils::{deref_variable, eat_interpolation}; use crate::{Token, TokenKind}; use std::fmt::{self, Display}; use std::iter::Peekable; -use std::slice::Iter; +use std::vec::IntoIter; /// A style: `color: red` #[derive(Clone, Debug, Eq, PartialEq)] @@ -19,22 +19,22 @@ impl Display for Style { } impl Style { - pub fn from_tokens(tokens: &[Token], scope: &Scope) -> Result { + pub fn from_tokens(tokens: Vec, scope: &Scope) -> Result { Ok(StyleParser::new(tokens, scope)?.parse()) } } struct StyleParser<'a> { - tokens: Peekable>, + tokens: Peekable>, scope: &'a Scope, } impl<'a> StyleParser<'a> { - fn new(tokens: &'a [Token], scope: &'a Scope) -> Result { + fn new(tokens: Vec, scope: &'a Scope) -> Result { if tokens.is_empty() { return Err(()); } - let tokens = tokens.iter().peekable(); + let tokens = tokens.into_iter().peekable(); Ok(StyleParser { tokens, scope }) } diff --git a/src/utils.rs b/src/utils.rs index 8464fdd..46ecc26 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -28,7 +28,7 @@ pub fn deref_variable(name: &str, scope: &Scope) -> Vec { .peekable(); let mut val = Vec::with_capacity(toks.len()); while let Some(tok) = toks.next() { - match &tok.kind { + match tok.kind { TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)), TokenKind::Whitespace(_) => { devour_whitespace(&mut toks); @@ -45,19 +45,19 @@ pub fn deref_variable(name: &str, scope: &Scope) -> Vec { val } -pub fn eat_interpolation<'a, I: Iterator>( +pub fn eat_interpolation>( tokens: &mut Peekable, scope: &Scope, ) -> Vec { let mut val = Vec::new(); for tok in tokens { - match &tok.kind { + match tok.kind { TokenKind::Symbol(Symbol::CloseCurlyBrace) => break, TokenKind::Symbol(Symbol::OpenCurlyBrace) => { todo!("invalid character in interpolation") } TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)), - _ => val.push(tok.clone()), + _ => val.push(tok), } } val