2024-07-26 15:14:51 -04:00
|
|
|
//! Standard library assert functions.
|
|
|
|
|
|
|
|
use anyhow::Result;
|
2025-03-01 13:59:01 -08:00
|
|
|
use kcl_derive_docs::stdlib;
|
2024-07-26 15:14:51 -04:00
|
|
|
|
|
|
|
use crate::{
|
|
|
|
errors::{KclError, KclErrorDetails},
|
2025-02-21 12:36:21 +13:00
|
|
|
execution::{ExecState, KclValue},
|
2024-07-26 15:14:51 -04:00
|
|
|
std::Args,
|
|
|
|
};
|
|
|
|
|
2025-04-14 05:58:19 -04:00
|
|
|
use super::args::TyF64;
|
|
|
|
|
2024-07-26 15:14:51 -04:00
|
|
|
async fn _assert(value: bool, message: &str, args: &Args) -> Result<(), KclError> {
|
|
|
|
if !value {
|
|
|
|
return Err(KclError::Type(KclErrorDetails {
|
|
|
|
message: format!("assert failed: {}", message),
|
|
|
|
source_ranges: vec![args.source_range],
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check that the provided value is true, or raise a [KclError]
|
|
|
|
/// with the provided description.
|
2024-09-16 15:10:33 -04:00
|
|
|
pub async fn assert(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
2024-07-26 15:14:51 -04:00
|
|
|
let (data, description): (bool, String) = args.get_data()?;
|
|
|
|
inner_assert(data, &description, &args).await?;
|
2025-02-21 12:36:21 +13:00
|
|
|
Ok(KclValue::none())
|
2024-07-26 15:14:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Check a value at runtime, and raise an error if the argument provided
|
|
|
|
/// is false.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2024-12-12 11:33:37 -05:00
|
|
|
/// myVar = true
|
2024-07-26 15:14:51 -04:00
|
|
|
/// assert(myVar, "should always be true")
|
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "assert",
|
|
|
|
}]
|
|
|
|
async fn inner_assert(data: bool, message: &str, args: &Args) -> Result<(), KclError> {
|
|
|
|
_assert(data, message, args).await
|
|
|
|
}
|
|
|
|
|
2024-09-16 15:10:33 -04:00
|
|
|
pub async fn assert_lt(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
2025-04-14 05:58:19 -04:00
|
|
|
let (left, right, description): (TyF64, TyF64, String) = args.get_data()?;
|
|
|
|
inner_assert_lt(left.n, right.n, &description, &args).await?;
|
2025-02-21 12:36:21 +13:00
|
|
|
Ok(KclValue::none())
|
2024-07-26 15:14:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Check that a numerical value is less than to another at runtime,
|
|
|
|
/// otherwise raise an error.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// assertLessThan(1, 2, "1 is less than 2")
|
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "assertLessThan",
|
|
|
|
}]
|
|
|
|
async fn inner_assert_lt(left: f64, right: f64, message: &str, args: &Args) -> Result<(), KclError> {
|
|
|
|
_assert(left < right, message, args).await
|
|
|
|
}
|
|
|
|
|
2024-09-16 15:10:33 -04:00
|
|
|
pub async fn assert_gt(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
2025-04-14 05:58:19 -04:00
|
|
|
let (left, right, description): (TyF64, TyF64, String) = args.get_data()?;
|
|
|
|
inner_assert_gt(left.n, right.n, &description, &args).await?;
|
2025-02-21 12:36:21 +13:00
|
|
|
Ok(KclValue::none())
|
2024-07-26 15:14:51 -04:00
|
|
|
}
|
|
|
|
|
2024-08-05 11:31:58 -05:00
|
|
|
/// Check that a numerical value equals another at runtime,
|
|
|
|
/// otherwise raise an error.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2024-12-12 11:33:37 -05:00
|
|
|
/// n = 1.0285
|
|
|
|
/// o = 1.0286
|
2024-08-21 12:12:56 -07:00
|
|
|
/// assertEqual(n, o, 0.01, "n is within the given tolerance for o")
|
2024-08-05 11:31:58 -05:00
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "assertEqual",
|
|
|
|
}]
|
|
|
|
async fn inner_assert_equal(left: f64, right: f64, epsilon: f64, message: &str, args: &Args) -> Result<(), KclError> {
|
2024-10-29 13:51:10 +11:00
|
|
|
if epsilon <= 0.0 {
|
|
|
|
Err(KclError::Type(KclErrorDetails {
|
2024-10-29 09:39:50 -05:00
|
|
|
message: "assertEqual epsilon must be greater than zero".to_owned(),
|
2024-10-29 13:51:10 +11:00
|
|
|
source_ranges: vec![args.source_range],
|
|
|
|
}))
|
|
|
|
} else if (right - left).abs() < epsilon {
|
2024-09-16 12:43:49 -04:00
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(KclError::Type(KclErrorDetails {
|
|
|
|
message: format!("assert failed because {left} != {right}: {message}"),
|
|
|
|
source_ranges: vec![args.source_range],
|
|
|
|
}))
|
|
|
|
}
|
2024-08-05 11:31:58 -05:00
|
|
|
}
|
|
|
|
|
2024-09-16 15:10:33 -04:00
|
|
|
pub async fn assert_equal(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
2025-04-14 05:58:19 -04:00
|
|
|
let (left, right, epsilon, description): (TyF64, TyF64, TyF64, String) = args.get_data()?;
|
|
|
|
inner_assert_equal(left.n, right.n, epsilon.n, &description, &args).await?;
|
2025-02-21 12:36:21 +13:00
|
|
|
Ok(KclValue::none())
|
2024-08-05 11:31:58 -05:00
|
|
|
}
|
|
|
|
|
2024-07-26 15:14:51 -04:00
|
|
|
/// Check that a numerical value is greater than another at runtime,
|
|
|
|
/// otherwise raise an error.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// assertGreaterThan(2, 1, "2 is greater than 1")
|
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "assertGreaterThan",
|
|
|
|
}]
|
|
|
|
async fn inner_assert_gt(left: f64, right: f64, message: &str, args: &Args) -> Result<(), KclError> {
|
|
|
|
_assert(left > right, message, args).await
|
|
|
|
}
|
|
|
|
|
2024-09-16 15:10:33 -04:00
|
|
|
pub async fn assert_lte(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
2025-04-14 05:58:19 -04:00
|
|
|
let (left, right, description): (TyF64, TyF64, String) = args.get_data()?;
|
|
|
|
inner_assert_lte(left.n, right.n, &description, &args).await?;
|
2025-02-21 12:36:21 +13:00
|
|
|
Ok(KclValue::none())
|
2024-07-26 15:14:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Check that a numerical value is less than or equal to another at runtime,
|
|
|
|
/// otherwise raise an error.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// assertLessThanOrEq(1, 2, "1 is less than 2")
|
|
|
|
/// assertLessThanOrEq(1, 1, "1 is equal to 1")
|
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "assertLessThanOrEq",
|
|
|
|
}]
|
|
|
|
async fn inner_assert_lte(left: f64, right: f64, message: &str, args: &Args) -> Result<(), KclError> {
|
|
|
|
_assert(left <= right, message, args).await
|
|
|
|
}
|
|
|
|
|
2024-09-16 15:10:33 -04:00
|
|
|
pub async fn assert_gte(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
2025-04-14 05:58:19 -04:00
|
|
|
let (left, right, description): (TyF64, TyF64, String) = args.get_data()?;
|
|
|
|
inner_assert_gte(left.n, right.n, &description, &args).await?;
|
2025-02-21 12:36:21 +13:00
|
|
|
Ok(KclValue::none())
|
2024-07-26 15:14:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Check that a numerical value is greater than or equal to another at runtime,
|
|
|
|
/// otherwise raise an error.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
|
|
|
/// assertGreaterThanOrEq(2, 1, "2 is greater than 1")
|
|
|
|
/// assertGreaterThanOrEq(1, 1, "1 is equal to 1")
|
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "assertGreaterThanOrEq",
|
|
|
|
}]
|
|
|
|
async fn inner_assert_gte(left: f64, right: f64, message: &str, args: &Args) -> Result<(), KclError> {
|
|
|
|
_assert(left >= right, message, args).await
|
|
|
|
}
|