use codemap::{Span, Spanned}; use peekmore::{PeekMore, PeekMoreIterator}; use super::{eat_stmts, AtRule}; use crate::error::SassResult; use crate::scope::Scope; use crate::selector::Selector; use crate::utils::{ devour_whitespace, read_until_closing_curly_brace, read_until_open_curly_brace, }; use crate::value::Value; use crate::{Stmt, Token}; #[derive(Debug, Clone)] pub(crate) struct While { pub cond: Vec, pub body: Vec, } impl While { pub fn ruleset_eval( self, scope: &mut Scope, super_selector: &Selector, ) -> SassResult>> { let mut stmts = Vec::new(); let mut val = Value::from_vec(self.cond.clone(), scope, super_selector)?; let scope = &mut scope.clone(); while val.node.is_true(val.span)? { stmts.extend(eat_stmts( &mut self.body.clone().into_iter().peekmore(), scope, super_selector, )?); val = Value::from_vec(self.cond.clone(), scope, super_selector)?; } Ok(stmts) } } pub(crate) fn parse_while>( toks: &mut PeekMoreIterator, span: Span, ) -> SassResult> { devour_whitespace(toks); let cond = read_until_open_curly_brace(toks); if cond.is_empty() { return Err(("Expected expression.", span).into()); } toks.next(); let body = read_until_closing_curly_brace(toks); toks.next(); devour_whitespace(toks); Ok(Spanned { node: AtRule::While(While { cond, body }), span, }) }