logo
  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
mod methods;
mod setter;
use crate::{systems::instruction::TailwindInstruction, *};
use std::{collections::BTreeSet, fmt::Debug};

#[derive(Debug)]
pub struct TailwindBuilder {
    // pub apply: BTreeMap<String, CssAttributes>,
    pub obfuscate: bool,
    pub objects: BTreeSet<Box<dyn TailwindInstance>>,
    pub preflight: PreflightSystem,
    pub palettes: PaletteSystem,
    pub screens: BreakPointSystem,
    pub fonts: FontSystem,
}

impl TailwindBuilder {
    /// ## Inline mode(no bundle)
    ///
    ///
    /// # Returns
    ///
    /// - Anonymous style sheets, which can be placed inside `style` tags
    ///
    /// ## Example
    /// - input
    /// ```html
    /// <div class="p-auto px-px pt-2 pb-2">Test</div>
    /// ```
    /// - output
    /// ```html
    /// <div class="p-auto px-px pt-2 pb-2">Test</div>
    /// <style> {} </style>
    /// ```
    #[inline]
    #[track_caller]
    pub fn trace(&mut self, style: &str) -> String {
        self.try_trace(style).unwrap()
    }
    /// Safe version of [`TailwindBuilder::trace`]
    pub fn try_trace(&mut self, style: &str) -> Result<String> {
        let parsed = parse_tailwind(style)?;
        let out: Vec<String> = parsed.iter().map(|s| s.id()).collect();
        for i in parsed.into_iter() {
            self.objects.insert(i.get_instance()?);
        }
        Ok(out.join(" "))
    }

    /// ## Inline mode(no bundle)
    ///
    ///
    /// # Returns
    ///
    /// - Anonymous style sheets, which can be placed inside `style` tags
    ///
    /// ## Example
    /// - input
    /// ```html
    /// <div class="p-auto px-px pt-2 pb-2">Test</div>
    /// ```
    /// - output
    /// ```html
    /// <div class="p-auto px-px pt-2 pb-2">Test</div>
    /// <style> {} </style>
    /// ```
    #[inline]
    #[track_caller]
    pub fn scope(&self, style: &str) {
        let _id = style;
    }
    /// Safe version of [`TailwindBuilder::scope`]
    pub fn try_scope() {}

    /// ## Inline mode(no bundle)
    ///
    ///
    /// # Returns
    ///
    /// - Anonymous style sheets, which can be placed inside `style` tags
    ///
    /// ## Example
    /// - input
    /// ```html
    /// <div class="p-auto px-px pt-2 pb-2">Test</div>
    /// ```
    /// - output
    /// ```html
    /// <div class="p-auto px-px pt-2 pb-2">Test</div>
    /// <style> {} </style>
    /// ```
    #[inline]
    #[track_caller]
    pub fn dataset() {}

    /// ## Inline mode(no bundle)
    ///
    ///
    /// # Returns
    /// **Not all instructions can be inline, if not, it will fall back to trace mode**
    ///
    /// - Anonymous style sheets, which can be placed inside `style` tags
    ///
    /// ## Example
    /// - input
    /// ```html
    /// <div class="p-auto px-px pt-2 pb-2">Test</div>
    /// ```
    /// - output
    /// ```html
    /// <div class="p-auto px-px pt-2 pb-2">Test</div>
    /// <style> {} </style>
    /// ```
    #[inline]
    #[track_caller]
    pub fn inline(&mut self, style: &str) -> String {
        self.try_inline(style).unwrap()
    }
    /// Safe version of [`TailwindBuilder::inline`]
    pub fn try_inline(&mut self, style: &str) -> Result<String> {
        let parsed = parse_tailwind(style)?;
        let mut set = BTreeSet::new();
        for item in parsed {
            // match item.inlineable() {
            //     true => {}
            //     false => {}
            // }
            set.extend(item.attributes(self))
        }
        let vec: Vec<_> = set.into_iter().map(|s| s.to_string()).collect();
        Ok(vec.join(""))
    }
    /// Bundle all used stylesheets
    #[inline]
    #[track_caller]
    pub fn bundle(&self) -> String {
        self.try_bundle(1024 * 10).unwrap()
    }
    /// Safe version of [`TailwindBuilder::bundle`]
    pub fn try_bundle(&self, cap: usize) -> Result<String> {
        let mut out = String::with_capacity(cap);
        self.preflight.write_css(&mut out, self)?;
        for item in &self.objects {
            item.write_css(&mut out, self)?;
        }
        Ok(out)
    }
}

fn parse_tailwind(input: &str) -> Result<Vec<TailwindInstruction>> {
    let styles = tailwind_ast::parse_tailwind(input)?;
    Ok(styles.into_iter().map(TailwindInstruction::from).collect())
}