Reduce usage of .clone()
This commit is contained in:
parent
b28295d2b1
commit
720b1e9f22
40
src/main.rs
40
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<Stmt>, Scope)> {
|
||||
let mut rules: Vec<Stmt> = 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<I: Iterator<Item = Token>>(
|
||||
|
||||
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<I: Iterator<Item = Token>>(
|
||||
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,
|
||||
))));
|
||||
}
|
||||
|
@ -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<Vec<Stmt>, (Pos, &'static str)> {
|
||||
pub fn call(mut self, super_selector: &Selector) -> Result<Vec<Stmt>, (Pos, &'static str)> {
|
||||
self.eval(super_selector, &mut self.scope.clone())
|
||||
}
|
||||
|
||||
|
@ -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<SelectorKind>);
|
||||
@ -175,7 +175,7 @@ impl<'a> SelectorParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn all_selectors(&mut self, tokens: &'a mut Peekable<Iter<'_, Token>>) -> Selector {
|
||||
fn all_selectors(mut self, tokens: &'a mut Peekable<IntoIter<Token>>) -> 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<Iter<'_, Token>>) {
|
||||
fn consume_pseudo_selector(&mut self, tokens: &'_ mut Peekable<IntoIter<Token>>) {
|
||||
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<Iter<'_, Token>>) {
|
||||
fn tokens_to_selectors(&mut self, tokens: &'_ mut Peekable<IntoIter<Token>>) {
|
||||
while tokens.peek().is_some() {
|
||||
self.consume_selector(tokens)
|
||||
}
|
||||
}
|
||||
|
||||
fn consume_selector(&mut self, tokens: &'_ mut Peekable<Iter<'_, Token>>) {
|
||||
fn consume_selector(&mut self, tokens: &'_ mut Peekable<IntoIter<Token>>) {
|
||||
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<Iter<'a, Token>>,
|
||||
tokens: &'a mut Peekable<IntoIter<Token>>,
|
||||
scope: &'a Scope,
|
||||
) -> Selector {
|
||||
SelectorParser::new(scope).all_selectors(tokens)
|
||||
|
10
src/style.rs
10
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<Self, ()> {
|
||||
pub fn from_tokens(tokens: Vec<Token>, scope: &Scope) -> Result<Self, ()> {
|
||||
Ok(StyleParser::new(tokens, scope)?.parse())
|
||||
}
|
||||
}
|
||||
|
||||
struct StyleParser<'a> {
|
||||
tokens: Peekable<Iter<'a, Token>>,
|
||||
tokens: Peekable<IntoIter<Token>>,
|
||||
scope: &'a Scope,
|
||||
}
|
||||
|
||||
impl<'a> StyleParser<'a> {
|
||||
fn new(tokens: &'a [Token], scope: &'a Scope) -> Result<Self, ()> {
|
||||
fn new(tokens: Vec<Token>, scope: &'a Scope) -> Result<Self, ()> {
|
||||
if tokens.is_empty() {
|
||||
return Err(());
|
||||
}
|
||||
let tokens = tokens.iter().peekable();
|
||||
let tokens = tokens.into_iter().peekable();
|
||||
Ok(StyleParser { tokens, scope })
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ pub fn deref_variable(name: &str, scope: &Scope) -> Vec<Token> {
|
||||
.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<Token> {
|
||||
val
|
||||
}
|
||||
|
||||
pub fn eat_interpolation<'a, I: Iterator<Item = &'a Token>>(
|
||||
pub fn eat_interpolation<I: Iterator<Item = Token>>(
|
||||
tokens: &mut Peekable<I>,
|
||||
scope: &Scope,
|
||||
) -> Vec<Token> {
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user