1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
use super::{
CallArgs, Callable, Name, SassString, Selectors, Value,
VariableDeclaration,
};
use crate::input::SourcePos;
use std::collections::BTreeSet;
/// Every sass file is a sequence of sass items.
/// Scoping items contains further sequences of items.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd)]
pub enum Item {
/// An `@import` directive.
Import(Vec<SassString>, Value, SourcePos),
/// A variable declaration.
VariableDeclaration(VariableDeclaration),
/// An `@at-root` directive.
AtRoot(Selectors, Vec<Item>),
/// An `@media` directive.
AtMedia {
/// Any arguments
args: Value,
/// The directive may have a body.
body: Option<Vec<Item>>,
/// The source location of this at rule.
pos: SourcePos,
},
/// A generic `@` directive.
AtRule {
/// The name of this directive
name: SassString,
/// Any arguments
args: Value,
/// The directive may have a body.
body: Option<Vec<Item>>,
/// The source location of this at rule.
pos: SourcePos,
},
/// An `@debug` directive.
Debug(Value),
/// An `@warn` directive.
Warn(Value),
/// An `@error` directive.
Error(Value, SourcePos),
/// A `@mixin` directive, declaring a mixin.
MixinDeclaration(String, Callable),
/// An `@include` directive, calling a mixin.
MixinCall(String, CallArgs, Option<Callable>, SourcePos),
/// An `@content` directive (in a mixin declaration).
Content(CallArgs, SourcePos),
/// An `@function` declaration.
FunctionDeclaration(String, Callable),
/// An `@return` statement in a function declaration.
Return(Value, SourcePos),
/// An `@if` conditional directive.
IfStatement(Value, Vec<Item>, Vec<Item>),
/// An `@each` loop directive.
///
/// The value may be or evaluate to a list.
Each(Vec<Name>, Value, Vec<Item>),
/// An `@for` loop directive.
For {
/// The name of the iteration variable.
name: Name,
/// The start value for the iteration.
from: Box<Value>,
/// The end value for the iteration.
to: Box<Value>,
/// True if the end should be included in the range.
inclusive: bool,
/// The body of the loop.
body: Vec<Item>,
},
/// An `@while` loop directive.
While(Value, Vec<Item>),
/// An `@use` directive.
Use(SassString, UseAs, Vec<(Name, Value, bool)>, SourcePos),
/// An `@forward` directive.
Forward(
SassString,
UseAs,
Expose,
Vec<(Name, Value, bool)>,
SourcePos,
),
/// Extend rule (not really supported yet).
Extend(Selectors),
/// A sass rule; selectors followed by a block of items.
Rule(Selectors, Vec<Item>),
/// A sass namespace rule; a name followed by a block of properties.
NamespaceRule(SassString, Value, Vec<Item>),
/// A sass property; a name and a value.
/// The position is the full value.
Property(SassString, Value, SourcePos),
/// A custom property.
CustomProperty(SassString, SassString),
/// A comment (that might be preserved for the output).
Comment(SassString),
/// Nothing
None,
}
impl From<VariableDeclaration> for Item {
fn from(value: VariableDeclaration) -> Self {
Self::VariableDeclaration(value)
}
}
/// How an `@forward`-ed module should be exposed.
///
/// As directed by the `show` or `hide` keywords or their absense.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd)]
pub enum Expose {
/// No `show` or `hide` specified; expose everything.
All,
/// Only show the listed items.
///
/// The first list is functions and mixins, the second is variables.
Show(BTreeSet<Name>, BTreeSet<Name>),
/// Hide the listed items, show everything else.
///
/// The first list is functions and mixins, the second is variables.
Hide(BTreeSet<Name>, BTreeSet<Name>),
}
impl Expose {
/// Check if `name` should be exposed as a function/mixin.
pub fn allow_fun(&self, name: &Name) -> bool {
match self {
Self::All => true,
Self::Show(show, _) => show.contains(name),
Self::Hide(hide, _) => !hide.contains(name),
}
}
/// Check if `name` should be exposed as a variable.
pub fn allow_var(&self, name: &Name) -> bool {
match self {
Self::All => true,
Self::Show(_, show) => show.contains(name),
Self::Hide(_, hide) => !hide.contains(name),
}
}
}
/// The `as` part of an `@use` or `@forward` directive.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd)]
pub enum UseAs {
/// A plain `@use foo;`.
KeepName,
/// Include the module contents directly in the scope, `@use foo as *;`.
Star,
/// An explicit name, `@use foo as bar`.
Name(String),
/// A prefix, `@forward foo as foo-*`.
Prefix(String),
}