Skip to content

Commit

Permalink
Merge PR #126: calc-args and calc-name.
Browse files Browse the repository at this point in the history
Impement `sass:meta` functions `calc-args` and `calc-name`
  • Loading branch information
kaj authored Dec 10, 2021
2 parents 94b2bd0 + 41fef76 commit 7f9eb1f
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 48 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ project adheres to
to 0..100%).
* `sass:selector` functions `append`, `nest`, and `parse` are closer
to correct (PR #123).
* `sass:meta` functions `calc-args` and `calc-name` implemented (PR #126).
* Css strings and selectors can now be parsed directly (PR #123).
* Fixed reformatting of to-much-indented comments.
* Fixed panics in some color arithmetic (Issue #120, #121, #122, PR #125).
Expand Down
1 change: 1 addition & 0 deletions src/css/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ impl Value {
pub fn type_name(&self) -> &'static str {
match *self {
Value::ArgList(..) => "arglist",
Value::Call(..) => "calculation",
Value::Color(..) => "color",
Value::Literal(..) => "string",
Value::Map(..) => "map",
Expand Down
21 changes: 3 additions & 18 deletions src/sass/functions/color/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::{
check, expected_to, get_checked, get_opt_check, is_not, CheckedArg,
Error, FunctionMap,
check, expected_to, get_checked, get_opt_check, is_not, is_special,
CheckedArg, Error, FunctionMap,
};
use crate::css::{CallArgs, CssString, Value};
use crate::css::{CallArgs, Value};
use crate::output::Format;
use crate::parser::SourcePos;
use crate::sass::{ArgsError, FormalArgs, Name};
Expand Down Expand Up @@ -163,21 +163,6 @@ fn num2chan(v: &Numeric) -> Result<Rational, String> {
}
}

fn is_special(v: &Value) -> bool {
match v {
Value::Call(..) => true,
Value::Literal(s) if looks_like_call(s) => true,
Value::BinOp(..) => true,
_ => false,
}
}

fn looks_like_call(s: &CssString) -> bool {
s.quotes().is_none()
&& s.value().contains('(')
&& s.value().ends_with(')')
}

fn make_call(name: &str, args: Vec<Value>) -> Value {
Value::Call(
name.into(),
Expand Down
5 changes: 4 additions & 1 deletion src/sass/functions/math.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{
check, expected_to, get_checked, get_numeric, get_opt_check, get_va_list,
is_not, CheckedArg, Error, FunctionMap, Scope,
is_not, is_special, CheckedArg, Error, FunctionMap, Scope,
};
use crate::css::{CallArgs, CssString, Value};
use crate::output::Format;
Expand Down Expand Up @@ -284,6 +284,9 @@ fn find_extreme(v: &[Value], pref: Ordering) -> Result<Value, Error> {
CallArgs::from_list(v.to_vec()),
)
};
if v.iter().any(is_special) {
return Ok(as_call());
}
match find_extreme_inner(v, pref) {
Ok(Some(v)) => Ok(v.into()),
Ok(None) => {
Expand Down
28 changes: 26 additions & 2 deletions src/sass/functions/meta.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use super::{
check, get_checked, get_opt_check, get_string, is_not, CheckedArg, Error,
FunctionMap,
check, get_checked, get_opt_check, get_string, is_not, looks_like_call,
CheckedArg, Error, FunctionMap,
};
use crate::css::{CallArgs, CssString, Value};
use crate::sass::{Function, Mixin, Name};
use crate::value::Quotes;
use crate::{Format, Scope, ScopeRef};

pub fn create_module() -> Scope {
Expand All @@ -12,6 +13,29 @@ pub fn create_module() -> Scope {
// TODO: load_css

// - - - Functions - - -
def!(f, calc_args(calc), |s| {
get_checked(s, name!(calc), |v| match v {
Value::Call(_, args) => Ok(args.into()),
Value::Literal(s) if looks_like_call(&s) => {
let s = s.value();
let i = s.find('(').unwrap();
Ok(s[i + 1..s.len() - 1].into())
}
v => Err(is_not(&v, "a calculation")),
})
});
def!(f, calc_name(calc), |s| {
let name = get_checked(s, name!(calc), |v| match v {
Value::Call(name, _) => Ok(name),
Value::Literal(s) if looks_like_call(&s) => {
let s = s.value();
let i = s.find('(').unwrap();
Ok(s[..i].to_string())
}
v => Err(is_not(&v, "a calculation")),
})?;
Ok(CssString::new(name, Quotes::Double).into())
});
def_va!(f, call(function, args), |s| {
let (function, name) = match s.get("function")? {
Value::Function(ref name, ref func) => {
Expand Down
15 changes: 15 additions & 0 deletions src/sass/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,21 @@ where
)
}

fn is_special(v: &Value) -> bool {
match v {
Value::Call(..) => true,
Value::Literal(s) if looks_like_call(s) => true,
Value::BinOp(..) => true,
_ => false,
}
}

fn looks_like_call(s: &CssString) -> bool {
s.quotes().is_none()
&& s.value().contains('(')
&& s.value().ends_with(')')
}

mod check {
use super::{expected_to, is_not};
use crate::css::{CssString, Value};
Expand Down
16 changes: 0 additions & 16 deletions tests/spec/core_functions/meta/calc_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ mod error {
use super::runner;

#[test]
#[ignore] // wrong error
fn invalid_args() {
assert_eq!(
runner().err(
Expand All @@ -26,7 +25,6 @@ mod error {
);
}
#[test]
#[ignore] // wrong error
fn too_few_args() {
assert_eq!(
runner().err(
Expand All @@ -46,7 +44,6 @@ mod error {
);
}
#[test]
#[ignore] // wrong error
fn too_many_args() {
assert_eq!(
runner().err(
Expand All @@ -71,7 +68,6 @@ mod multi_args {
use super::runner;

#[test]
#[ignore] // unexepected error
fn first() {
assert_eq!(
runner().ok("@use \"sass:list\";\
Expand All @@ -83,7 +79,6 @@ mod multi_args {
);
}
#[test]
#[ignore] // unexepected error
fn length() {
assert_eq!(
runner().ok("@use \"sass:list\";\
Expand All @@ -95,7 +90,6 @@ mod multi_args {
);
}
#[test]
#[ignore] // unexepected error
fn second() {
assert_eq!(
runner().ok("@use \"sass:list\";\
Expand All @@ -107,7 +101,6 @@ mod multi_args {
);
}
#[test]
#[ignore] // unexepected error
fn third() {
assert_eq!(
runner().ok("@use \"sass:list\";\
Expand All @@ -120,7 +113,6 @@ mod multi_args {
}
}
#[test]
#[ignore] // unexepected error
fn named() {
assert_eq!(
runner().ok("@use \"sass:meta\";\
Expand All @@ -135,7 +127,6 @@ mod one_arg {
use super::runner;

#[test]
#[ignore] // unexepected error
fn first() {
assert_eq!(
runner().ok("@use \"sass:list\";\
Expand All @@ -147,7 +138,6 @@ mod one_arg {
);
}
#[test]
#[ignore] // unexepected error
fn length() {
assert_eq!(
runner().ok("@use \"sass:list\";\
Expand All @@ -164,7 +154,6 @@ mod test_type {
use super::runner;

#[test]
#[ignore] // unexepected error
fn calculation() {
assert_eq!(
runner().ok(
Expand All @@ -178,7 +167,6 @@ mod test_type {
);
}
#[test]
#[ignore] // unexepected error
fn css_function() {
assert_eq!(
runner().ok(
Expand All @@ -192,7 +180,6 @@ mod test_type {
);
}
#[test]
#[ignore] // unexepected error
fn interpolation() {
assert_eq!(
runner().ok(
Expand All @@ -206,7 +193,6 @@ mod test_type {
);
}
#[test]
#[ignore] // unexepected error
fn math() {
assert_eq!(
runner().ok(
Expand All @@ -220,7 +206,6 @@ mod test_type {
);
}
#[test]
#[ignore] // unexepected error
fn number() {
assert_eq!(
runner().ok(
Expand All @@ -234,7 +219,6 @@ mod test_type {
);
}
#[test]
#[ignore] // unexepected error
fn string_variable() {
assert_eq!(
runner().ok("@use \"sass:list\";\
Expand Down
8 changes: 0 additions & 8 deletions tests/spec/core_functions/meta/calc_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner {
}

#[test]
#[ignore] // unexepected error
fn calc() {
assert_eq!(
runner().ok("@use \"sass:meta\";\
Expand All @@ -17,7 +16,6 @@ fn calc() {
);
}
#[test]
#[ignore] // unexepected error
fn clamp() {
assert_eq!(
runner().ok("@use \"sass:meta\";\
Expand All @@ -32,7 +30,6 @@ mod error {
use super::runner;

#[test]
#[ignore] // wrong error
fn invalid_args() {
assert_eq!(
runner().err(
Expand All @@ -48,7 +45,6 @@ mod error {
);
}
#[test]
#[ignore] // wrong error
fn too_few_args() {
assert_eq!(
runner().err(
Expand All @@ -68,7 +64,6 @@ mod error {
);
}
#[test]
#[ignore] // wrong error
fn too_many_args() {
assert_eq!(
runner().err(
Expand All @@ -89,7 +84,6 @@ mod error {
}
}
#[test]
#[ignore] // unexepected error
fn max() {
assert_eq!(
runner().ok("@use \"sass:meta\";\
Expand All @@ -100,7 +94,6 @@ fn max() {
);
}
#[test]
#[ignore] // unexepected error
fn min() {
assert_eq!(
runner().ok("@use \"sass:meta\";\
Expand All @@ -111,7 +104,6 @@ fn min() {
);
}
#[test]
#[ignore] // unexepected error
fn named() {
assert_eq!(
runner().ok("@use \"sass:meta\";\
Expand Down
1 change: 0 additions & 1 deletion tests/spec/core_functions/meta/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ mod calculation {
);
}
#[test]
#[ignore] // wrong result
fn clamp() {
assert_eq!(
runner().ok("a {b: type-of(clamp(1%, 1px, 2px))}\n"),
Expand Down
2 changes: 1 addition & 1 deletion tests/spec/values/calculation/max.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ mod error {
use super::runner;

#[test]
#[ignore] // wrong error
#[ignore] // missing error
fn in_calc() {
assert_eq!(
runner().err("a {b: max(calc(1px + 2))}\n"),
Expand Down
2 changes: 1 addition & 1 deletion tests/spec/values/calculation/min.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ mod error {
use super::runner;

#[test]
#[ignore] // wrong error
#[ignore] // missing error
fn in_calc() {
assert_eq!(
runner().err("a {b: min(calc(1px + 2))}\n"),
Expand Down

0 comments on commit 7f9eb1f

Please sign in to comment.