diff --git a/Cargo.toml b/Cargo.toml index 665372c..bfd1b77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ repository = "https://github.com/connorskees/grass" authors = ["ConnorSkees <39542938+ConnorSkees@users.noreply.github.com>"] edition = "2018" exclude = ["*.scss", "sass-spec", "tests", "Cargo.lock"] +default-run = "grass" [[bin]] name = "grass" @@ -19,6 +20,7 @@ required-features = ["commandline"] [lib] name = "grass" path = "src/lib.rs" +crate-type = ["cdylib", "rlib"] [dependencies] clap = { version = "2.33.0", optional = true } @@ -29,6 +31,7 @@ once_cell = "1.3.1" rand = { version = "0.7.3", optional = true } codemap = "0.1.3" peekmore = "0.4.0" +wasm-bindgen = { version = "0.2.60", optional = true } [features] default = ["commandline", "random"] @@ -38,6 +41,8 @@ commandline = ["clap"] nightly = [] # Option (enabled by default): enable the builtin functions `random([$limit])` and `unique-id()` random = ["rand"] +# Option: compile to web assembly +wasm = ["wasm-bindgen"] [dev-dependencies] tempfile = "3" diff --git a/src/lib.rs b/src/lib.rs index 4a97cae..d769c67 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,6 +88,9 @@ use codemap::{CodeMap, Span, Spanned}; use peekmore::{PeekMore, PeekMoreIterator}; +#[cfg(feature = "wasm")] +use wasm_bindgen::prelude::*; + use crate::atrule::{eat_include, AtRule, AtRuleKind, Function, Mixin}; pub use crate::error::{SassError, SassResult}; use crate::imports::import; @@ -124,6 +127,7 @@ mod utils; mod value; /// Represents a parsed SASS stylesheet with nesting +#[cfg_attr(feature = "wasm", wasm_bindgen)] #[derive(Debug, Clone)] pub struct StyleSheet(Vec>); @@ -188,6 +192,28 @@ fn raw_to_parse_error(map: &CodeMap, err: SassError) -> SassError { SassError::from_loc(message, map.look_up_span(span)) } +#[cfg(feature = "wasm")] +#[wasm_bindgen] +impl StyleSheet { + pub fn new(input: String) -> Result { + let mut map = CodeMap::new(); + let file = map.add_file("stdin".into(), input); + Ok(Css::from_stylesheet(StyleSheet( + StyleSheetParser { + lexer: Lexer::new(&file).peekmore(), + nesting: 0, + map: &map, + } + .parse_toplevel() + .map_err(|e| raw_to_parse_error(&map, e).to_string())? + .0, + )) + .map_err(|e| raw_to_parse_error(&map, e).to_string())? + .pretty_print() + .map_err(|e| raw_to_parse_error(&map, e).to_string())?) + } +} + impl StyleSheet { /// Write CSS to `buf`, constructed from a string /// @@ -201,6 +227,7 @@ impl StyleSheet { /// } /// ``` #[inline] + #[cfg(not(feature = "wasm"))] pub fn new(input: String) -> SassResult { let mut map = CodeMap::new(); let file = map.add_file("stdin".into(), input); @@ -230,6 +257,7 @@ impl StyleSheet { /// } /// ``` #[inline] + #[cfg(not(feature = "wasm"))] pub fn from_path + Into + Clone>(p: P) -> SassResult { let mut map = CodeMap::new(); let file = map.add_file(p.clone().into(), String::from_utf8(fs::read(p)?)?);