#![doc = include_str!("readme.md")]
use core::range::Range;
use oak_core::tree::{GreenNode, RedNode, TypedNode};
pub trait StylusVisitor {
fn visit_root(&mut self, node: &StylusRoot) -> VisitResult {
VisitResult::Continue
}
fn visit_rule(&mut self, node: &StylusRule) -> VisitResult {
VisitResult::Continue
}
fn visit_comment(&mut self, node: &StylusComment) -> VisitResult {
VisitResult::Continue
}
fn visit_property(&mut self, node: &StylusProperty) -> VisitResult {
VisitResult::Continue
}
fn visit_mixin(&mut self, node: &StylusMixin) -> VisitResult {
VisitResult::Continue
}
fn visit_variable(&mut self, node: &StylusVariable) -> VisitResult {
VisitResult::Continue
}
fn visit_import(&mut self, node: &StylusImport) -> VisitResult {
VisitResult::Continue
}
fn visit_function(&mut self, node: &StylusFunction) -> VisitResult {
VisitResult::Continue
}
fn visit_if(&mut self, node: &StylusIf) -> VisitResult {
VisitResult::Continue
}
fn visit_for(&mut self, node: &StylusFor) -> VisitResult {
VisitResult::Continue
}
fn visit_while(&mut self, node: &StylusWhile) -> VisitResult {
VisitResult::Continue
}
fn visit_param(&mut self, node: &StylusParam) -> VisitResult {
VisitResult::Continue
}
}
pub enum VisitResult {
Continue,
Stop,
SkipChildren,
}
pub trait AcceptVisitor {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult;
}
pub trait AstProcessor {
fn process<T: AcceptVisitor>(&self, node: &T, visitor: &mut impl StylusVisitor);
fn process_recursive<T: AcceptVisitor>(&self, node: &T, visitor: &mut impl StylusVisitor);
fn transform<T: AcceptVisitor>(&self, node: &T) -> T;
}
pub struct DefaultAstProcessor;
impl AstProcessor for DefaultAstProcessor {
fn process<T: AcceptVisitor>(&self, node: &T, visitor: &mut impl StylusVisitor) {
node.accept(visitor);
}
fn process_recursive<T: AcceptVisitor>(&self, node: &T, visitor: &mut impl StylusVisitor) {
self.process(node, visitor);
}
fn transform<T: AcceptVisitor>(&self, node: &T) -> T {
unimplemented!("DefaultAstProcessor::transform() not implemented")
}
}
impl DefaultAstProcessor {
pub fn new() -> Self {
Self
}
}
pub struct MapAstProcessor<F: MapFn> {
pub map_fn: F,
}
impl<F: MapFn> MapAstProcessor<F> {
pub fn new(map_fn: F) -> Self {
Self { map_fn }
}
}
impl<F: MapFn> AstProcessor for MapAstProcessor<F> {
fn process<T: AcceptVisitor>(&self, node: &T, visitor: &mut impl StylusVisitor) {
node.accept(visitor);
}
fn process_recursive<T: AcceptVisitor>(&self, node: &T, visitor: &mut impl StylusVisitor) {
self.process(node, visitor);
}
fn transform<T: AcceptVisitor>(&self, node: &T) -> T {
unimplemented!("MapAstProcessor::transform() not implemented")
}
}
pub struct DebugAstProcessor {
pub indent: usize,
}
impl DebugAstProcessor {
pub fn new() -> Self {
Self { indent: 0 }
}
}
impl AstProcessor for DebugAstProcessor {
fn process<T: AcceptVisitor>(&self, node: &T, visitor: &mut impl StylusVisitor) {
node.accept(visitor);
}
fn process_recursive<T: AcceptVisitor>(&self, node: &T, visitor: &mut impl StylusVisitor) {
self.process(node, visitor);
}
fn transform<T: AcceptVisitor>(&self, node: &T) -> T {
unimplemented!("DebugAstProcessor::transform() not implemented")
}
}
pub struct DefaultVisitor;
impl StylusVisitor for DefaultVisitor {
}
pub struct MapVisitor<F> {
pub map_fn: F,
}
impl<F> MapVisitor<F> {
pub fn new(map_fn: F) -> Self {
Self { map_fn }
}
}
pub trait MapFn {
fn map_root(&mut self, node: &StylusRoot) -> StylusRoot {
let mut new_root = StylusRoot::new(node.span.clone());
for item in &node.items {
new_root.add_item(self.map_item(item));
}
new_root
}
fn map_item(&mut self, node: &StylusItem) -> StylusItem {
match node {
StylusItem::Rule(rule) => StylusItem::Rule(self.map_rule(rule)),
StylusItem::Comment(comment) => StylusItem::Comment(self.map_comment(comment)),
StylusItem::Mixin(mixin) => StylusItem::Mixin(self.map_mixin(mixin)),
StylusItem::Variable(variable) => StylusItem::Variable(self.map_variable(variable)),
StylusItem::Import(import) => StylusItem::Import(self.map_import(import)),
StylusItem::Function(function) => StylusItem::Function(self.map_function(function)),
StylusItem::If(if_stmt) => StylusItem::If(self.map_if(if_stmt)),
StylusItem::For(for_stmt) => StylusItem::For(self.map_for(for_stmt)),
StylusItem::While(while_stmt) => StylusItem::While(self.map_while(while_stmt)),
}
}
fn map_rule(&mut self, node: &StylusRule) -> StylusRule {
let mut new_rule = StylusRule { span: node.span.clone(), selector: node.selector.clone(), properties: Vec::new() };
for property in &node.properties {
new_rule.add_property(self.map_property(property));
}
new_rule
}
fn map_comment(&mut self, node: &StylusComment) -> StylusComment {
StylusComment { span: node.span.clone(), text: node.text.clone() }
}
fn map_property(&mut self, node: &StylusProperty) -> StylusProperty {
StylusProperty { span: node.span.clone(), name: node.name.clone(), value: node.value.clone() }
}
fn map_mixin(&mut self, node: &StylusMixin) -> StylusMixin {
let mut new_mixin = StylusMixin { span: node.span.clone(), name: node.name.clone(), params: Vec::new(), body: Vec::new() };
for param in &node.params {
new_mixin.add_param(self.map_param(param));
}
for item in &node.body {
new_mixin.add_body_item(self.map_item(item));
}
new_mixin
}
fn map_variable(&mut self, node: &StylusVariable) -> StylusVariable {
StylusVariable { span: node.span.clone(), name: node.name.clone(), value: node.value.clone() }
}
fn map_import(&mut self, node: &StylusImport) -> StylusImport {
StylusImport { span: node.span.clone(), path: node.path.clone() }
}
fn map_function(&mut self, node: &StylusFunction) -> StylusFunction {
let mut new_function = StylusFunction { span: node.span.clone(), name: node.name.clone(), params: Vec::new(), body: Vec::new(), return_value: node.return_value.clone() };
for param in &node.params {
new_function.add_param(self.map_param(param));
}
for item in &node.body {
new_function.add_body_item(self.map_item(item));
}
new_function
}
fn map_if(&mut self, node: &StylusIf) -> StylusIf {
let mut new_if = StylusIf { span: node.span.clone(), condition: node.condition.clone(), body: Vec::new(), else_clause: None };
for item in &node.body {
new_if.add_body_item(self.map_item(item));
}
if let Some(else_items) = &node.else_clause {
let mut new_else_items = Vec::new();
for item in else_items {
new_else_items.push(self.map_item(item));
}
new_if.else_clause = Some(new_else_items);
}
new_if
}
fn map_for(&mut self, node: &StylusFor) -> StylusFor {
let mut new_for = StylusFor { span: node.span.clone(), variable: node.variable.clone(), range: node.range.clone(), body: Vec::new() };
for item in &node.body {
new_for.add_body_item(self.map_item(item));
}
new_for
}
fn map_while(&mut self, node: &StylusWhile) -> StylusWhile {
let mut new_while = StylusWhile { span: node.span.clone(), condition: node.condition.clone(), body: Vec::new() };
for item in &node.body {
new_while.add_body_item(self.map_item(item));
}
new_while
}
fn map_param(&mut self, node: &StylusParam) -> StylusParam {
StylusParam { span: node.span.clone(), name: node.name.clone(), default: node.default.clone() }
}
}
pub struct DebugVisitor {
pub indent: usize,
}
impl DebugVisitor {
pub fn new() -> Self {
Self { indent: 0 }
}
fn print_indent(&self) {
for _ in 0..self.indent {
print!(" ");
}
}
}
impl StylusVisitor for DebugVisitor {
fn visit_root(&mut self, node: &StylusRoot) -> VisitResult {
self.print_indent();
println!(
"StylusRoot (span: {:?})
",
node.span
);
self.indent += 1;
let result = VisitResult::Continue;
self.indent -= 1;
result
}
fn visit_rule(&mut self, node: &StylusRule) -> VisitResult {
self.print_indent();
println!(
"StylusRule (selector: {}, span: {:?})
",
node.selector, node.span
);
self.indent += 1;
let result = VisitResult::Continue;
self.indent -= 1;
result
}
fn visit_comment(&mut self, node: &StylusComment) -> VisitResult {
self.print_indent();
println!(
"StylusComment (text: {}, span: {:?})
",
node.text, node.span
);
VisitResult::Continue
}
fn visit_property(&mut self, node: &StylusProperty) -> VisitResult {
self.print_indent();
println!(
"StylusProperty (name: {}, value: {}, span: {:?})
",
node.name, node.value, node.span
);
VisitResult::Continue
}
fn visit_mixin(&mut self, node: &StylusMixin) -> VisitResult {
self.print_indent();
println!(
"StylusMixin (name: {}, span: {:?})
",
node.name, node.span
);
self.indent += 1;
let result = VisitResult::Continue;
self.indent -= 1;
result
}
fn visit_variable(&mut self, node: &StylusVariable) -> VisitResult {
self.print_indent();
println!(
"StylusVariable (name: {}, value: {}, span: {:?})
",
node.name, node.value, node.span
);
VisitResult::Continue
}
fn visit_import(&mut self, node: &StylusImport) -> VisitResult {
self.print_indent();
println!(
"StylusImport (path: {}, span: {:?})
",
node.path, node.span
);
VisitResult::Continue
}
fn visit_function(&mut self, node: &StylusFunction) -> VisitResult {
self.print_indent();
println!(
"StylusFunction (name: {}, span: {:?})
",
node.name, node.span
);
self.indent += 1;
let result = VisitResult::Continue;
self.indent -= 1;
result
}
fn visit_if(&mut self, node: &StylusIf) -> VisitResult {
self.print_indent();
println!(
"StylusIf (condition: {}, span: {:?})
",
node.condition, node.span
);
self.indent += 1;
let result = VisitResult::Continue;
self.indent -= 1;
result
}
fn visit_for(&mut self, node: &StylusFor) -> VisitResult {
self.print_indent();
println!(
"StylusFor (variable: {}, range: {}, span: {:?})
",
node.variable, node.range, node.span
);
self.indent += 1;
let result = VisitResult::Continue;
self.indent -= 1;
result
}
fn visit_while(&mut self, node: &StylusWhile) -> VisitResult {
self.print_indent();
println!(
"StylusWhile (condition: {}, span: {:?})
",
node.condition, node.span
);
self.indent += 1;
let result = VisitResult::Continue;
self.indent -= 1;
result
}
fn visit_param(&mut self, node: &StylusParam) -> VisitResult {
self.print_indent();
println!(
"StylusParam (name: {}, default: {:?}, span: {:?})
",
node.name, node.default, node.span
);
VisitResult::Continue
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusRoot {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub items: Vec<StylusItem>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum StylusItem {
Rule(StylusRule),
Comment(StylusComment),
Mixin(StylusMixin),
Variable(StylusVariable),
Import(StylusImport),
Function(StylusFunction),
If(StylusIf),
For(StylusFor),
While(StylusWhile),
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusRule {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub selector: String,
pub properties: Vec<StylusProperty>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusComment {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub text: String,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusProperty {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub name: String,
pub value: String,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusMixin {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub name: String,
pub params: Vec<StylusParam>,
pub body: Vec<StylusItem>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusVariable {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub name: String,
pub value: String,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusImport {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub path: String,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusFunction {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub name: String,
pub params: Vec<StylusParam>,
pub body: Vec<StylusItem>,
pub return_value: Option<String>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusIf {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub condition: String,
pub body: Vec<StylusItem>,
pub else_clause: Option<Vec<StylusItem>>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusFor {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub variable: String,
pub range: String,
pub body: Vec<StylusItem>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusWhile {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub condition: String,
pub body: Vec<StylusItem>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StylusParam {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub name: String,
pub default: Option<String>,
}
impl StylusRoot {
pub fn new(span: Range<usize>) -> Self {
Self { span, items: Vec::new() }
}
pub fn add_item(&mut self, item: StylusItem) {
self.items.push(item);
}
pub fn remove_item(&mut self, index: usize) -> Option<StylusItem> {
if index < self.items.len() { Some(self.items.remove(index)) } else { None }
}
pub fn insert_item(&mut self, index: usize, item: StylusItem) {
if index <= self.items.len() {
self.items.insert(index, item);
}
}
}
impl AcceptVisitor for StylusRoot {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
match visitor.visit_root(self) {
VisitResult::Stop => VisitResult::Stop,
VisitResult::SkipChildren => VisitResult::Continue,
VisitResult::Continue => {
for item in &self.items {
if let VisitResult::Stop = item.accept(visitor) {
return VisitResult::Stop;
}
}
VisitResult::Continue
}
}
}
}
impl AcceptVisitor for StylusItem {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
match self {
StylusItem::Rule(rule) => rule.accept(visitor),
StylusItem::Comment(comment) => comment.accept(visitor),
StylusItem::Mixin(mixin) => mixin.accept(visitor),
StylusItem::Variable(variable) => variable.accept(visitor),
StylusItem::Import(import) => import.accept(visitor),
StylusItem::Function(function) => function.accept(visitor),
StylusItem::If(if_stmt) => if_stmt.accept(visitor),
StylusItem::For(for_stmt) => for_stmt.accept(visitor),
StylusItem::While(while_stmt) => while_stmt.accept(visitor),
}
}
}
impl AcceptVisitor for StylusRule {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
match visitor.visit_rule(self) {
VisitResult::Stop => VisitResult::Stop,
VisitResult::SkipChildren => VisitResult::Continue,
VisitResult::Continue => {
for property in &self.properties {
if let VisitResult::Stop = property.accept(visitor) {
return VisitResult::Stop;
}
}
VisitResult::Continue
}
}
}
}
impl StylusRule {
pub fn add_property(&mut self, property: StylusProperty) {
self.properties.push(property);
}
pub fn remove_property(&mut self, index: usize) -> Option<StylusProperty> {
if index < self.properties.len() { Some(self.properties.remove(index)) } else { None }
}
pub fn insert_property(&mut self, index: usize, property: StylusProperty) {
if index <= self.properties.len() {
self.properties.insert(index, property);
}
}
}
impl AcceptVisitor for StylusComment {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
visitor.visit_comment(self)
}
}
impl AcceptVisitor for StylusProperty {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
visitor.visit_property(self)
}
}
impl AcceptVisitor for StylusMixin {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
match visitor.visit_mixin(self) {
VisitResult::Stop => VisitResult::Stop,
VisitResult::SkipChildren => VisitResult::Continue,
VisitResult::Continue => {
for param in &self.params {
if let VisitResult::Stop = param.accept(visitor) {
return VisitResult::Stop;
}
}
for item in &self.body {
if let VisitResult::Stop = item.accept(visitor) {
return VisitResult::Stop;
}
}
VisitResult::Continue
}
}
}
}
impl StylusMixin {
pub fn add_param(&mut self, param: StylusParam) {
self.params.push(param);
}
pub fn add_body_item(&mut self, item: StylusItem) {
self.body.push(item);
}
}
impl AcceptVisitor for StylusVariable {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
visitor.visit_variable(self)
}
}
impl AcceptVisitor for StylusImport {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
visitor.visit_import(self)
}
}
impl AcceptVisitor for StylusFunction {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
match visitor.visit_function(self) {
VisitResult::Stop => VisitResult::Stop,
VisitResult::SkipChildren => VisitResult::Continue,
VisitResult::Continue => {
for param in &self.params {
if let VisitResult::Stop = param.accept(visitor) {
return VisitResult::Stop;
}
}
for item in &self.body {
if let VisitResult::Stop = item.accept(visitor) {
return VisitResult::Stop;
}
}
VisitResult::Continue
}
}
}
}
impl StylusFunction {
pub fn add_param(&mut self, param: StylusParam) {
self.params.push(param);
}
pub fn add_body_item(&mut self, item: StylusItem) {
self.body.push(item);
}
pub fn set_return_value(&mut self, return_value: Option<String>) {
self.return_value = return_value;
}
}
impl AcceptVisitor for StylusIf {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
match visitor.visit_if(self) {
VisitResult::Stop => VisitResult::Stop,
VisitResult::SkipChildren => VisitResult::Continue,
VisitResult::Continue => {
for item in &self.body {
if let VisitResult::Stop = item.accept(visitor) {
return VisitResult::Stop;
}
}
if let Some(else_items) = &self.else_clause {
for item in else_items {
if let VisitResult::Stop = item.accept(visitor) {
return VisitResult::Stop;
}
}
}
VisitResult::Continue
}
}
}
}
impl StylusIf {
pub fn add_body_item(&mut self, item: StylusItem) {
self.body.push(item);
}
pub fn add_else_item(&mut self, item: StylusItem) {
if self.else_clause.is_none() {
self.else_clause = Some(Vec::new());
}
if let Some(else_items) = &mut self.else_clause {
else_items.push(item);
}
}
}
impl AcceptVisitor for StylusFor {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
match visitor.visit_for(self) {
VisitResult::Stop => VisitResult::Stop,
VisitResult::SkipChildren => VisitResult::Continue,
VisitResult::Continue => {
for item in &self.body {
if let VisitResult::Stop = item.accept(visitor) {
return VisitResult::Stop;
}
}
VisitResult::Continue
}
}
}
}
impl StylusFor {
pub fn add_body_item(&mut self, item: StylusItem) {
self.body.push(item);
}
}
impl AcceptVisitor for StylusWhile {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
match visitor.visit_while(self) {
VisitResult::Stop => VisitResult::Stop,
VisitResult::SkipChildren => VisitResult::Continue,
VisitResult::Continue => {
for item in &self.body {
if let VisitResult::Stop = item.accept(visitor) {
return VisitResult::Stop;
}
}
VisitResult::Continue
}
}
}
}
impl StylusWhile {
pub fn add_body_item(&mut self, item: StylusItem) {
self.body.push(item);
}
}
impl AcceptVisitor for StylusParam {
fn accept(&self, visitor: &mut impl StylusVisitor) -> VisitResult {
visitor.visit_param(self)
}
}
impl<'a> TypedNode<'a> for StylusRoot {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), items: Vec::new() })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusRoot::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusItem {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
if let Some(rule) = StylusRule::cast(node.clone()) {
Some(Self::Rule(rule))
}
else if let Some(comment) = StylusComment::cast(node.clone()) {
Some(Self::Comment(comment))
}
else if let Some(mixin) = StylusMixin::cast(node.clone()) {
Some(Self::Mixin(mixin))
}
else if let Some(variable) = StylusVariable::cast(node.clone()) {
Some(Self::Variable(variable))
}
else if let Some(import) = StylusImport::cast(node.clone()) {
Some(Self::Import(import))
}
else if let Some(function) = StylusFunction::cast(node.clone()) {
Some(Self::Function(function))
}
else if let Some(if_stmt) = StylusIf::cast(node.clone()) {
Some(Self::If(if_stmt))
}
else if let Some(for_stmt) = StylusFor::cast(node.clone()) {
Some(Self::For(for_stmt))
}
else if let Some(while_stmt) = StylusWhile::cast(node.clone()) {
Some(Self::While(while_stmt))
}
else {
None
}
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusItem::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusRule {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), selector: String::new(), properties: Vec::new() })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusRule::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusComment {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
Some(Self { span: node.span().into(), text: String::new() })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusComment::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusProperty {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), name: String::new(), value: String::new() })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusProperty::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusMixin {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), name: String::new(), params: Vec::new(), body: Vec::new() })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusMixin::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusVariable {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), name: String::new(), value: String::new() })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusVariable::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusImport {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
Some(Self { span: node.span().into(), path: String::new() })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusImport::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusFunction {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), name: String::new(), params: Vec::new(), body: Vec::new(), return_value: None })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusFunction::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusIf {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), condition: String::new(), body: Vec::new(), else_clause: None })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusIf::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusFor {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), variable: String::new(), range: String::new(), body: Vec::new() })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusFor::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusWhile {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), condition: String::new(), body: Vec::new() })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusWhile::green() not implemented")
}
}
impl<'a> TypedNode<'a> for StylusParam {
type Language = crate::StylusLanguage;
fn cast(node: RedNode<'a, Self::Language>) -> Option<Self> {
let children: Vec<_> = node.children().collect();
Some(Self { span: node.span().into(), name: String::new(), default: None })
}
fn green(&self) -> &'a GreenNode<'a, Self::Language> {
panic!("StylusParam::green() not implemented")
}
}