diff --git a/src/parse/mod.rs b/src/parse/mod.rs index a534f9e..d63cc2d 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -149,32 +149,67 @@ impl<'a> Parser<'a> { let Spanned { node: module, span } = self.parse_quoted_string(quote)?; let module = module.unquote().to_css_string(span)?; - if let Some(Token { kind: ';', .. }) = self.toks.peek() { - self.toks.next(); - } else { - todo!() + self.whitespace_or_comment(); + + let mut module_name: Option = None; + + match self.toks.peek() { + Some(Token { kind: ';', .. }) => { + self.toks.next(); + } + Some(Token { kind: 'a', .. }) | Some(Token { kind: 'A', .. }) => { + let mut ident = + peek_ident_no_interpolation(self.toks, false, self.span_before)?; + ident.node.make_ascii_lowercase(); + if ident.node != "as" { + return Err(("expected \";\".", ident.span).into()); + } + + self.whitespace_or_comment(); + + let name = self.parse_identifier_no_interpolation(false)?; + + module_name = Some(name.node); + + if !matches!(self.toks.next(), Some(Token { kind: ';', .. })) { + return Err(("expected \";\".", name.span).into()); + } + } + Some(Token { kind: 'w', .. }) | Some(Token { kind: 'W', .. }) => { + todo!("with") + } + Some(..) | None => return Err(("expected \";\".", span).into()), } match module.as_ref() { - "sass:color" => self - .modules - .insert("color".to_owned(), declare_module_color()), - "sass:list" => self - .modules - .insert("list".to_owned(), declare_module_list()), - "sass:map" => self.modules.insert("map".to_owned(), declare_module_map()), - "sass:math" => self - .modules - .insert("math".to_owned(), declare_module_math()), - "sass:meta" => self - .modules - .insert("meta".to_owned(), declare_module_meta()), - "sass:selector" => self - .modules - .insert("selector".to_owned(), declare_module_selector()), - "sass:string" => self - .modules - .insert("string".to_owned(), declare_module_string()), + "sass:color" => self.modules.insert( + module_name.unwrap_or("color".to_owned()), + declare_module_color(), + ), + "sass:list" => self.modules.insert( + module_name.unwrap_or("list".to_owned()), + declare_module_list(), + ), + "sass:map" => self.modules.insert( + module_name.unwrap_or("map".to_owned()), + declare_module_map(), + ), + "sass:math" => self.modules.insert( + module_name.unwrap_or("math".to_owned()), + declare_module_math(), + ), + "sass:meta" => self.modules.insert( + module_name.unwrap_or("meta".to_owned()), + declare_module_meta(), + ), + "sass:selector" => self.modules.insert( + module_name.unwrap_or("selector".to_owned()), + declare_module_selector(), + ), + "sass:string" => self.modules.insert( + module_name.unwrap_or("string".to_owned()), + declare_module_string(), + ), _ => todo!("@use not yet implemented"), }; } diff --git a/tests/use.rs b/tests/use.rs index e673c9f..7a53bff 100644 --- a/tests/use.rs +++ b/tests/use.rs @@ -10,3 +10,34 @@ error!( ", "Error: @use rules must be written before any other rules." ); +error!( + interpolation_in_as_identifier, + "@use \"sass:math\" as m#{a}th;", + "Error: expected \";\"." +); +error!( + use_as_quoted_string, + "@use \"sass:math\" as \"math\";", + "Error: Expected identifier." +); +error!( + use_as_missing_s, + "@use \"sass:math\" a math;", + "Error: expected \";\"." +); +test!( + use_as, + "@use \"sass:math\" as foo; + a { + color: foo.clamp(0, 1, 2); + }", + "a {\n color: 1;\n}\n" +); +test!( + use_as_uppercase, + "@use \"sass:math\" AS foo; + a { + color: foo.clamp(0, 1, 2); + }", + "a {\n color: 1;\n}\n" +);