Change unit conversion functions to operate on input rather than return a conversion factor (#6181)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
@ -138,12 +138,12 @@ lazy_static! {
|
||||
Box::new(crate::std::math::Ln),
|
||||
Box::new(crate::std::math::ToDegrees),
|
||||
Box::new(crate::std::math::ToRadians),
|
||||
Box::new(crate::std::units::Mm),
|
||||
Box::new(crate::std::units::Inch),
|
||||
Box::new(crate::std::units::Ft),
|
||||
Box::new(crate::std::units::M),
|
||||
Box::new(crate::std::units::Cm),
|
||||
Box::new(crate::std::units::Yd),
|
||||
Box::new(crate::std::units::FromMm),
|
||||
Box::new(crate::std::units::FromInches),
|
||||
Box::new(crate::std::units::FromFt),
|
||||
Box::new(crate::std::units::FromM),
|
||||
Box::new(crate::std::units::FromCm),
|
||||
Box::new(crate::std::units::FromYd),
|
||||
Box::new(crate::std::assert::Assert),
|
||||
Box::new(crate::std::assert::AssertEqual),
|
||||
Box::new(crate::std::assert::AssertLessThan),
|
||||
|
@ -9,252 +9,258 @@ use crate::{
|
||||
std::{args::TyF64, Args},
|
||||
};
|
||||
|
||||
/// Millimeters conversion factor for current projects units.
|
||||
pub async fn mm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_mm(exec_state)?;
|
||||
/// Millimeters conversion factor for current files units.
|
||||
pub async fn from_mm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let input = args.get_number()?;
|
||||
let result = inner_from_mm(input, exec_state)?;
|
||||
|
||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
||||
}
|
||||
|
||||
/// Millimeters conversion factor for current projects units.
|
||||
/// Converts a number from mm to the current default unit.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to millimeters.
|
||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||
/// to the input in 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`.
|
||||
/// For example, if the current file uses inches, `fromMm(1)` will return `1/25.4`.
|
||||
/// If the current file uses millimeters, `fromMm(1)` 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
|
||||
/// have different units in your code than the file 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.
|
||||
/// `fromMm(10)` is more readable that your intent is "I want 10 millimeters" than
|
||||
/// `10 * (1/25.4)`, if the file settings are in inches.
|
||||
///
|
||||
/// ```no_run
|
||||
/// totalWidth = 10 * mm()
|
||||
/// totalWidth = fromMm(10)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "mm",
|
||||
name = "fromMm",
|
||||
tags = ["units"],
|
||||
}]
|
||||
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()),
|
||||
}
|
||||
fn inner_from_mm(input: f64, exec_state: &ExecState) -> Result<f64, KclError> {
|
||||
Ok(match exec_state.length_unit() {
|
||||
UnitLen::Mm => input,
|
||||
UnitLen::Inches => measurements::Length::from_millimeters(input).as_inches(),
|
||||
UnitLen::Feet => measurements::Length::from_millimeters(input).as_feet(),
|
||||
UnitLen::M => measurements::Length::from_millimeters(input).as_meters(),
|
||||
UnitLen::Cm => measurements::Length::from_millimeters(input).as_centimeters(),
|
||||
UnitLen::Yards => measurements::Length::from_millimeters(input).as_yards(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Inches conversion factor for current projects units.
|
||||
pub async fn inch(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_inch(exec_state)?;
|
||||
/// Inches conversion factor for current files units.
|
||||
pub async fn from_inches(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let input = args.get_number()?;
|
||||
let result = inner_from_inches(input, exec_state)?;
|
||||
|
||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
||||
}
|
||||
|
||||
/// Inches conversion factor for current projects units.
|
||||
/// Converts a number from inches to the current default unit.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to inches.
|
||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||
/// to the input in 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`.
|
||||
/// For example, if the current file uses inches, `fromInches(1)` will return `1`.
|
||||
/// If the current file uses millimeters, `fromInches(1)` 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
|
||||
/// have different units in your code than the file 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.
|
||||
/// `fromInches(10)` is more readable that your intent is "I want 10 inches" than
|
||||
/// `10 * 25.4`, if the file settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// totalWidth = 10 * inch()
|
||||
/// totalWidth = fromInches(10)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "inch",
|
||||
name = "fromInches",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_inch(exec_state: &ExecState) -> Result<f64, KclError> {
|
||||
fn inner_from_inches(input: f64, 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()),
|
||||
UnitLen::Mm => Ok(measurements::Length::from_inches(input).as_millimeters()),
|
||||
UnitLen::Inches => Ok(input),
|
||||
UnitLen::Feet => Ok(measurements::Length::from_inches(input).as_feet()),
|
||||
UnitLen::M => Ok(measurements::Length::from_inches(input).as_meters()),
|
||||
UnitLen::Cm => Ok(measurements::Length::from_inches(input).as_centimeters()),
|
||||
UnitLen::Yards => Ok(measurements::Length::from_inches(input).as_yards()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Feet conversion factor for current projects units.
|
||||
pub async fn ft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_ft(exec_state)?;
|
||||
/// Feet conversion factor for current files units.
|
||||
pub async fn from_ft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let input = args.get_number()?;
|
||||
let result = inner_from_ft(input, exec_state)?;
|
||||
|
||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
||||
}
|
||||
|
||||
/// Feet conversion factor for current projects units.
|
||||
/// Converts a number from feet to the current default unit.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to feet.
|
||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||
/// to the input in 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`.
|
||||
/// For example, if the current file uses inches, `fromFt(1)` will return `12`.
|
||||
/// If the current file uses millimeters, `fromFt(1)` will return `304.8`.
|
||||
/// If the current file uses feet, `fromFt(1)` 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
|
||||
/// have different units in your code than the file 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.
|
||||
/// `fromFt(10)` is more readable that your intent is "I want 10 feet" than
|
||||
/// `10 * 304.8`, if the file settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// totalWidth = 10 * ft()
|
||||
/// totalWidth = fromFt(10)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "ft",
|
||||
name = "fromFt",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_ft(exec_state: &ExecState) -> Result<f64, KclError> {
|
||||
fn inner_from_ft(input: f64, 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()),
|
||||
UnitLen::Mm => Ok(measurements::Length::from_feet(input).as_millimeters()),
|
||||
UnitLen::Inches => Ok(measurements::Length::from_feet(input).as_inches()),
|
||||
UnitLen::Feet => Ok(input),
|
||||
UnitLen::M => Ok(measurements::Length::from_feet(input).as_meters()),
|
||||
UnitLen::Cm => Ok(measurements::Length::from_feet(input).as_centimeters()),
|
||||
UnitLen::Yards => Ok(measurements::Length::from_feet(input).as_yards()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Meters conversion factor for current projects units.
|
||||
pub async fn m(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_m(exec_state)?;
|
||||
/// Meters conversion factor for current files units.
|
||||
pub async fn from_m(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let input = args.get_number()?;
|
||||
let result = inner_from_m(input, exec_state)?;
|
||||
|
||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
||||
}
|
||||
|
||||
/// Meters conversion factor for current projects units.
|
||||
/// Converts a number from meters to the current default unit.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to meters.
|
||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||
/// to the input in 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`.
|
||||
/// For example, if the current file uses inches, `fromM(1)` will return `39.3701`.
|
||||
/// If the current file uses millimeters, `fromM(1)` will return `1000`.
|
||||
/// If the current file uses meters, `fromM(1)` 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
|
||||
/// have different units in your code than the file 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.
|
||||
/// `fromM(10)` is more readable that your intent is "I want 10 meters" than
|
||||
/// `10 * 1000`, if the file settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// totalWidth = 10 * m()
|
||||
/// totalWidth = 10 * fromM(10)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "m",
|
||||
name = "fromM",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_m(exec_state: &ExecState) -> Result<f64, KclError> {
|
||||
fn inner_from_m(input: f64, 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()),
|
||||
UnitLen::Mm => Ok(measurements::Length::from_meters(input).as_millimeters()),
|
||||
UnitLen::Inches => Ok(measurements::Length::from_meters(input).as_inches()),
|
||||
UnitLen::Feet => Ok(measurements::Length::from_meters(input).as_feet()),
|
||||
UnitLen::M => Ok(input),
|
||||
UnitLen::Cm => Ok(measurements::Length::from_meters(input).as_centimeters()),
|
||||
UnitLen::Yards => Ok(measurements::Length::from_meters(input).as_yards()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Centimeters conversion factor for current projects units.
|
||||
pub async fn cm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_cm(exec_state)?;
|
||||
/// Centimeters conversion factor for current files units.
|
||||
pub async fn from_cm(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let input = args.get_number()?;
|
||||
let result = inner_from_cm(input, exec_state)?;
|
||||
|
||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
||||
}
|
||||
|
||||
/// Centimeters conversion factor for current projects units.
|
||||
/// Converts a number from centimeters to the current default unit.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to centimeters.
|
||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||
/// to the input in 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`.
|
||||
/// For example, if the current file uses inches, `fromCm(1)` will return `0.393701`.
|
||||
/// If the current file uses millimeters, `fromCm(1)` will return `10`.
|
||||
/// If the current file uses centimeters, `fromCm(1)` 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
|
||||
/// have different units in your code than the file 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.
|
||||
/// `fromCm(10)` is more readable that your intent is "I want 10 centimeters" than
|
||||
/// `10 * 10`, if the file settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// totalWidth = 10 * cm()
|
||||
/// totalWidth = fromCm(10)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "cm",
|
||||
name = "fromCm",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_cm(exec_state: &ExecState) -> Result<f64, KclError> {
|
||||
fn inner_from_cm(input: f64, 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()),
|
||||
UnitLen::Mm => Ok(measurements::Length::from_centimeters(input).as_millimeters()),
|
||||
UnitLen::Inches => Ok(measurements::Length::from_centimeters(input).as_inches()),
|
||||
UnitLen::Feet => Ok(measurements::Length::from_centimeters(input).as_feet()),
|
||||
UnitLen::M => Ok(measurements::Length::from_centimeters(input).as_meters()),
|
||||
UnitLen::Cm => Ok(input),
|
||||
UnitLen::Yards => Ok(measurements::Length::from_centimeters(input).as_yards()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Yards conversion factor for current projects units.
|
||||
pub async fn yd(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_yd(exec_state)?;
|
||||
/// Yards conversion factor for current files units.
|
||||
pub async fn from_yd(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let input = args.get_number()?;
|
||||
let result = inner_from_yd(input, exec_state)?;
|
||||
|
||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
||||
}
|
||||
|
||||
/// Yards conversion factor for current projects units.
|
||||
/// Converts a number from yards to the current default unit.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to yards.
|
||||
/// No matter what units the current file uses, this function will always return a number equivalent
|
||||
/// to the input in 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`.
|
||||
/// For example, if the current file uses inches, `fromYd(1)` will return `36`.
|
||||
/// If the current file uses millimeters, `fromYd(1)` will return `914.4`.
|
||||
/// If the current file uses yards, `fromYd(1)` 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
|
||||
/// have different units in your code than the file 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.
|
||||
/// `fromYd(10)` is more readable that your intent is "I want 10 yards" than
|
||||
/// `10 * 914.4`, if the file settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// totalWidth = 10 * yd()
|
||||
/// totalWidth = fromYd(10)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "yd",
|
||||
name = "fromYd",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_yd(exec_state: &ExecState) -> Result<f64, KclError> {
|
||||
fn inner_from_yd(input: f64, 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),
|
||||
UnitLen::Mm => Ok(measurements::Length::from_yards(input).as_millimeters()),
|
||||
UnitLen::Inches => Ok(measurements::Length::from_yards(input).as_inches()),
|
||||
UnitLen::Feet => Ok(measurements::Length::from_yards(input).as_feet()),
|
||||
UnitLen::M => Ok(measurements::Length::from_yards(input).as_meters()),
|
||||
UnitLen::Cm => Ok(measurements::Length::from_yards(input).as_centimeters()),
|
||||
UnitLen::Yards => Ok(input),
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user