2024-08-21 12:12:56 -07:00
|
|
|
//! Functions related to unitsematics.
|
|
|
|
|
|
|
|
use anyhow::Result;
|
2025-03-01 13:59:01 -08:00
|
|
|
use kcl_derive_docs::stdlib;
|
2024-08-21 12:12:56 -07:00
|
|
|
|
2024-09-16 15:10:33 -04:00
|
|
|
use crate::{
|
|
|
|
errors::KclError,
|
2025-03-21 10:56:55 +13:00
|
|
|
execution::{types::UnitLen, ExecState, KclValue},
|
2024-09-16 15:10:33 -04:00
|
|
|
std::Args,
|
|
|
|
};
|
2024-08-21 12:12:56 -07:00
|
|
|
|
|
|
|
/// Millimeters conversion factor for current projects units.
|
2025-01-17 07:55:01 +13:00
|
|
|
pub async fn mm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
|
|
let result = inner_mm(exec_state)?;
|
2024-08-21 12:12:56 -07:00
|
|
|
|
2024-11-14 17:27:19 -06:00
|
|
|
Ok(args.make_user_val_from_f64(result))
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Millimeters conversion factor for current projects units.
|
|
|
|
///
|
|
|
|
/// No matter what units the current project uses, this function will always return the conversion
|
|
|
|
/// factor to millimeters.
|
|
|
|
///
|
|
|
|
/// For example, if the current project uses inches, this function will return `(1/25.4)`.
|
|
|
|
/// If the current project uses millimeters, this function will return `1`.
|
|
|
|
///
|
|
|
|
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
|
|
|
/// have different units in your code than the project settings. Otherwise, it is
|
|
|
|
/// a bad pattern to use this function.
|
|
|
|
///
|
|
|
|
/// We merely provide these functions for convenience and readability, as
|
|
|
|
/// `10 * mm()` is more readable that your intent is "I want 10 millimeters" than
|
|
|
|
/// `10 * (1/25.4)`, if the project settings are in inches.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2024-12-12 11:33:37 -05:00
|
|
|
/// totalWidth = 10 * mm()
|
2024-08-21 12:12:56 -07:00
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "mm",
|
|
|
|
tags = ["units"],
|
|
|
|
}]
|
2025-01-17 07:55:01 +13:00
|
|
|
fn inner_mm(exec_state: &ExecState) -> Result<f64, KclError> {
|
|
|
|
match exec_state.length_unit() {
|
|
|
|
UnitLen::Mm => Ok(1.0),
|
|
|
|
UnitLen::Inches => Ok(measurements::Length::from_millimeters(1.0).as_inches()),
|
|
|
|
UnitLen::Feet => Ok(measurements::Length::from_millimeters(1.0).as_feet()),
|
|
|
|
UnitLen::M => Ok(measurements::Length::from_millimeters(1.0).as_meters()),
|
|
|
|
UnitLen::Cm => Ok(measurements::Length::from_millimeters(1.0).as_centimeters()),
|
|
|
|
UnitLen::Yards => Ok(measurements::Length::from_millimeters(1.0).as_yards()),
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Inches conversion factor for current projects units.
|
2025-01-17 07:55:01 +13:00
|
|
|
pub async fn inch(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
|
|
let result = inner_inch(exec_state)?;
|
2024-08-21 12:12:56 -07:00
|
|
|
|
2024-11-14 17:27:19 -06:00
|
|
|
Ok(args.make_user_val_from_f64(result))
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Inches conversion factor for current projects units.
|
|
|
|
///
|
|
|
|
/// No matter what units the current project uses, this function will always return the conversion
|
|
|
|
/// factor to inches.
|
|
|
|
///
|
|
|
|
/// For example, if the current project uses inches, this function will return `1`.
|
|
|
|
/// If the current project uses millimeters, this function will return `25.4`.
|
|
|
|
///
|
|
|
|
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
|
|
|
/// have different units in your code than the project settings. Otherwise, it is
|
|
|
|
/// a bad pattern to use this function.
|
|
|
|
///
|
|
|
|
/// We merely provide these functions for convenience and readability, as
|
|
|
|
/// `10 * inch()` is more readable that your intent is "I want 10 inches" than
|
|
|
|
/// `10 * 25.4`, if the project settings are in millimeters.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2024-12-12 11:33:37 -05:00
|
|
|
/// totalWidth = 10 * inch()
|
2024-08-21 12:12:56 -07:00
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "inch",
|
|
|
|
tags = ["units"],
|
|
|
|
}]
|
2025-01-17 07:55:01 +13:00
|
|
|
fn inner_inch(exec_state: &ExecState) -> Result<f64, KclError> {
|
|
|
|
match exec_state.length_unit() {
|
|
|
|
UnitLen::Mm => Ok(measurements::Length::from_inches(1.0).as_millimeters()),
|
|
|
|
UnitLen::Inches => Ok(1.0),
|
|
|
|
UnitLen::Feet => Ok(measurements::Length::from_inches(1.0).as_feet()),
|
|
|
|
UnitLen::M => Ok(measurements::Length::from_inches(1.0).as_meters()),
|
|
|
|
UnitLen::Cm => Ok(measurements::Length::from_inches(1.0).as_centimeters()),
|
|
|
|
UnitLen::Yards => Ok(measurements::Length::from_inches(1.0).as_yards()),
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Feet conversion factor for current projects units.
|
2025-01-17 07:55:01 +13:00
|
|
|
pub async fn ft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
|
|
let result = inner_ft(exec_state)?;
|
2024-08-21 12:12:56 -07:00
|
|
|
|
2024-11-14 17:27:19 -06:00
|
|
|
Ok(args.make_user_val_from_f64(result))
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Feet conversion factor for current projects units.
|
|
|
|
///
|
|
|
|
/// No matter what units the current project uses, this function will always return the conversion
|
|
|
|
/// factor to feet.
|
|
|
|
///
|
|
|
|
/// For example, if the current project uses inches, this function will return `12`.
|
|
|
|
/// If the current project uses millimeters, this function will return `304.8`.
|
|
|
|
/// If the current project uses feet, this function will return `1`.
|
|
|
|
///
|
|
|
|
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
|
|
|
/// have different units in your code than the project settings. Otherwise, it is
|
|
|
|
/// a bad pattern to use this function.
|
|
|
|
///
|
|
|
|
/// We merely provide these functions for convenience and readability, as
|
|
|
|
/// `10 * ft()` is more readable that your intent is "I want 10 feet" than
|
|
|
|
/// `10 * 304.8`, if the project settings are in millimeters.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2024-12-12 11:33:37 -05:00
|
|
|
/// totalWidth = 10 * ft()
|
2024-08-21 12:12:56 -07:00
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "ft",
|
|
|
|
tags = ["units"],
|
|
|
|
}]
|
2025-01-17 07:55:01 +13:00
|
|
|
fn inner_ft(exec_state: &ExecState) -> Result<f64, KclError> {
|
|
|
|
match exec_state.length_unit() {
|
|
|
|
UnitLen::Mm => Ok(measurements::Length::from_feet(1.0).as_millimeters()),
|
|
|
|
UnitLen::Inches => Ok(measurements::Length::from_feet(1.0).as_inches()),
|
|
|
|
UnitLen::Feet => Ok(1.0),
|
|
|
|
UnitLen::M => Ok(measurements::Length::from_feet(1.0).as_meters()),
|
|
|
|
UnitLen::Cm => Ok(measurements::Length::from_feet(1.0).as_centimeters()),
|
|
|
|
UnitLen::Yards => Ok(measurements::Length::from_feet(1.0).as_yards()),
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Meters conversion factor for current projects units.
|
2025-01-17 07:55:01 +13:00
|
|
|
pub async fn m(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
|
|
let result = inner_m(exec_state)?;
|
2024-08-21 12:12:56 -07:00
|
|
|
|
2024-11-14 17:27:19 -06:00
|
|
|
Ok(args.make_user_val_from_f64(result))
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Meters conversion factor for current projects units.
|
|
|
|
///
|
|
|
|
/// No matter what units the current project uses, this function will always return the conversion
|
|
|
|
/// factor to meters.
|
|
|
|
///
|
|
|
|
/// For example, if the current project uses inches, this function will return `39.3701`.
|
|
|
|
/// If the current project uses millimeters, this function will return `1000`.
|
|
|
|
/// If the current project uses meters, this function will return `1`.
|
|
|
|
///
|
|
|
|
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
|
|
|
/// have different units in your code than the project settings. Otherwise, it is
|
|
|
|
/// a bad pattern to use this function.
|
|
|
|
///
|
|
|
|
/// We merely provide these functions for convenience and readability, as
|
|
|
|
/// `10 * m()` is more readable that your intent is "I want 10 meters" than
|
|
|
|
/// `10 * 1000`, if the project settings are in millimeters.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2024-12-12 11:33:37 -05:00
|
|
|
/// totalWidth = 10 * m()
|
2024-08-21 12:12:56 -07:00
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "m",
|
|
|
|
tags = ["units"],
|
|
|
|
}]
|
2025-01-17 07:55:01 +13:00
|
|
|
fn inner_m(exec_state: &ExecState) -> Result<f64, KclError> {
|
|
|
|
match exec_state.length_unit() {
|
|
|
|
UnitLen::Mm => Ok(measurements::Length::from_meters(1.0).as_millimeters()),
|
|
|
|
UnitLen::Inches => Ok(measurements::Length::from_meters(1.0).as_inches()),
|
|
|
|
UnitLen::Feet => Ok(measurements::Length::from_meters(1.0).as_feet()),
|
|
|
|
UnitLen::M => Ok(1.0),
|
|
|
|
UnitLen::Cm => Ok(measurements::Length::from_meters(1.0).as_centimeters()),
|
|
|
|
UnitLen::Yards => Ok(measurements::Length::from_meters(1.0).as_yards()),
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Centimeters conversion factor for current projects units.
|
2025-01-17 07:55:01 +13:00
|
|
|
pub async fn cm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
|
|
let result = inner_cm(exec_state)?;
|
2024-08-21 12:12:56 -07:00
|
|
|
|
2024-11-14 17:27:19 -06:00
|
|
|
Ok(args.make_user_val_from_f64(result))
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Centimeters conversion factor for current projects units.
|
|
|
|
///
|
|
|
|
/// No matter what units the current project uses, this function will always return the conversion
|
|
|
|
/// factor to centimeters.
|
|
|
|
///
|
|
|
|
/// For example, if the current project uses inches, this function will return `0.393701`.
|
|
|
|
/// If the current project uses millimeters, this function will return `10`.
|
|
|
|
/// If the current project uses centimeters, this function will return `1`.
|
|
|
|
///
|
|
|
|
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
|
|
|
/// have different units in your code than the project settings. Otherwise, it is
|
|
|
|
/// a bad pattern to use this function.
|
|
|
|
///
|
|
|
|
/// We merely provide these functions for convenience and readability, as
|
|
|
|
/// `10 * cm()` is more readable that your intent is "I want 10 centimeters" than
|
|
|
|
/// `10 * 10`, if the project settings are in millimeters.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2024-12-12 11:33:37 -05:00
|
|
|
/// totalWidth = 10 * cm()
|
2024-08-21 12:12:56 -07:00
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "cm",
|
|
|
|
tags = ["units"],
|
|
|
|
}]
|
2025-01-17 07:55:01 +13:00
|
|
|
fn inner_cm(exec_state: &ExecState) -> Result<f64, KclError> {
|
|
|
|
match exec_state.length_unit() {
|
|
|
|
UnitLen::Mm => Ok(measurements::Length::from_centimeters(1.0).as_millimeters()),
|
|
|
|
UnitLen::Inches => Ok(measurements::Length::from_centimeters(1.0).as_inches()),
|
|
|
|
UnitLen::Feet => Ok(measurements::Length::from_centimeters(1.0).as_feet()),
|
|
|
|
UnitLen::M => Ok(measurements::Length::from_centimeters(1.0).as_meters()),
|
|
|
|
UnitLen::Cm => Ok(1.0),
|
|
|
|
UnitLen::Yards => Ok(measurements::Length::from_centimeters(1.0).as_yards()),
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Yards conversion factor for current projects units.
|
2025-01-17 07:55:01 +13:00
|
|
|
pub async fn yd(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
|
|
let result = inner_yd(exec_state)?;
|
2024-08-21 12:12:56 -07:00
|
|
|
|
2024-11-14 17:27:19 -06:00
|
|
|
Ok(args.make_user_val_from_f64(result))
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Yards conversion factor for current projects units.
|
|
|
|
///
|
|
|
|
/// No matter what units the current project uses, this function will always return the conversion
|
|
|
|
/// factor to yards.
|
|
|
|
///
|
|
|
|
/// For example, if the current project uses inches, this function will return `36`.
|
|
|
|
/// If the current project uses millimeters, this function will return `914.4`.
|
|
|
|
/// If the current project uses yards, this function will return `1`.
|
|
|
|
///
|
|
|
|
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
|
|
|
/// have different units in your code than the project settings. Otherwise, it is
|
|
|
|
/// a bad pattern to use this function.
|
|
|
|
///
|
|
|
|
/// We merely provide these functions for convenience and readability, as
|
|
|
|
/// `10 * yd()` is more readable that your intent is "I want 10 yards" than
|
|
|
|
/// `10 * 914.4`, if the project settings are in millimeters.
|
|
|
|
///
|
|
|
|
/// ```no_run
|
2024-12-12 11:33:37 -05:00
|
|
|
/// totalWidth = 10 * yd()
|
2024-08-21 12:12:56 -07:00
|
|
|
/// ```
|
|
|
|
#[stdlib {
|
|
|
|
name = "yd",
|
|
|
|
tags = ["units"],
|
|
|
|
}]
|
2025-01-17 07:55:01 +13:00
|
|
|
fn inner_yd(exec_state: &ExecState) -> Result<f64, KclError> {
|
|
|
|
match exec_state.length_unit() {
|
|
|
|
UnitLen::Mm => Ok(measurements::Length::from_yards(1.0).as_millimeters()),
|
|
|
|
UnitLen::Inches => Ok(measurements::Length::from_yards(1.0).as_inches()),
|
|
|
|
UnitLen::Feet => Ok(measurements::Length::from_yards(1.0).as_feet()),
|
|
|
|
UnitLen::M => Ok(measurements::Length::from_yards(1.0).as_meters()),
|
|
|
|
UnitLen::Cm => Ok(measurements::Length::from_yards(1.0).as_centimeters()),
|
|
|
|
UnitLen::Yards => Ok(1.0),
|
2024-08-21 12:12:56 -07:00
|
|
|
}
|
|
|
|
}
|