Skip to main content

oak_tailwind/ast/
mod.rs

1#![doc = include_str!("readme.md")]
2use core::range::Range;
3
4/// The root node of a Tailwind document.
5#[derive(Debug, Clone, PartialEq, Eq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub struct TailwindRoot {
8    /// The span of the entire root.
9    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
10    pub span: Range<usize>,
11    /// The children of the root.
12    pub children: Vec<TailwindNode>,
13}
14
15/// A node in the Tailwind AST.
16#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub enum TailwindNode {
19    /// A CSS directive (e.g., @tailwind base).
20    Directive(TailwindDirective),
21    /// A utility class (e.g., bg-red-500).
22    Class(TailwindClass),
23    /// A comment.
24    Comment(TailwindComment),
25}
26
27/// A Tailwind class (e.g., hover:bg-red-500, !p-4).
28#[derive(Debug, Clone, PartialEq, Eq)]
29#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
30pub struct TailwindClass {
31    /// The span of the entire class.
32    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
33    pub span: Range<usize>,
34    /// Whether the class has an important flag (!).
35    pub is_important: bool,
36    /// The modifiers applied to the class.
37    pub modifiers: Vec<TailwindModifier>,
38    /// The kind of class (utility or arbitrary value).
39    pub kind: TailwindClassKind,
40}
41
42/// The kind of Tailwind class.
43#[derive(Debug, Clone, PartialEq, Eq)]
44#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
45pub enum TailwindClassKind {
46    /// A utility class (e.g., `bg-red-500`).
47    Utility(TailwindUtility),
48    /// An arbitrary value (e.g., `[100px]`).
49    ArbitraryValue(TailwindArbitraryValue),
50}
51
52/// A Tailwind modifier (e.g., hover:).
53#[derive(Debug, Clone, PartialEq, Eq)]
54#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
55pub struct TailwindModifier {
56    /// The span of the modifier.
57    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
58    pub span: Range<usize>,
59    /// The name of the modifier.
60    pub name: String,
61}
62
63/// A Tailwind utility (e.g., bg-red-500).
64#[derive(Debug, Clone, PartialEq, Eq)]
65#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
66pub struct TailwindUtility {
67    /// The span of the utility.
68    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
69    pub span: Range<usize>,
70    /// The name of the utility.
71    pub name: String,
72}
73
74/// A Tailwind arbitrary value (e.g., [100px]).
75#[derive(Debug, Clone, PartialEq, Eq)]
76#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
77pub struct TailwindArbitraryValue {
78    /// The span of the arbitrary value.
79    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
80    pub span: Range<usize>,
81    /// The value inside the brackets.
82    pub value: String,
83}
84
85/// A Tailwind directive (e.g., @tailwind base).
86#[derive(Debug, Clone, PartialEq, Eq)]
87#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
88pub struct TailwindDirective {
89    /// The span of the directive.
90    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
91    pub span: Range<usize>,
92    /// The name of the directive (e.g., "tailwind").
93    pub name: String,
94    /// The optional body of the directive (e.g., "base").
95    pub body: Option<String>,
96}
97
98/// A Tailwind comment.
99#[derive(Debug, Clone, PartialEq, Eq)]
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101pub struct TailwindComment {
102    /// The span of the comment.
103    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
104    pub span: Range<usize>,
105    /// The content of the comment.
106    pub content: String,
107}
108
109impl TailwindRoot {
110    /// Creates a new Tailwind root node with the given span.
111    pub fn new(span: Range<usize>, children: Vec<TailwindNode>) -> Self {
112        Self { span, children }
113    }
114}