use std::rc::Rc;
use crate::scanner::Pos;
use crate::value::{Color, ListSep};
pub(crate) struct Stylesheet {
pub stmts: Vec<Stmt>,
}
#[derive(Clone, Copy, Default, PartialEq)]
pub(crate) struct SrcLines {
pub file: u32,
pub start: u32,
pub end: u32,
pub col: u32,
pub start_col: u32,
pub map_file: u32,
pub map_line: u32,
}
pub(crate) enum Stmt {
VarDecl(VarDecl),
Rule(Rule),
Decl(Declaration),
PropertySet(PropertySet),
CustomDecl(CustomDecl),
Import(Vec<ImportArg>),
Use {
url: String,
namespace: Option<String>,
star: bool,
config: Vec<ConfigEntry>,
pos: Pos,
},
Forward {
url: String,
prefix: Option<String>,
show: Option<Vec<ForwardMember>>,
hide: Option<Vec<ForwardMember>>,
config: Vec<ConfigEntry>,
pos: Pos,
},
Comment(Vec<TplPiece>, SrcLines),
If(Vec<IfBranch>),
For {
var: String,
from: Expr,
to: Expr,
inclusive: bool,
body: Vec<Stmt>,
},
Each {
vars: Vec<String>,
list: Expr,
body: Vec<Stmt>,
},
While { cond: Expr, body: Vec<Stmt> },
FunctionDef(Rc<Callable>),
Return(Expr),
MixinDef(Rc<Callable>),
Include {
name: String,
args: Vec<CallArg>,
content: Option<Rc<Vec<Stmt>>>,
content_params: Option<Rc<ParamList>>,
module: Option<String>,
pos: Pos,
length: usize,
},
Content(Vec<CallArg>),
AtRule {
name: String,
prelude: Vec<TplPiece>,
body: Option<Vec<Stmt>>,
lines: SrcLines,
},
InterpAtRule {
name: Vec<TplPiece>,
prelude: Vec<TplPiece>,
body: Option<Vec<Stmt>>,
},
CssCustomAtRule {
name: String,
prelude: Vec<TplPiece>,
body: Vec<CssCustomItem>,
},
Media {
query: MediaQueryList,
body: Vec<Stmt>,
lines: SrcLines,
},
Supports {
condition: SupportsCondition,
body: Vec<Stmt>,
lines: SrcLines,
},
AtRoot {
query: Option<Vec<TplPiece>>,
body: Vec<Stmt>,
},
Keyframes {
name: String,
prelude: Vec<TplPiece>,
body: Vec<Stmt>,
lines: SrcLines,
},
Extend {
selector: Vec<TplPiece>,
optional: bool,
pos: Pos,
},
Warn { value: Expr, pos: Pos },
Debug { value: Expr, pos: Pos },
Error { value: Expr, pos: Pos, length: usize },
}
pub(crate) struct ConfigEntry {
pub name: String,
pub value: Expr,
pub is_default: bool,
}
pub(crate) enum ForwardMember {
Var(String),
Name(String),
}
pub(crate) enum ImportArg {
Sass { path: String, pos: Pos, length: usize },
Css {
url: Vec<TplPiece>,
modifiers: Vec<ImportModifier>,
},
}
pub(crate) enum ImportModifier {
Raw(Vec<TplPiece>),
Supports {
condition: SupportsCondition,
declaration: bool,
},
Media {
list: MediaQueryList,
comma_before: bool,
},
}
pub(crate) struct IfBranch {
pub cond: Option<Expr>,
pub body: Vec<Stmt>,
}
pub(crate) struct Callable {
pub name: String,
pub params: ParamList,
pub body: Vec<Stmt>,
}
pub(crate) struct ParamList {
pub params: Vec<Param>,
pub rest: Option<String>,
}
pub(crate) struct Param {
pub name: String,
pub default: Option<Expr>,
}
pub(crate) struct VarDecl {
pub name: String,
pub value: Expr,
pub is_default: bool,
pub is_global: bool,
pub namespace: Option<String>,
}
pub(crate) struct Rule {
pub selector: Vec<TplPiece>,
pub body: Vec<Stmt>,
pub selector_pos: crate::scanner::Pos,
pub selector_interp_spans: Vec<(u32, u32, u32)>,
pub brace_line: u32,
pub end_line: u32,
}
pub(crate) struct CssCustomItem {
pub property: Vec<TplPiece>,
pub value: CssCustomValue,
}
pub(crate) enum CssCustomValue {
Raw(Vec<TplPiece>),
Script(Expr),
Set(Vec<(Vec<TplPiece>, Expr)>),
}
pub(crate) struct Declaration {
pub property: Vec<TplPiece>,
pub value: Expr,
pub important: bool,
pub pos: Pos,
pub end_line: u32,
}
pub(crate) struct CustomDecl {
pub property: Vec<TplPiece>,
pub value: Vec<TplPiece>,
pub pos: Pos,
pub end_line: u32,
}
pub(crate) struct PropertySet {
pub property: Vec<TplPiece>,
pub value: Option<Expr>,
pub important: bool,
pub body: Vec<Stmt>,
pub pos: Pos,
}
pub(crate) enum TplPiece {
Lit(String),
Interp(Expr),
}
pub(crate) enum Expr {
Number(f64, String),
Color(Color),
QuotedString(Vec<TplPiece>),
Ident(Vec<TplPiece>),
Bool(bool),
Null,
Var { name: String, pos: Pos },
NsVar { module: String, name: String },
Parent,
Binary {
op: BinOp,
lhs: Box<Expr>,
rhs: Box<Expr>,
pos: Pos,
},
Div {
lhs: Box<Expr>,
rhs: Box<Expr>,
slash: bool,
pos: Pos,
},
Calc { inner: Box<Expr> },
Unary { op: UnOp, operand: Box<Expr> },
Func {
name: String,
args: Vec<CallArg>,
pos: Pos,
length: usize,
module: Option<String>,
},
InterpFunc {
name: Vec<TplPiece>,
args: Vec<CallArg>,
pos: Pos,
},
List {
items: Vec<Expr>,
sep: ListSep,
bracketed: bool,
},
Paren(Box<Expr>),
Map(Vec<(Expr, Expr)>),
Interp(Box<Expr>),
ModernIf(Vec<IfClause>),
}
pub(crate) struct IfClause {
pub condition: Option<IfCond>,
pub value: Expr,
}
pub(crate) enum IfCond {
Sass(Box<Expr>),
Raw { pieces: Vec<TplPiece>, multi: bool },
Not(Box<IfCond>),
And(Vec<IfCond>),
Or(Vec<IfCond>),
Paren(Box<IfCond>),
}
pub(crate) struct CallArg {
pub name: Option<String>,
pub value: Expr,
pub splat: bool,
}
#[derive(Clone, Copy)]
pub(crate) enum BinOp {
Add,
Sub,
Mul,
Mod,
Eq,
Neq,
Lt,
Gt,
Le,
Ge,
And,
Or,
SingleEq,
}
#[derive(Clone, Copy)]
pub(crate) enum UnOp {
Neg,
Plus,
Not,
}
pub(crate) struct MediaQueryList {
pub queries: Vec<MediaQuery>,
}
pub(crate) enum MediaQuery {
Type {
modifier: Option<Vec<TplPiece>>,
mtype: Vec<TplPiece>,
conditions: Vec<MediaInParens>,
},
Condition {
conditions: Vec<MediaInParens>,
conjunction: Conjunction,
},
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) enum Conjunction {
And,
Or,
}
pub(crate) enum MediaInParens {
Feature(Box<MediaFeature>),
Not(Box<MediaInParens>),
Group {
conditions: Vec<MediaInParens>,
conjunction: Conjunction,
},
Interp(Expr),
}
pub(crate) enum MediaFeature {
Decl { name: Expr, value: Option<Expr> },
Range {
first: Expr,
op1: String,
second: Expr,
rest: Option<(String, Expr)>,
},
}
pub(crate) enum SupportsCondition {
Declaration {
name: Expr,
value: Box<SupportsValue>,
custom: bool,
},
Negation(Box<SupportsCondition>),
Operation {
left: Box<SupportsCondition>,
right: Box<SupportsCondition>,
op: Conjunction,
},
Interpolation(Expr),
Function {
name: Vec<TplPiece>,
arguments: Vec<TplPiece>,
},
Anything(Vec<TplPiece>),
}
pub(crate) enum SupportsValue {
Expr(Expr),
Raw(Vec<TplPiece>),
}