tailwind_ast/ast/
mod.rs

1mod display;
2mod from_str;
3mod methods;
4mod parse;
5#[cfg(test)]
6mod tests;
7use nom::{
8    branch::alt,
9    bytes::complete::{tag, take_till1},
10    character::complete::{alphanumeric1, char, multispace1},
11    combinator::opt,
12    error::Error,
13    multi::{many0, separated_list0},
14    sequence::{delimited, tuple},
15    Err, IResult,
16};
17use std::{
18    fmt::{Display, Formatter},
19    ops::{Add, AddAssign},
20};
21
22/// Decompose a string into tailwind instructions
23pub fn parse_tailwind(input: &str) -> Result<Vec<AstStyle>, Err<Error<&str>>> {
24    let rest = many0(tuple((multispace1, AstGroupItem::parse)));
25    let (head, groups) = match tuple((AstGroupItem::parse, rest))(input.trim()) {
26        Ok(o) => o.1,
27        Err(e) => return Err(e),
28    };
29    let mut out = vec![];
30    head.expand(&mut out);
31    for (_, g) in groups {
32        g.expand(&mut out)
33    }
34    Ok(out)
35}
36
37/// `variant:ast-style(grouped)`
38#[derive(Clone, Debug, PartialEq)]
39pub struct AstGroup<'a> {
40    /// Is a `!important` group
41    pub important: bool,
42    ///
43    pub head: AstStyle<'a>,
44    ///
45    pub children: Vec<AstGroupItem<'a>>,
46}
47
48/// One of [`AstGroup`] and [`AstStyle`]
49#[derive(Clone, Debug, PartialEq)]
50pub enum AstGroupItem<'a> {
51    /// Is grouped node can be expand
52    Grouped(AstGroup<'a>),
53    /// Is standalone ast node
54    Styled(AstStyle<'a>),
55}
56
57/// `not-variant:pseudo::-ast-element-[arbitrary]`
58#[derive(Clone, Debug, PartialEq)]
59pub struct AstStyle<'a> {
60    /// Is a `!important` style
61    pub important: bool,
62    /// Is a negative style
63    pub negative: bool,
64    ///
65    pub variants: Vec<ASTVariant<'a>>,
66    ///
67    pub elements: Vec<&'a str>,
68    /// Is a arbitrary value
69    pub arbitrary: Option<&'a str>,
70}
71
72/// `-[.+]`
73#[derive(Clone, Debug, PartialEq)]
74pub struct AstArbitrary<'a> {
75    /// The arbitrary value text
76    pub arbitrary: &'a str,
77}
78
79/// `ast-elements`
80#[derive(Clone, Debug, PartialEq, Default)]
81pub struct AstElements<'a> {
82    /// `name-space`
83    pub elements: Vec<&'a str>,
84}
85
86/// `&`
87#[derive(Copy, Clone, Debug, PartialEq)]
88pub struct AstReference {}
89
90/// `!`
91#[derive(Copy, Clone, Debug, PartialEq)]
92pub struct AstImportant {}
93
94/// `(not-)?variant:pseudo::`
95#[derive(Clone, Debug, PartialEq)]
96pub struct ASTVariant<'a> {
97    /// `not-`
98    pub not: bool,
99    /// `::`
100    pub pseudo: bool,
101    /// `name-space`
102    pub names: Vec<&'a str>,
103}