From 54e71130e71e370f500ce9a52a0ed270230c5e5b Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Mon, 24 Feb 2020 15:18:53 -0500 Subject: [PATCH] Strings containing interpolation are double quoted --- src/selector.rs | 4 ++-- src/utils.rs | 18 ++++++++++++------ src/value/parse.rs | 43 ++----------------------------------------- 3 files changed, 16 insertions(+), 49 deletions(-) diff --git a/src/selector.rs b/src/selector.rs index 6af2500..fe8148c 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -375,7 +375,7 @@ impl Attribute { } q @ TokenKind::Symbol(Symbol::DoubleQuote) | q @ TokenKind::Symbol(Symbol::SingleQuote) => { - parse_quoted_string(toks, scope, q)? + parse_quoted_string(toks, scope, q)?.to_string() } _ => return Err("Expected identifier.".into()), } @@ -437,7 +437,7 @@ impl Attribute { } q @ TokenKind::Symbol(Symbol::DoubleQuote) | q @ TokenKind::Symbol(Symbol::SingleQuote) => { - parse_quoted_string(toks, scope, q)? + parse_quoted_string(toks, scope, q)?.to_string() } _ => return Err("Expected identifier.".into()), } diff --git a/src/utils.rs b/src/utils.rs index 9a236fb..43276a4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -152,9 +152,10 @@ pub(crate) fn parse_quoted_string>( toks: &mut Peekable, scope: &Scope, q: TokenKind, -) -> SassResult { +) -> SassResult { let mut s = String::new(); let mut is_escaped = false; + let mut found_interpolation = false; while let Some(tok) = toks.next() { match tok.kind { TokenKind::Symbol(Symbol::DoubleQuote) @@ -170,6 +171,7 @@ pub(crate) fn parse_quoted_string>( TokenKind::Symbol(Symbol::BackSlash) if !is_escaped => is_escaped = true, TokenKind::Symbol(Symbol::BackSlash) => s.push('\\'), TokenKind::Interpolation => { + found_interpolation = true; s.push_str( &parse_interpolation(toks, scope)? .iter() @@ -185,10 +187,14 @@ pub(crate) fn parse_quoted_string>( } s.push_str(&tok.kind.to_string()); } - let quotes = match q { - TokenKind::Symbol(Symbol::DoubleQuote) => QuoteKind::Double, - TokenKind::Symbol(Symbol::SingleQuote) => QuoteKind::Single, - _ => unreachable!(), + let quotes = if found_interpolation { + QuoteKind::Double + } else { + match q { + TokenKind::Symbol(Symbol::DoubleQuote) => QuoteKind::Double, + TokenKind::Symbol(Symbol::SingleQuote) => QuoteKind::Single, + _ => unreachable!(), + } }; - Ok(format!("{}{}{}", quotes, s, quotes)) + Ok(Value::Ident(s, quotes)) } diff --git a/src/value/parse.rs b/src/value/parse.rs index aa0b181..49ded3a 100644 --- a/src/value/parse.rs +++ b/src/value/parse.rs @@ -11,7 +11,7 @@ use crate::color::Color; use crate::common::{Keyword, ListSeparator, Op, QuoteKind, Scope, Symbol}; use crate::error::SassResult; use crate::units::Unit; -use crate::utils::{devour_whitespace_or_comment, parse_interpolation}; +use crate::utils::{devour_whitespace_or_comment, parse_interpolation, parse_quoted_string}; use crate::value::Value; use crate::{Token, TokenKind}; @@ -287,46 +287,7 @@ impl Value { } } q @ TokenKind::Symbol(Symbol::DoubleQuote) - | q @ TokenKind::Symbol(Symbol::SingleQuote) => { - let mut s = String::new(); - let mut is_escaped = false; - while let Some(tok) = toks.next() { - match tok.kind { - TokenKind::Symbol(Symbol::DoubleQuote) - if !is_escaped && q == TokenKind::Symbol(Symbol::DoubleQuote) => - { - break - } - TokenKind::Symbol(Symbol::SingleQuote) - if !is_escaped && q == TokenKind::Symbol(Symbol::SingleQuote) => - { - break - } - TokenKind::Symbol(Symbol::BackSlash) if !is_escaped => is_escaped = true, - TokenKind::Symbol(Symbol::BackSlash) => s.push('\\'), - TokenKind::Interpolation => { - s.push_str( - &parse_interpolation(toks, scope)? - .iter() - .map(|x| x.kind.to_string()) - .collect::(), - ); - continue; - } - _ => {} - } - if is_escaped && tok.kind != TokenKind::Symbol(Symbol::BackSlash) { - is_escaped = false; - } - s.push_str(&tok.kind.to_string()); - } - let quotes = match q { - TokenKind::Symbol(Symbol::DoubleQuote) => QuoteKind::Double, - TokenKind::Symbol(Symbol::SingleQuote) => QuoteKind::Single, - _ => unreachable!(), - }; - Ok(Value::Ident(s, quotes)) - } + | q @ TokenKind::Symbol(Symbol::SingleQuote) => parse_quoted_string(toks, scope, q), TokenKind::Variable(ref v) => Ok(scope.get_var(v)?.clone()), TokenKind::Interpolation => { let mut s = parse_interpolation(toks, scope)?