Browse Source

Add new quantity_cast function

David Peter 8 months ago
parent
commit
fa18ae5762

+ 17 - 0
book/src/list-functions-other.md

@@ -260,6 +260,23 @@ fn unit_name<T: Dim>(quantity: T) -> String
 
 </details>
 
+### `quantity_cast`
+Unsafe function that returns the quantity `from` unmodified with the target dimension `To`. This can be useful in generic code, but should generally be avoided otherwise.
+
+```nbt
+fn quantity_cast<From: Dim, To: Dim>(f: From, t: To) -> To
+```
+
+<details>
+<summary>Examples</summary>
+
+<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code"  onclick=" window.open('https://numbat.dev/?q=quantity%5Fcast%281%20nm%2C%20m%29')""></button></div><code class="language-nbt hljs numbat">quantity_cast(1 nm, m)
+
+    = 1 nm    [Length]
+</code></pre>
+
+</details>
+
 ## Chemical elements
 
 Defined in: `chemistry::elements`

+ 6 - 0
examples/tests/core.nbt

@@ -50,6 +50,12 @@ assert_eq(unit_name(1), "")
 assert_eq(unit_name(1 m), "m")
 assert_eq(unit_name(1 m^2/s), "m²/s")
 
+# quantity_cast
+
+assert_eq(quantity_cast(1 m, m), 1 m)
+assert_eq(quantity_cast(1 nm, m), 1 nm)
+assert_eq(quantity_cast(0, m), 0)
+
 # round, round_in
 
 assert_eq(round(1.234), 1)

+ 6 - 0
numbat/modules/core/quantities.nbt

@@ -25,3 +25,9 @@ fn is_dimensionless<T: Dim>(quantity: T) -> Bool
 @example("unit_name(20 m^2)")
 @example("unit_name(20 km/h)")
 fn unit_name<T: Dim>(quantity: T) -> String
+
+# TODO: Once we support explicitly passing arguments to type parameters, we can remove the second argument and
+# replace this with `fn quantity_cast<To: Dim, From: Dim>(f: From) -> To` and call it with `quantity_cast::<Length>(…)`.
+@description("Unsafe function that returns the quantity `from` unmodified with the target dimension `To`. This can be useful in generic code, but should generally be avoided otherwise.")
+@example("quantity_cast(1 nm, m)")
+fn quantity_cast<From: Dim, To: Dim>(f: From, t: To) -> To

+ 8 - 0
numbat/src/ffi/functions.rs

@@ -42,6 +42,7 @@ pub(crate) fn functions() -> &'static HashMap<String, ForeignFunction> {
         insert_function!(has_unit, 2..=2);
         insert_function!(is_dimensionless, 1..=1);
         insert_function!(unit_name, 1..=1);
+        insert_function!(quantity_cast, 2..=2);
 
         // Math
         insert_function!("mod", mod_, 2..=2);
@@ -148,3 +149,10 @@ fn unit_name(mut args: Args) -> Result<Value> {
 
     return_string!(from = &quantity.unit().to_string())
 }
+
+fn quantity_cast(mut args: Args) -> Result<Value> {
+    let value_from = quantity_arg!(args);
+    let _ = quantity_arg!(args);
+
+    Ok(Value::Quantity(value_from))
+}