Remove the untyped getters from std::args (#7377)

* Move last uses of untypeed arg getters

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Rename _typed functions

Signed-off-by: Nick Cameron <nrc@ncameron.org>

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
Nick Cameron
2025-06-06 10:45:58 +12:00
committed by GitHub
parent 18b458fbca
commit e116bbaae8
24 changed files with 296 additions and 343 deletions

View File

@ -40,6 +40,10 @@ impl RuntimeType {
RuntimeType::Primitive(PrimitiveType::Edge)
}
pub fn function() -> Self {
RuntimeType::Primitive(PrimitiveType::Function)
}
pub fn sketch() -> Self {
RuntimeType::Primitive(PrimitiveType::Sketch)
}
@ -84,6 +88,10 @@ impl RuntimeType {
RuntimeType::Primitive(PrimitiveType::Tag)
}
pub fn tag_decl() -> Self {
RuntimeType::Primitive(PrimitiveType::TagDecl)
}
pub fn tag_identifier() -> Self {
RuntimeType::Primitive(PrimitiveType::TagId)
}
@ -376,8 +384,8 @@ pub enum PrimitiveType {
String,
Boolean,
Tag,
// Annoyingly some functions only want a TagIdentifier, not any kind of tag.
TagId,
TagDecl,
Sketch,
Solid,
Plane,
@ -409,6 +417,7 @@ impl PrimitiveType {
PrimitiveType::ImportedGeometry => "imported geometries".to_owned(),
PrimitiveType::Function => "functions".to_owned(),
PrimitiveType::Tag => "tags".to_owned(),
PrimitiveType::TagDecl => "tag declarators".to_owned(),
PrimitiveType::TagId => "tag identifiers".to_owned(),
}
}
@ -417,7 +426,7 @@ impl PrimitiveType {
match (self, other) {
(_, PrimitiveType::Any) => true,
(PrimitiveType::Number(n1), PrimitiveType::Number(n2)) => n1.subtype(n2),
(PrimitiveType::TagId, PrimitiveType::Tag) => true,
(PrimitiveType::TagId, PrimitiveType::Tag) | (PrimitiveType::TagDecl, PrimitiveType::Tag) => true,
(t1, t2) => t1 == t2,
}
}
@ -434,6 +443,7 @@ impl fmt::Display for PrimitiveType {
PrimitiveType::String => write!(f, "string"),
PrimitiveType::Boolean => write!(f, "bool"),
PrimitiveType::Tag => write!(f, "tag"),
PrimitiveType::TagDecl => write!(f, "tag declarator"),
PrimitiveType::TagId => write!(f, "tag identifier"),
PrimitiveType::Sketch => write!(f, "Sketch"),
PrimitiveType::Solid => write!(f, "Solid"),
@ -1291,6 +1301,10 @@ impl KclValue {
KclValue::TagIdentifier { .. } => Ok(self.clone()),
_ => Err(self.into()),
},
PrimitiveType::TagDecl => match self {
KclValue::TagDeclarator { .. } => Ok(self.clone()),
_ => Err(self.into()),
},
PrimitiveType::Tag => match self {
KclValue::TagDeclarator { .. } | KclValue::TagIdentifier { .. } | KclValue::Uuid { .. } => {
Ok(self.clone())
@ -1490,7 +1504,8 @@ impl KclValue {
Some(RuntimeType::Array(Box::new(ty.clone()), ArrayLen::Known(value.len())))
}
KclValue::TagIdentifier(_) => Some(RuntimeType::Primitive(PrimitiveType::TagId)),
KclValue::TagDeclarator(_) | KclValue::Uuid { .. } => Some(RuntimeType::Primitive(PrimitiveType::Tag)),
KclValue::TagDeclarator(_) => Some(RuntimeType::Primitive(PrimitiveType::TagDecl)),
KclValue::Uuid { .. } => Some(RuntimeType::Primitive(PrimitiveType::Tag)),
KclValue::Function { .. } => Some(RuntimeType::Primitive(PrimitiveType::Function)),
KclValue::Module { .. } | KclValue::KclNone { .. } | KclValue::Type { .. } => None,
}

View File

@ -22,7 +22,7 @@ lazy_static::lazy_static! {
/// Construct a color from its red, blue and green components.
pub async fn hex_string(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let rgb: [TyF64; 3] = args.get_unlabeled_kw_arg_typed(
let rgb: [TyF64; 3] = args.get_unlabeled_kw_arg(
"rgb",
&RuntimeType::Array(Box::new(RuntimeType::count()), ArrayLen::Known(3)),
exec_state,
@ -50,15 +50,15 @@ async fn inner_hex_string(rgb: [TyF64; 3], _: &mut ExecState, args: Args) -> Res
/// Set the appearance of a solid. This only works on solids, not sketches or individual paths.
pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed(
let solids = args.get_unlabeled_kw_arg(
"solids",
&RuntimeType::Union(vec![RuntimeType::solids(), RuntimeType::imported()]),
exec_state,
)?;
let color: String = args.get_kw_arg_typed("color", &RuntimeType::string(), exec_state)?;
let metalness: Option<TyF64> = args.get_kw_arg_opt_typed("metalness", &RuntimeType::count(), exec_state)?;
let roughness: Option<TyF64> = args.get_kw_arg_opt_typed("roughness", &RuntimeType::count(), exec_state)?;
let color: String = args.get_kw_arg("color", &RuntimeType::string(), exec_state)?;
let metalness: Option<TyF64> = args.get_kw_arg_opt("metalness", &RuntimeType::count(), exec_state)?;
let roughness: Option<TyF64> = args.get_kw_arg_opt("roughness", &RuntimeType::count(), exec_state)?;
// Make sure the color if set is valid.
if !HEX_REGEX.is_match(&color) {

View File

@ -109,32 +109,7 @@ impl JsonSchema for TyF64 {
}
impl Args {
/// Get a keyword argument. If not set, returns None.
pub(crate) fn get_kw_arg_opt<'a, T>(&'a self, label: &str) -> Result<Option<T>, KclError>
where
T: FromKclValue<'a>,
{
let Some(arg) = self.kw_args.labeled.get(label) else {
return Ok(None);
};
if let KclValue::KclNone { .. } = arg.value {
// It is set, but it's an optional parameter that wasn't provided.
return Ok(None);
}
T::from_kcl_val(&arg.value).map(Some).ok_or_else(|| {
KclError::new_type(KclErrorDetails::new(
format!(
"The arg {label} was given, but it was the wrong type. It should be type {} but it was {}",
tynm::type_name::<T>(),
arg.value.human_friendly_type(),
),
vec![self.source_range],
))
})
}
pub(crate) fn get_kw_arg_opt_typed<T>(
pub(crate) fn get_kw_arg_opt<T>(
&self,
label: &str,
ty: &RuntimeType,
@ -152,28 +127,10 @@ impl Args {
}
}
self.get_kw_arg_typed(label, ty, exec_state).map(Some)
self.get_kw_arg(label, ty, exec_state).map(Some)
}
/// Get a keyword argument. If not set, returns Err.
pub(crate) fn get_kw_arg<'a, T>(&'a self, label: &str) -> Result<T, KclError>
where
T: FromKclValue<'a>,
{
self.get_kw_arg_opt(label)?.ok_or_else(|| {
KclError::new_semantic(KclErrorDetails::new(
format!("This function requires a keyword argument '{label}'"),
vec![self.source_range],
))
})
}
pub(crate) fn get_kw_arg_typed<T>(
&self,
label: &str,
ty: &RuntimeType,
exec_state: &mut ExecState,
) -> Result<T, KclError>
pub(crate) fn get_kw_arg<T>(&self, label: &str, ty: &RuntimeType, exec_state: &mut ExecState) -> Result<T, KclError>
where
T: for<'a> FromKclValue<'a>,
{
@ -254,7 +211,7 @@ impl Args {
label: &str,
exec_state: &mut ExecState,
) -> Result<(Vec<KclValue>, RuntimeType), KclError> {
let value = self.get_unlabeled_kw_arg_typed(label, &RuntimeType::any_array(), exec_state)?;
let value = self.get_unlabeled_kw_arg(label, &RuntimeType::any_array(), exec_state)?;
Ok(match value {
KclValue::HomArray { value, ty } => (value, ty),
KclValue::Tuple { value, .. } => (value, RuntimeType::any()),
@ -264,7 +221,7 @@ impl Args {
/// Get the unlabeled keyword argument. If not set, returns Err. If it
/// can't be converted to the given type, returns Err.
pub(crate) fn get_unlabeled_kw_arg_typed<T>(
pub(crate) fn get_unlabeled_kw_arg<T>(
&self,
label: &str,
ty: &RuntimeType,
@ -1365,9 +1322,9 @@ impl<'a> FromKclValue<'a> for Box<Solid> {
}
}
impl<'a> FromKclValue<'a> for &'a FunctionSource {
impl<'a> FromKclValue<'a> for FunctionSource {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
arg.as_function()
arg.as_function().cloned()
}
}

View File

@ -14,8 +14,8 @@ use crate::{
/// Apply a function to each element of an array.
pub async fn map(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let array: Vec<KclValue> = args.get_unlabeled_kw_arg_typed("array", &RuntimeType::any_array(), exec_state)?;
let f: &FunctionSource = args.get_kw_arg("f")?;
let array: Vec<KclValue> = args.get_unlabeled_kw_arg("array", &RuntimeType::any_array(), exec_state)?;
let f: FunctionSource = args.get_kw_arg("f", &RuntimeType::function(), exec_state)?;
let new_array = inner_map(array, f, exec_state, &args).await?;
Ok(KclValue::HomArray {
value: new_array,
@ -23,15 +23,15 @@ pub async fn map(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
})
}
async fn inner_map<'a>(
async fn inner_map(
array: Vec<KclValue>,
f: &'a FunctionSource,
f: FunctionSource,
exec_state: &mut ExecState,
args: &'a Args,
args: &Args,
) -> Result<Vec<KclValue>, KclError> {
let mut new_array = Vec::with_capacity(array.len());
for elem in array {
let new_elem = call_map_closure(elem, f, args.source_range, exec_state, &args.ctx).await?;
let new_elem = call_map_closure(elem, &f, args.source_range, exec_state, &args.ctx).await?;
new_array.push(new_elem);
}
Ok(new_array)
@ -68,22 +68,22 @@ async fn call_map_closure(
/// For each item in an array, update a value.
pub async fn reduce(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let array: Vec<KclValue> = args.get_unlabeled_kw_arg_typed("array", &RuntimeType::any_array(), exec_state)?;
let f: &FunctionSource = args.get_kw_arg("f")?;
let initial: KclValue = args.get_kw_arg_typed("initial", &RuntimeType::any(), exec_state)?;
let array: Vec<KclValue> = args.get_unlabeled_kw_arg("array", &RuntimeType::any_array(), exec_state)?;
let f: FunctionSource = args.get_kw_arg("f", &RuntimeType::function(), exec_state)?;
let initial: KclValue = args.get_kw_arg("initial", &RuntimeType::any(), exec_state)?;
inner_reduce(array, initial, f, exec_state, &args).await
}
async fn inner_reduce<'a>(
async fn inner_reduce(
array: Vec<KclValue>,
initial: KclValue,
f: &'a FunctionSource,
f: FunctionSource,
exec_state: &mut ExecState,
args: &'a Args,
args: &Args,
) -> Result<KclValue, KclError> {
let mut reduced = initial;
for elem in array {
reduced = call_reduce_closure(elem, reduced, f, args.source_range, exec_state, &args.ctx).await?;
reduced = call_reduce_closure(elem, reduced, &f, args.source_range, exec_state, &args.ctx).await?;
}
Ok(reduced)
@ -128,7 +128,7 @@ async fn call_reduce_closure(
pub async fn push(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (mut array, ty) = args.get_unlabeled_kw_arg_array_and_type("array", exec_state)?;
let item: KclValue = args.get_kw_arg_typed("item", &RuntimeType::any(), exec_state)?;
let item: KclValue = args.get_kw_arg("item", &RuntimeType::any(), exec_state)?;
array.push(item);

View File

@ -20,8 +20,8 @@ async fn _assert(value: bool, message: &str, args: &Args) -> Result<(), KclError
}
pub async fn assert_is(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let actual = args.get_unlabeled_kw_arg_typed("actual", &RuntimeType::bool(), exec_state)?;
let error = args.get_kw_arg_opt_typed("error", &RuntimeType::string(), exec_state)?;
let actual = args.get_unlabeled_kw_arg("actual", &RuntimeType::bool(), exec_state)?;
let error = args.get_kw_arg_opt("error", &RuntimeType::string(), exec_state)?;
inner_assert_is(actual, error, &args).await?;
Ok(KclValue::none())
}
@ -29,14 +29,14 @@ pub async fn assert_is(exec_state: &mut ExecState, args: Args) -> Result<KclValu
/// Check that the provided value is true, or raise a [KclError]
/// with the provided description.
pub async fn assert(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let actual = args.get_unlabeled_kw_arg_typed("actual", &RuntimeType::num_any(), exec_state)?;
let gt = args.get_kw_arg_opt_typed("isGreaterThan", &RuntimeType::num_any(), exec_state)?;
let lt = args.get_kw_arg_opt_typed("isLessThan", &RuntimeType::num_any(), exec_state)?;
let gte = args.get_kw_arg_opt_typed("isGreaterThanOrEqual", &RuntimeType::num_any(), exec_state)?;
let lte = args.get_kw_arg_opt_typed("isLessThanOrEqual", &RuntimeType::num_any(), exec_state)?;
let eq = args.get_kw_arg_opt_typed("isEqualTo", &RuntimeType::num_any(), exec_state)?;
let tolerance = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::num_any(), exec_state)?;
let error = args.get_kw_arg_opt_typed("error", &RuntimeType::string(), exec_state)?;
let actual = args.get_unlabeled_kw_arg("actual", &RuntimeType::num_any(), exec_state)?;
let gt = args.get_kw_arg_opt("isGreaterThan", &RuntimeType::num_any(), exec_state)?;
let lt = args.get_kw_arg_opt("isLessThan", &RuntimeType::num_any(), exec_state)?;
let gte = args.get_kw_arg_opt("isGreaterThanOrEqual", &RuntimeType::num_any(), exec_state)?;
let lte = args.get_kw_arg_opt("isLessThanOrEqual", &RuntimeType::num_any(), exec_state)?;
let eq = args.get_kw_arg_opt("isEqualTo", &RuntimeType::num_any(), exec_state)?;
let tolerance = args.get_kw_arg_opt("tolerance", &RuntimeType::num_any(), exec_state)?;
let error = args.get_kw_arg_opt("error", &RuntimeType::string(), exec_state)?;
inner_assert(actual, gt, lt, gte, lte, eq, tolerance, error, &args).await?;
Ok(KclValue::none())
}

View File

@ -7,10 +7,7 @@ use kittycad_modeling_cmds as kcmc;
use super::args::TyF64;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
types::{PrimitiveType, RuntimeType},
ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, Solid,
},
execution::{types::RuntimeType, ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, Solid},
parsing::ast::types::TagNode,
std::{fillet::EdgeReference, Args},
};
@ -19,10 +16,10 @@ pub(crate) const DEFAULT_TOLERANCE: f64 = 0.0000001;
/// Create chamfers on tagged paths.
pub async fn chamfer(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid = args.get_unlabeled_kw_arg_typed("solid", &RuntimeType::Primitive(PrimitiveType::Solid), exec_state)?;
let length: TyF64 = args.get_kw_arg_typed("length", &RuntimeType::length(), exec_state)?;
let solid = args.get_unlabeled_kw_arg("solid", &RuntimeType::solid(), exec_state)?;
let length: TyF64 = args.get_kw_arg("length", &RuntimeType::length(), exec_state)?;
let tags = args.kw_arg_edge_array_and_source("tags")?;
let tag = args.get_kw_arg_opt("tag")?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
super::fillet::validate_unique(&tags)?;
let tags: Vec<EdgeReference> = tags.into_iter().map(|item| item.0).collect();

View File

@ -26,7 +26,7 @@ use crate::{
///
/// This works essentially like a copy-paste operation.
pub async fn clone(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let geometry = args.get_unlabeled_kw_arg_typed(
let geometry = args.get_unlabeled_kw_arg(
"geometry",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Sketch),

View File

@ -19,8 +19,8 @@ use crate::{
/// Union two or more solids into a single solid.
pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids: Vec<Solid> =
args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::Union(vec![RuntimeType::solids()]), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
args.get_unlabeled_kw_arg("solids", &RuntimeType::Union(vec![RuntimeType::solids()]), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt("tolerance", &RuntimeType::length(), exec_state)?;
if solids.len() < 2 {
return Err(KclError::new_semantic(KclErrorDetails::new(
@ -84,8 +84,8 @@ pub(crate) async fn inner_union(
/// Intersect returns the shared volume between multiple solids, preserving only
/// overlapping regions.
pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
let solids: Vec<Solid> = args.get_unlabeled_kw_arg("solids", &RuntimeType::solids(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt("tolerance", &RuntimeType::length(), exec_state)?;
if solids.len() < 2 {
return Err(KclError::new_semantic(KclErrorDetails::new(
@ -148,10 +148,10 @@ pub(crate) async fn inner_intersect(
/// Subtract removes tool solids from base solids, leaving the remaining material.
pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
let tools: Vec<Solid> = args.get_kw_arg_typed("tools", &RuntimeType::solids(), exec_state)?;
let solids: Vec<Solid> = args.get_unlabeled_kw_arg("solids", &RuntimeType::solids(), exec_state)?;
let tools: Vec<Solid> = args.get_kw_arg("tools", &RuntimeType::solids(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt("tolerance", &RuntimeType::length(), exec_state)?;
let solids = inner_subtract(solids, tools, tolerance, exec_state, args).await?;
Ok(solids.into())

View File

@ -16,7 +16,7 @@ use crate::{
/// Get the opposite edge to the edge given.
pub async fn get_opposite_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::tag_identifier(), exec_state)?;
let input_edge = args.get_unlabeled_kw_arg("edge", &RuntimeType::tag_identifier(), exec_state)?;
let edge = inner_get_opposite_edge(input_edge, exec_state, args.clone()).await?;
Ok(KclValue::Uuid {
@ -63,7 +63,7 @@ async fn inner_get_opposite_edge(
/// Get the next adjacent edge to the edge given.
pub async fn get_next_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::tag_identifier(), exec_state)?;
let input_edge = args.get_unlabeled_kw_arg("edge", &RuntimeType::tag_identifier(), exec_state)?;
let edge = inner_get_next_adjacent_edge(input_edge, exec_state, args.clone()).await?;
Ok(KclValue::Uuid {
@ -119,7 +119,7 @@ async fn inner_get_next_adjacent_edge(
/// Get the previous adjacent edge to the edge given.
pub async fn get_previous_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::tag_identifier(), exec_state)?;
let input_edge = args.get_unlabeled_kw_arg("edge", &RuntimeType::tag_identifier(), exec_state)?;
let edge = inner_get_previous_adjacent_edge(input_edge, exec_state, args.clone()).await?;
Ok(KclValue::Uuid {
@ -174,7 +174,7 @@ async fn inner_get_previous_adjacent_edge(
/// Get the shared edge between two faces.
pub async fn get_common_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let faces: Vec<TagIdentifier> = args.get_kw_arg_typed(
let faces: Vec<TagIdentifier> = args.get_kw_arg(
"faces",
&RuntimeType::Array(Box::new(RuntimeType::tag_identifier()), ArrayLen::Known(2)),
exec_state,

View File

@ -28,13 +28,13 @@ use crate::{
/// Extrudes by a given amount.
pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let length: TyF64 = args.get_kw_arg_typed("length", &RuntimeType::length(), exec_state)?;
let symmetric = args.get_kw_arg_opt_typed("symmetric", &RuntimeType::bool(), exec_state)?;
let sketches = args.get_unlabeled_kw_arg("sketches", &RuntimeType::sketches(), exec_state)?;
let length: TyF64 = args.get_kw_arg("length", &RuntimeType::length(), exec_state)?;
let symmetric = args.get_kw_arg_opt("symmetric", &RuntimeType::bool(), exec_state)?;
let bidirectional_length: Option<TyF64> =
args.get_kw_arg_opt_typed("bidirectionalLength", &RuntimeType::length(), exec_state)?;
let tag_start = args.get_kw_arg_opt("tagStart")?;
let tag_end = args.get_kw_arg_opt("tagEnd")?;
args.get_kw_arg_opt("bidirectionalLength", &RuntimeType::length(), exec_state)?;
let tag_start = args.get_kw_arg_opt("tagStart", &RuntimeType::tag_decl(), exec_state)?;
let tag_end = args.get_kw_arg_opt("tagEnd", &RuntimeType::tag_decl(), exec_state)?;
let result = inner_extrude(
sketches,

View File

@ -60,11 +60,11 @@ pub(super) fn validate_unique<T: Eq + std::hash::Hash>(tags: &[(T, SourceRange)]
/// Create fillets on tagged paths.
pub async fn fillet(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid = args.get_unlabeled_kw_arg_typed("solid", &RuntimeType::solid(), exec_state)?;
let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
let solid = args.get_unlabeled_kw_arg("solid", &RuntimeType::solid(), exec_state)?;
let radius: TyF64 = args.get_kw_arg("radius", &RuntimeType::length(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt("tolerance", &RuntimeType::length(), exec_state)?;
let tags = args.kw_arg_edge_array_and_source("tags")?;
let tag = args.get_kw_arg_opt("tag")?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
// Run the function.
validate_unique(&tags)?;

View File

@ -16,11 +16,11 @@ use crate::{
/// Create a helix.
pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let angle_start: TyF64 = args.get_kw_arg_typed("angleStart", &RuntimeType::degrees(), exec_state)?;
let revolutions: TyF64 = args.get_kw_arg_typed("revolutions", &RuntimeType::count(), exec_state)?;
let ccw = args.get_kw_arg_opt_typed("ccw", &RuntimeType::bool(), exec_state)?;
let radius: Option<TyF64> = args.get_kw_arg_opt_typed("radius", &RuntimeType::length(), exec_state)?;
let axis: Option<Axis3dOrEdgeReference> = args.get_kw_arg_opt_typed(
let angle_start: TyF64 = args.get_kw_arg("angleStart", &RuntimeType::degrees(), exec_state)?;
let revolutions: TyF64 = args.get_kw_arg("revolutions", &RuntimeType::count(), exec_state)?;
let ccw = args.get_kw_arg_opt("ccw", &RuntimeType::bool(), exec_state)?;
let radius: Option<TyF64> = args.get_kw_arg_opt("radius", &RuntimeType::length(), exec_state)?;
let axis: Option<Axis3dOrEdgeReference> = args.get_kw_arg_opt(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Edge),
@ -28,8 +28,8 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
]),
exec_state,
)?;
let length: Option<TyF64> = args.get_kw_arg_opt_typed("length", &RuntimeType::length(), exec_state)?;
let cylinder = args.get_kw_arg_opt_typed("cylinder", &RuntimeType::solid(), exec_state)?;
let length: Option<TyF64> = args.get_kw_arg_opt("length", &RuntimeType::length(), exec_state)?;
let cylinder = args.get_kw_arg_opt("cylinder", &RuntimeType::solid(), exec_state)?;
// Make sure we have a radius if we don't have a cylinder.
if radius.is_none() && cylinder.is_none() {

View File

@ -21,23 +21,22 @@ const DEFAULT_V_DEGREE: u32 = 2;
/// Create a 3D surface or solid by interpolating between two or more sketches.
pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let sketches = args.get_unlabeled_kw_arg("sketches", &RuntimeType::sketches(), exec_state)?;
let v_degree: NonZeroU32 = args
.get_kw_arg_opt_typed("vDegree", &RuntimeType::count(), exec_state)?
.get_kw_arg_opt("vDegree", &RuntimeType::count(), exec_state)?
.unwrap_or(NonZeroU32::new(DEFAULT_V_DEGREE).unwrap());
// Attempt to approximate rational curves (such as arcs) using a bezier.
// This will remove banding around interpolations between arcs and non-arcs. It may produce errors in other scenarios
// Over time, this field won't be necessary.
let bez_approximate_rational = args
.get_kw_arg_opt_typed("bezApproximateRational", &RuntimeType::bool(), exec_state)?
.get_kw_arg_opt("bezApproximateRational", &RuntimeType::bool(), exec_state)?
.unwrap_or(false);
// This can be set to override the automatically determined topological base curve, which is usually the first section encountered.
let base_curve_index: Option<u32> =
args.get_kw_arg_opt_typed("baseCurveIndex", &RuntimeType::count(), exec_state)?;
let base_curve_index: Option<u32> = args.get_kw_arg_opt("baseCurveIndex", &RuntimeType::count(), exec_state)?;
// Tolerance for the loft operation.
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
let tag_start = args.get_kw_arg_opt("tagStart")?;
let tag_end = args.get_kw_arg_opt("tagEnd")?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt("tolerance", &RuntimeType::length(), exec_state)?;
let tag_start = args.get_kw_arg_opt("tagStart", &RuntimeType::tag_decl(), exec_state)?;
let tag_end = args.get_kw_arg_opt("tagEnd", &RuntimeType::tag_decl(), exec_state)?;
let value = inner_loft(
sketches,

View File

@ -15,8 +15,8 @@ use crate::{
/// Compute the remainder after dividing `num` by `div`.
/// If `num` is negative, the result will be too.
pub async fn rem(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let n: TyF64 = args.get_unlabeled_kw_arg_typed("number to divide", &RuntimeType::num_any(), exec_state)?;
let d: TyF64 = args.get_kw_arg_typed("divisor", &RuntimeType::num_any(), exec_state)?;
let n: TyF64 = args.get_unlabeled_kw_arg("number to divide", &RuntimeType::num_any(), exec_state)?;
let d: TyF64 = args.get_kw_arg("divisor", &RuntimeType::num_any(), exec_state)?;
let (n, d, ty) = NumericType::combine_div(n, d);
if ty == NumericType::Unknown {
@ -32,28 +32,28 @@ pub async fn rem(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
/// Compute the cosine of a number (in radians).
pub async fn cos(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let num: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::angle(), exec_state)?;
let num: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::angle(), exec_state)?;
let num = num.to_radians();
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.cos())))
}
/// Compute the sine of a number (in radians).
pub async fn sin(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let num: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::angle(), exec_state)?;
let num: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::angle(), exec_state)?;
let num = num.to_radians();
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.sin())))
}
/// Compute the tangent of a number (in radians).
pub async fn tan(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let num: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::angle(), exec_state)?;
let num: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::angle(), exec_state)?;
let num = num.to_radians();
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.tan())))
}
/// Compute the square root of a number.
pub async fn sqrt(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
if input.n < 0.0 {
return Err(KclError::new_semantic(KclErrorDetails::new(
@ -72,7 +72,7 @@ pub async fn sqrt(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
/// Compute the absolute value of a number.
pub async fn abs(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
let result = input.n.abs();
Ok(args.make_user_val_from_f64_with_type(input.map_value(result)))
@ -80,7 +80,7 @@ pub async fn abs(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
/// Round a number to the nearest integer.
pub async fn round(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
let result = input.n.round();
Ok(args.make_user_val_from_f64_with_type(input.map_value(result)))
@ -88,7 +88,7 @@ pub async fn round(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// Compute the largest integer less than or equal to a number.
pub async fn floor(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
let result = input.n.floor();
Ok(args.make_user_val_from_f64_with_type(input.map_value(result)))
@ -96,7 +96,7 @@ pub async fn floor(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// Compute the smallest integer greater than or equal to a number.
pub async fn ceil(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
let result = input.n.ceil();
Ok(args.make_user_val_from_f64_with_type(input.map_value(result)))
@ -104,7 +104,7 @@ pub async fn ceil(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
/// Compute the minimum of the given arguments.
pub async fn min(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let nums: Vec<TyF64> = args.get_unlabeled_kw_arg_typed(
let nums: Vec<TyF64> = args.get_unlabeled_kw_arg(
"input",
&RuntimeType::Array(Box::new(RuntimeType::num_any()), ArrayLen::Minimum(1)),
exec_state,
@ -129,7 +129,7 @@ pub async fn min(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
/// Compute the maximum of the given arguments.
pub async fn max(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let nums: Vec<TyF64> = args.get_unlabeled_kw_arg_typed(
let nums: Vec<TyF64> = args.get_unlabeled_kw_arg(
"input",
&RuntimeType::Array(Box::new(RuntimeType::num_any()), ArrayLen::Minimum(1)),
exec_state,
@ -154,8 +154,8 @@ pub async fn max(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
/// Compute the number to a power.
pub async fn pow(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let exp: TyF64 = args.get_kw_arg_typed("exp", &RuntimeType::count(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
let exp: TyF64 = args.get_kw_arg("exp", &RuntimeType::count(), exec_state)?;
let result = input.n.powf(exp.n);
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
@ -163,7 +163,7 @@ pub async fn pow(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
/// Compute the arccosine of a number (in radians).
pub async fn acos(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::count(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::count(), exec_state)?;
let result = input.n.acos();
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
@ -171,7 +171,7 @@ pub async fn acos(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
/// Compute the arcsine of a number (in radians).
pub async fn asin(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::count(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::count(), exec_state)?;
let result = input.n.asin();
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
@ -179,7 +179,7 @@ pub async fn asin(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
/// Compute the arctangent of a number (in radians).
pub async fn atan(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::count(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::count(), exec_state)?;
let result = input.n.atan();
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::radians())))
@ -187,8 +187,8 @@ pub async fn atan(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
/// Compute the four quadrant arctangent of Y and X (in radians).
pub async fn atan2(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let y = args.get_kw_arg_typed("y", &RuntimeType::length(), exec_state)?;
let x = args.get_kw_arg_typed("x", &RuntimeType::length(), exec_state)?;
let y = args.get_kw_arg("y", &RuntimeType::length(), exec_state)?;
let x = args.get_kw_arg("x", &RuntimeType::length(), exec_state)?;
let (y, x, _) = NumericType::combine_eq_coerce(y, x);
let result = y.atan2(x);
@ -201,8 +201,8 @@ pub async fn atan2(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// details; `log2()` can produce more accurate results for base 2,
/// and `log10()` can produce more accurate results for base 10.
pub async fn log(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let base: TyF64 = args.get_kw_arg_typed("base", &RuntimeType::count(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
let base: TyF64 = args.get_kw_arg("base", &RuntimeType::count(), exec_state)?;
let result = input.n.log(base.n);
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
@ -210,7 +210,7 @@ pub async fn log(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
/// Compute the base 2 logarithm of the number.
pub async fn log2(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
let result = input.n.log2();
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
@ -218,7 +218,7 @@ pub async fn log2(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
/// Compute the base 10 logarithm of the number.
pub async fn log10(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
let result = input.n.log10();
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
@ -226,7 +226,7 @@ pub async fn log10(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// Compute the natural logarithm of the number.
pub async fn ln(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
let input: TyF64 = args.get_unlabeled_kw_arg("input", &RuntimeType::num_any(), exec_state)?;
let result = input.n.ln();
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
@ -234,8 +234,8 @@ pub async fn ln(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclE
/// Compute the length of the given leg.
pub async fn leg_length(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let hypotenuse: TyF64 = args.get_kw_arg_typed("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg_typed("leg", &RuntimeType::length(), exec_state)?;
let hypotenuse: TyF64 = args.get_kw_arg("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg("leg", &RuntimeType::length(), exec_state)?;
let (hypotenuse, leg, ty) = NumericType::combine_eq_coerce(hypotenuse, leg);
let result = (hypotenuse.powi(2) - f64::min(hypotenuse.abs(), leg.abs()).powi(2)).sqrt();
Ok(KclValue::from_number_with_type(result, ty, vec![args.into()]))
@ -243,8 +243,8 @@ pub async fn leg_length(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// Compute the angle of the given leg for x.
pub async fn leg_angle_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let hypotenuse: TyF64 = args.get_kw_arg_typed("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg_typed("leg", &RuntimeType::length(), exec_state)?;
let hypotenuse: TyF64 = args.get_kw_arg("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg("leg", &RuntimeType::length(), exec_state)?;
let (hypotenuse, leg, _ty) = NumericType::combine_eq_coerce(hypotenuse, leg);
let result = (leg.min(hypotenuse) / hypotenuse).acos().to_degrees();
Ok(KclValue::from_number_with_type(
@ -256,8 +256,8 @@ pub async fn leg_angle_x(exec_state: &mut ExecState, args: Args) -> Result<KclVa
/// Compute the angle of the given leg for y.
pub async fn leg_angle_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let hypotenuse: TyF64 = args.get_kw_arg_typed("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg_typed("leg", &RuntimeType::length(), exec_state)?;
let hypotenuse: TyF64 = args.get_kw_arg("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg("leg", &RuntimeType::length(), exec_state)?;
let (hypotenuse, leg, _ty) = NumericType::combine_eq_coerce(hypotenuse, leg);
let result = (leg.min(hypotenuse) / hypotenuse).asin().to_degrees();
Ok(KclValue::from_number_with_type(

View File

@ -18,8 +18,8 @@ use crate::{
/// Mirror a sketch.
pub async fn mirror_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let axis = args.get_kw_arg_typed(
let sketches = args.get_unlabeled_kw_arg("sketches", &RuntimeType::sketches(), exec_state)?;
let axis = args.get_kw_arg(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Edge),

View File

@ -35,10 +35,10 @@ const MUST_HAVE_ONE_INSTANCE: &str = "There must be at least 1 instance of your
/// Repeat some 3D solid, changing each repetition slightly.
pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
let instances: u32 = args.get_kw_arg_typed("instances", &RuntimeType::count(), exec_state)?;
let transform: &FunctionSource = args.get_kw_arg("transform")?;
let use_original = args.get_kw_arg_opt_typed("useOriginal", &RuntimeType::bool(), exec_state)?;
let solids = args.get_unlabeled_kw_arg("solids", &RuntimeType::solids(), exec_state)?;
let instances: u32 = args.get_kw_arg("instances", &RuntimeType::count(), exec_state)?;
let transform: FunctionSource = args.get_kw_arg("transform", &RuntimeType::function(), exec_state)?;
let use_original = args.get_kw_arg_opt("useOriginal", &RuntimeType::bool(), exec_state)?;
let solids = inner_pattern_transform(solids, instances, transform, use_original, exec_state, &args).await?;
Ok(solids.into())
@ -46,22 +46,22 @@ pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result
/// Repeat some 2D sketch, changing each repetition slightly.
pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let instances: u32 = args.get_kw_arg_typed("instances", &RuntimeType::count(), exec_state)?;
let transform: &FunctionSource = args.get_kw_arg("transform")?;
let use_original = args.get_kw_arg_opt_typed("useOriginal", &RuntimeType::bool(), exec_state)?;
let sketches = args.get_unlabeled_kw_arg("sketches", &RuntimeType::sketches(), exec_state)?;
let instances: u32 = args.get_kw_arg("instances", &RuntimeType::count(), exec_state)?;
let transform: FunctionSource = args.get_kw_arg("transform", &RuntimeType::function(), exec_state)?;
let use_original = args.get_kw_arg_opt("useOriginal", &RuntimeType::bool(), exec_state)?;
let sketches = inner_pattern_transform_2d(sketches, instances, transform, use_original, exec_state, &args).await?;
Ok(sketches.into())
}
async fn inner_pattern_transform<'a>(
async fn inner_pattern_transform(
solids: Vec<Solid>,
instances: u32,
transform: &'a FunctionSource,
transform: FunctionSource,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: &'a Args,
args: &Args,
) -> Result<Vec<Solid>, KclError> {
// Build the vec of transforms, one for each repetition.
let mut transform_vec = Vec::with_capacity(usize::try_from(instances).unwrap());
@ -72,7 +72,7 @@ async fn inner_pattern_transform<'a>(
)));
}
for i in 1..instances {
let t = make_transform::<Solid>(i, transform, args.source_range, exec_state, &args.ctx).await?;
let t = make_transform::<Solid>(i, &transform, args.source_range, exec_state, &args.ctx).await?;
transform_vec.push(t);
}
execute_pattern_transform(
@ -85,13 +85,13 @@ async fn inner_pattern_transform<'a>(
.await
}
async fn inner_pattern_transform_2d<'a>(
async fn inner_pattern_transform_2d(
sketches: Vec<Sketch>,
instances: u32,
transform: &'a FunctionSource,
transform: FunctionSource,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: &'a Args,
args: &Args,
) -> Result<Vec<Sketch>, KclError> {
// Build the vec of transforms, one for each repetition.
let mut transform_vec = Vec::with_capacity(usize::try_from(instances).unwrap());
@ -102,7 +102,7 @@ async fn inner_pattern_transform_2d<'a>(
)));
}
for i in 1..instances {
let t = make_transform::<Sketch>(i, transform, args.source_range, exec_state, &args.ctx).await?;
let t = make_transform::<Sketch>(i, &transform, args.source_range, exec_state, &args.ctx).await?;
transform_vec.push(t);
}
execute_pattern_transform(
@ -519,10 +519,10 @@ mod tests {
/// A linear pattern on a 2D sketch.
pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let instances: u32 = args.get_kw_arg_typed("instances", &RuntimeType::count(), exec_state)?;
let distance: TyF64 = args.get_kw_arg_typed("distance", &RuntimeType::length(), exec_state)?;
let axis: Axis2dOrPoint2d = args.get_kw_arg_typed(
let sketches = args.get_unlabeled_kw_arg("sketches", &RuntimeType::sketches(), exec_state)?;
let instances: u32 = args.get_kw_arg("instances", &RuntimeType::count(), exec_state)?;
let distance: TyF64 = args.get_kw_arg("distance", &RuntimeType::length(), exec_state)?;
let axis: Axis2dOrPoint2d = args.get_kw_arg(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Axis2d),
@ -530,7 +530,7 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
]),
exec_state,
)?;
let use_original = args.get_kw_arg_opt_typed("useOriginal", &RuntimeType::bool(), exec_state)?;
let use_original = args.get_kw_arg_opt("useOriginal", &RuntimeType::bool(), exec_state)?;
let axis = axis.to_point2d();
if axis[0].n == 0.0 && axis[1].n == 0.0 {
@ -579,10 +579,10 @@ async fn inner_pattern_linear_2d(
/// A linear pattern on a 3D model.
pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
let instances: u32 = args.get_kw_arg_typed("instances", &RuntimeType::count(), exec_state)?;
let distance: TyF64 = args.get_kw_arg_typed("distance", &RuntimeType::length(), exec_state)?;
let axis: Axis3dOrPoint3d = args.get_kw_arg_typed(
let solids = args.get_unlabeled_kw_arg("solids", &RuntimeType::solids(), exec_state)?;
let instances: u32 = args.get_kw_arg("instances", &RuntimeType::count(), exec_state)?;
let distance: TyF64 = args.get_kw_arg("distance", &RuntimeType::length(), exec_state)?;
let axis: Axis3dOrPoint3d = args.get_kw_arg(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Axis3d),
@ -590,7 +590,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
]),
exec_state,
)?;
let use_original = args.get_kw_arg_opt_typed("useOriginal", &RuntimeType::bool(), exec_state)?;
let use_original = args.get_kw_arg_opt("useOriginal", &RuntimeType::bool(), exec_state)?;
let axis = axis.to_point3d();
if axis[0].n == 0.0 && axis[1].n == 0.0 && axis[2].n == 0.0 {
@ -747,12 +747,12 @@ impl CircularPattern {
/// A circular pattern on a 2D sketch.
pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let instances: u32 = args.get_kw_arg_typed("instances", &RuntimeType::count(), exec_state)?;
let center: [TyF64; 2] = args.get_kw_arg_typed("center", &RuntimeType::point2d(), exec_state)?;
let arc_degrees: Option<TyF64> = args.get_kw_arg_opt_typed("arcDegrees", &RuntimeType::degrees(), exec_state)?;
let rotate_duplicates = args.get_kw_arg_opt_typed("rotateDuplicates", &RuntimeType::bool(), exec_state)?;
let use_original = args.get_kw_arg_opt_typed("useOriginal", &RuntimeType::bool(), exec_state)?;
let sketches = args.get_unlabeled_kw_arg("sketches", &RuntimeType::sketches(), exec_state)?;
let instances: u32 = args.get_kw_arg("instances", &RuntimeType::count(), exec_state)?;
let center: [TyF64; 2] = args.get_kw_arg("center", &RuntimeType::point2d(), exec_state)?;
let arc_degrees: Option<TyF64> = args.get_kw_arg_opt("arcDegrees", &RuntimeType::degrees(), exec_state)?;
let rotate_duplicates = args.get_kw_arg_opt("rotateDuplicates", &RuntimeType::bool(), exec_state)?;
let use_original = args.get_kw_arg_opt("useOriginal", &RuntimeType::bool(), exec_state)?;
let sketches = inner_pattern_circular_2d(
sketches,
@ -817,14 +817,14 @@ async fn inner_pattern_circular_2d(
/// A circular pattern on a 3D model.
pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
let solids = args.get_unlabeled_kw_arg("solids", &RuntimeType::solids(), exec_state)?;
// The number of total instances. Must be greater than or equal to 1.
// This includes the original entity. For example, if instances is 2,
// there will be two copies -- the original, and one new copy.
// If instances is 1, this has no effect.
let instances: u32 = args.get_kw_arg_typed("instances", &RuntimeType::count(), exec_state)?;
let instances: u32 = args.get_kw_arg("instances", &RuntimeType::count(), exec_state)?;
// The axis around which to make the pattern. This is a 3D vector.
let axis: Axis3dOrPoint3d = args.get_kw_arg_typed(
let axis: Axis3dOrPoint3d = args.get_kw_arg(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Axis3d),
@ -835,14 +835,14 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
let axis = axis.to_point3d();
// The center about which to make the pattern. This is a 3D vector.
let center: [TyF64; 3] = args.get_kw_arg_typed("center", &RuntimeType::point3d(), exec_state)?;
let center: [TyF64; 3] = args.get_kw_arg("center", &RuntimeType::point3d(), exec_state)?;
// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
let arc_degrees: Option<TyF64> = args.get_kw_arg_opt_typed("arcDegrees", &RuntimeType::degrees(), exec_state)?;
let arc_degrees: Option<TyF64> = args.get_kw_arg_opt("arcDegrees", &RuntimeType::degrees(), exec_state)?;
// Whether or not to rotate the duplicates as they are copied.
let rotate_duplicates = args.get_kw_arg_opt_typed("rotateDuplicates", &RuntimeType::bool(), exec_state)?;
let rotate_duplicates = args.get_kw_arg_opt("rotateDuplicates", &RuntimeType::bool(), exec_state)?;
// If the target being patterned is itself a pattern, then, should you use the original solid,
// or the pattern?
let use_original = args.get_kw_arg_opt_typed("useOriginal", &RuntimeType::bool(), exec_state)?;
let use_original = args.get_kw_arg_opt("useOriginal", &RuntimeType::bool(), exec_state)?;
let solids = inner_pattern_circular_3d(
solids,

View File

@ -12,8 +12,8 @@ use crate::{
/// Offset a plane by a distance along its normal.
pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let std_plane = args.get_unlabeled_kw_arg_typed("plane", &RuntimeType::plane(), exec_state)?;
let offset: TyF64 = args.get_kw_arg_typed("offset", &RuntimeType::length(), exec_state)?;
let std_plane = args.get_unlabeled_kw_arg("plane", &RuntimeType::plane(), exec_state)?;
let offset: TyF64 = args.get_kw_arg("offset", &RuntimeType::length(), exec_state)?;
let plane = inner_offset_plane(std_plane, offset, exec_state, &args).await?;
Ok(KclValue::Plane { value: Box::new(plane) })
}

View File

@ -24,8 +24,8 @@ extern crate nalgebra_glm as glm;
/// Revolve a sketch or set of sketches around an axis.
pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let axis = args.get_kw_arg_typed(
let sketches = args.get_unlabeled_kw_arg("sketches", &RuntimeType::sketches(), exec_state)?;
let axis = args.get_kw_arg(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Edge),
@ -33,13 +33,13 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
]),
exec_state,
)?;
let angle: Option<TyF64> = args.get_kw_arg_opt_typed("angle", &RuntimeType::degrees(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
let tag_start = args.get_kw_arg_opt("tagStart")?;
let tag_end = args.get_kw_arg_opt("tagEnd")?;
let symmetric = args.get_kw_arg_opt_typed("symmetric", &RuntimeType::bool(), exec_state)?;
let angle: Option<TyF64> = args.get_kw_arg_opt("angle", &RuntimeType::degrees(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt("tolerance", &RuntimeType::length(), exec_state)?;
let tag_start = args.get_kw_arg_opt("tagStart", &RuntimeType::tag_decl(), exec_state)?;
let tag_end = args.get_kw_arg_opt("tagEnd", &RuntimeType::tag_decl(), exec_state)?;
let symmetric = args.get_kw_arg_opt("symmetric", &RuntimeType::bool(), exec_state)?;
let bidirectional_angle: Option<TyF64> =
args.get_kw_arg_opt_typed("bidirectionalAngle", &RuntimeType::angle(), exec_state)?;
args.get_kw_arg_opt("bidirectionalAngle", &RuntimeType::angle(), exec_state)?;
let value = inner_revolve(
sketches,

View File

@ -15,7 +15,7 @@ use crate::{
/// Returns the point at the end of the given segment.
pub async fn segment_end(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg_typed("tag", &RuntimeType::tag_identifier(), exec_state)?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tag_identifier(), exec_state)?;
let pt = inner_segment_end(&tag, exec_state, args.clone())?;
args.make_kcl_val_from_point([pt[0].n, pt[1].n], pt[0].ty.clone())
@ -38,7 +38,7 @@ fn inner_segment_end(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args
/// Returns the segment end of x.
pub async fn segment_end_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg_typed("tag", &RuntimeType::tag_identifier(), exec_state)?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tag_identifier(), exec_state)?;
let result = inner_segment_end_x(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(result))
@ -58,7 +58,7 @@ fn inner_segment_end_x(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
/// Returns the segment end of y.
pub async fn segment_end_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg_typed("tag", &RuntimeType::tag_identifier(), exec_state)?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tag_identifier(), exec_state)?;
let result = inner_segment_end_y(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(result))
@ -78,7 +78,7 @@ fn inner_segment_end_y(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
/// Returns the point at the start of the given segment.
pub async fn segment_start(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg_typed("tag", &RuntimeType::tag_identifier(), exec_state)?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tag_identifier(), exec_state)?;
let pt = inner_segment_start(&tag, exec_state, args.clone())?;
args.make_kcl_val_from_point([pt[0].n, pt[1].n], pt[0].ty.clone())
@ -101,7 +101,7 @@ fn inner_segment_start(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
/// Returns the segment start of x.
pub async fn segment_start_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg_typed("tag", &RuntimeType::tag_identifier(), exec_state)?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tag_identifier(), exec_state)?;
let result = inner_segment_start_x(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(result))
@ -121,7 +121,7 @@ fn inner_segment_start_x(tag: &TagIdentifier, exec_state: &mut ExecState, args:
/// Returns the segment start of y.
pub async fn segment_start_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg_typed("tag", &RuntimeType::tag_identifier(), exec_state)?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tag_identifier(), exec_state)?;
let result = inner_segment_start_y(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(result))
@ -140,8 +140,7 @@ fn inner_segment_start_y(tag: &TagIdentifier, exec_state: &mut ExecState, args:
}
/// Returns the last segment of x.
pub async fn last_segment_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let result = inner_last_segment_x(sketch, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(result))
@ -164,8 +163,7 @@ fn inner_last_segment_x(sketch: Sketch, args: Args) -> Result<TyF64, KclError> {
/// Returns the last segment of y.
pub async fn last_segment_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let result = inner_last_segment_y(sketch, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(result))
@ -188,7 +186,7 @@ fn inner_last_segment_y(sketch: Sketch, args: Args) -> Result<TyF64, KclError> {
/// Returns the length of the segment.
pub async fn segment_length(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg_typed("tag", &RuntimeType::tag_identifier(), exec_state)?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tag_identifier(), exec_state)?;
let result = inner_segment_length(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(result))
}
@ -207,7 +205,7 @@ fn inner_segment_length(tag: &TagIdentifier, exec_state: &mut ExecState, args: A
/// Returns the angle of the segment.
pub async fn segment_angle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg_typed("tag", &RuntimeType::tag_identifier(), exec_state)?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tag_identifier(), exec_state)?;
let result = inner_segment_angle(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees())))
@ -229,7 +227,7 @@ fn inner_segment_angle(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
/// Returns the angle coming out of the end of the segment in degrees.
pub async fn tangent_to_end(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg_typed("tag", &RuntimeType::tag_identifier(), exec_state)?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tag_identifier(), exec_state)?;
let result = inner_tangent_to_end(&tag, exec_state, args.clone()).await?;
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees())))

View File

@ -24,7 +24,6 @@ use crate::{
},
parsing::ast::types::TagNode,
std::{
sketch::NEW_TAG_KW,
utils::{calculate_circle_center, distance},
Args,
},
@ -43,11 +42,11 @@ pub enum SketchOrSurface {
/// Sketch a circle.
pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_or_surface =
args.get_unlabeled_kw_arg_typed("sketchOrSurface", &RuntimeType::sketch_or_surface(), exec_state)?;
let center = args.get_kw_arg_typed("center", &RuntimeType::point2d(), exec_state)?;
let radius: Option<TyF64> = args.get_kw_arg_opt_typed("radius", &RuntimeType::length(), exec_state)?;
let diameter: Option<TyF64> = args.get_kw_arg_opt_typed("diameter", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
args.get_unlabeled_kw_arg("sketchOrSurface", &RuntimeType::sketch_or_surface(), exec_state)?;
let center = args.get_kw_arg("center", &RuntimeType::point2d(), exec_state)?;
let radius: Option<TyF64> = args.get_kw_arg_opt("radius", &RuntimeType::length(), exec_state)?;
let diameter: Option<TyF64> = args.get_kw_arg_opt("diameter", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let sketch = inner_circle(sketch_or_surface, center, radius, diameter, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -130,11 +129,11 @@ async fn inner_circle(
/// Sketch a 3-point circle.
pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_or_surface =
args.get_unlabeled_kw_arg_typed("sketchOrSurface", &RuntimeType::sketch_or_surface(), exec_state)?;
let p1 = args.get_kw_arg_typed("p1", &RuntimeType::point2d(), exec_state)?;
let p2 = args.get_kw_arg_typed("p2", &RuntimeType::point2d(), exec_state)?;
let p3 = args.get_kw_arg_typed("p3", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt("tag")?;
args.get_unlabeled_kw_arg("sketchOrSurface", &RuntimeType::sketch_or_surface(), exec_state)?;
let p1 = args.get_kw_arg("p1", &RuntimeType::point2d(), exec_state)?;
let p2 = args.get_kw_arg("p2", &RuntimeType::point2d(), exec_state)?;
let p3 = args.get_kw_arg("p3", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let sketch = inner_circle_three_point(sketch_or_surface, p1, p2, p3, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -239,11 +238,11 @@ pub enum PolygonType {
/// Create a regular polygon with the specified number of sides and radius.
pub async fn polygon(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_or_surface =
args.get_unlabeled_kw_arg_typed("sketchOrSurface", &RuntimeType::sketch_or_surface(), exec_state)?;
let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?;
let num_sides: TyF64 = args.get_kw_arg_typed("numSides", &RuntimeType::count(), exec_state)?;
let center = args.get_kw_arg_typed("center", &RuntimeType::point2d(), exec_state)?;
let inscribed = args.get_kw_arg_opt_typed("inscribed", &RuntimeType::bool(), exec_state)?;
args.get_unlabeled_kw_arg("sketchOrSurface", &RuntimeType::sketch_or_surface(), exec_state)?;
let radius: TyF64 = args.get_kw_arg("radius", &RuntimeType::length(), exec_state)?;
let num_sides: TyF64 = args.get_kw_arg("numSides", &RuntimeType::count(), exec_state)?;
let center = args.get_kw_arg("center", &RuntimeType::point2d(), exec_state)?;
let inscribed = args.get_kw_arg_opt("inscribed", &RuntimeType::bool(), exec_state)?;
let sketch = inner_polygon(
sketch_or_surface,

View File

@ -16,9 +16,9 @@ use crate::{
/// Create a shell.
pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
let thickness: TyF64 = args.get_kw_arg_typed("thickness", &RuntimeType::length(), exec_state)?;
let faces = args.get_kw_arg_typed(
let solids = args.get_unlabeled_kw_arg("solids", &RuntimeType::solids(), exec_state)?;
let thickness: TyF64 = args.get_kw_arg("thickness", &RuntimeType::length(), exec_state)?;
let faces = args.get_kw_arg(
"faces",
&RuntimeType::Array(Box::new(RuntimeType::tag()), ArrayLen::Minimum(1)),
exec_state,
@ -94,8 +94,8 @@ async fn inner_shell(
/// Make the inside of a 3D object hollow.
pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid = args.get_unlabeled_kw_arg_typed("solid", &RuntimeType::solid(), exec_state)?;
let thickness: TyF64 = args.get_kw_arg_typed("thickness", &RuntimeType::length(), exec_state)?;
let solid = args.get_unlabeled_kw_arg("solid", &RuntimeType::solid(), exec_state)?;
let thickness: TyF64 = args.get_kw_arg("thickness", &RuntimeType::length(), exec_state)?;
let value = inner_hollow(solid, thickness, exec_state, args).await?;
Ok(KclValue::Solid { value })

View File

@ -99,13 +99,13 @@ pub enum StartOrEnd {
pub const NEW_TAG_KW: &str = "tag";
pub async fn involute_circular(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::sketch(), exec_state)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::sketch(), exec_state)?;
let start_radius: TyF64 = args.get_kw_arg_typed("startRadius", &RuntimeType::length(), exec_state)?;
let end_radius: TyF64 = args.get_kw_arg_typed("endRadius", &RuntimeType::length(), exec_state)?;
let angle: TyF64 = args.get_kw_arg_typed("angle", &RuntimeType::angle(), exec_state)?;
let reverse = args.get_kw_arg_opt_typed("reverse", &RuntimeType::bool(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let start_radius: TyF64 = args.get_kw_arg("startRadius", &RuntimeType::length(), exec_state)?;
let end_radius: TyF64 = args.get_kw_arg("endRadius", &RuntimeType::length(), exec_state)?;
let angle: TyF64 = args.get_kw_arg("angle", &RuntimeType::angle(), exec_state)?;
let reverse = args.get_kw_arg_opt("reverse", &RuntimeType::bool(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch =
inner_involute_circular(sketch, start_radius, end_radius, angle, reverse, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -192,10 +192,10 @@ async fn inner_involute_circular(
/// Draw a line to a point.
pub async fn line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::sketch(), exec_state)?;
let end = args.get_kw_arg_opt_typed("end", &RuntimeType::point2d(), exec_state)?;
let end_absolute = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::sketch(), exec_state)?;
let end = args.get_kw_arg_opt("end", &RuntimeType::point2d(), exec_state)?;
let end_absolute = args.get_kw_arg_opt("endAbsolute", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch = inner_line(sketch, end_absolute, end, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -329,11 +329,10 @@ async fn straight_line(
/// Draw a line on the x-axis.
pub async fn x_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let length: Option<TyF64> = args.get_kw_arg_opt_typed("length", &RuntimeType::length(), exec_state)?;
let end_absolute: Option<TyF64> = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let length: Option<TyF64> = args.get_kw_arg_opt("length", &RuntimeType::length(), exec_state)?;
let end_absolute: Option<TyF64> = args.get_kw_arg_opt("endAbsolute", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch = inner_x_line(sketch, length, end_absolute, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -366,11 +365,10 @@ async fn inner_x_line(
/// Draw a line on the y-axis.
pub async fn y_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let length: Option<TyF64> = args.get_kw_arg_opt_typed("length", &RuntimeType::length(), exec_state)?;
let end_absolute: Option<TyF64> = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let length: Option<TyF64> = args.get_kw_arg_opt("length", &RuntimeType::length(), exec_state)?;
let end_absolute: Option<TyF64> = args.get_kw_arg_opt("endAbsolute", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch = inner_y_line(sketch, length, end_absolute, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -403,16 +401,14 @@ async fn inner_y_line(
/// Draw an angled line.
pub async fn angled_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::sketch(), exec_state)?;
let angle: TyF64 = args.get_kw_arg_typed("angle", &RuntimeType::degrees(), exec_state)?;
let length: Option<TyF64> = args.get_kw_arg_opt_typed("length", &RuntimeType::length(), exec_state)?;
let length_x: Option<TyF64> = args.get_kw_arg_opt_typed("lengthX", &RuntimeType::length(), exec_state)?;
let length_y: Option<TyF64> = args.get_kw_arg_opt_typed("lengthY", &RuntimeType::length(), exec_state)?;
let end_absolute_x: Option<TyF64> =
args.get_kw_arg_opt_typed("endAbsoluteX", &RuntimeType::length(), exec_state)?;
let end_absolute_y: Option<TyF64> =
args.get_kw_arg_opt_typed("endAbsoluteY", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::sketch(), exec_state)?;
let angle: TyF64 = args.get_kw_arg("angle", &RuntimeType::degrees(), exec_state)?;
let length: Option<TyF64> = args.get_kw_arg_opt("length", &RuntimeType::length(), exec_state)?;
let length_x: Option<TyF64> = args.get_kw_arg_opt("lengthX", &RuntimeType::length(), exec_state)?;
let length_y: Option<TyF64> = args.get_kw_arg_opt("lengthY", &RuntimeType::length(), exec_state)?;
let end_absolute_x: Option<TyF64> = args.get_kw_arg_opt("endAbsoluteX", &RuntimeType::length(), exec_state)?;
let end_absolute_y: Option<TyF64> = args.get_kw_arg_opt("endAbsoluteY", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch = inner_angled_line(
sketch,
@ -683,13 +679,11 @@ async fn inner_angled_line_to_y(
/// Draw an angled line that intersects with a given line.
pub async fn angled_line_that_intersects(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let angle: TyF64 = args.get_kw_arg_typed("angle", &RuntimeType::angle(), exec_state)?;
let intersect_tag: TagIdentifier =
args.get_kw_arg_typed("intersectTag", &RuntimeType::tag_identifier(), exec_state)?;
let offset = args.get_kw_arg_opt_typed("offset", &RuntimeType::length(), exec_state)?;
let tag: Option<TagNode> = args.get_kw_arg_opt("tag")?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let angle: TyF64 = args.get_kw_arg("angle", &RuntimeType::angle(), exec_state)?;
let intersect_tag: TagIdentifier = args.get_kw_arg("intersectTag", &RuntimeType::tag_identifier(), exec_state)?;
let offset = args.get_kw_arg_opt("offset", &RuntimeType::length(), exec_state)?;
let tag: Option<TagNode> = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch =
inner_angled_line_that_intersects(sketch, angle, intersect_tag, offset, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -774,12 +768,12 @@ pub enum PlaneData {
/// Start a sketch on a specific plane or face.
pub async fn start_sketch_on(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let data = args.get_unlabeled_kw_arg_typed(
let data = args.get_unlabeled_kw_arg(
"planeOrSolid",
&RuntimeType::Union(vec![RuntimeType::solid(), RuntimeType::plane()]),
exec_state,
)?;
let face = args.get_kw_arg_opt_typed("face", &RuntimeType::tag(), exec_state)?;
let face = args.get_kw_arg_opt("face", &RuntimeType::tag(), exec_state)?;
match inner_start_sketch_on(data, face, exec_state, &args).await? {
SketchSurface::Plane(value) => Ok(KclValue::Plane { value }),
@ -898,13 +892,13 @@ async fn make_sketch_plane_from_orientation(
/// Start a new profile at a given point.
pub async fn start_profile(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_surface = args.get_unlabeled_kw_arg_typed(
let sketch_surface = args.get_unlabeled_kw_arg(
"startProfileOn",
&RuntimeType::Union(vec![RuntimeType::plane(), RuntimeType::face()]),
exec_state,
)?;
let start: [TyF64; 2] = args.get_kw_arg_typed("at", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let start: [TyF64; 2] = args.get_kw_arg("at", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let sketch = inner_start_profile(sketch_surface, start, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -1028,7 +1022,7 @@ pub(crate) async fn inner_start_profile(
/// Returns the X component of the sketch profile start point.
pub async fn profile_start_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch: Sketch = args.get_unlabeled_kw_arg_typed("profile", &RuntimeType::sketch(), exec_state)?;
let sketch: Sketch = args.get_unlabeled_kw_arg("profile", &RuntimeType::sketch(), exec_state)?;
let ty = sketch.units.into();
let x = inner_profile_start_x(sketch)?;
Ok(args.make_user_val_from_f64_with_type(TyF64::new(x, ty)))
@ -1040,7 +1034,7 @@ pub(crate) fn inner_profile_start_x(profile: Sketch) -> Result<f64, KclError> {
/// Returns the Y component of the sketch profile start point.
pub async fn profile_start_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch: Sketch = args.get_unlabeled_kw_arg_typed("profile", &RuntimeType::sketch(), exec_state)?;
let sketch: Sketch = args.get_unlabeled_kw_arg("profile", &RuntimeType::sketch(), exec_state)?;
let ty = sketch.units.into();
let x = inner_profile_start_y(sketch)?;
Ok(args.make_user_val_from_f64_with_type(TyF64::new(x, ty)))
@ -1052,7 +1046,7 @@ pub(crate) fn inner_profile_start_y(profile: Sketch) -> Result<f64, KclError> {
/// Returns the sketch profile start point.
pub async fn profile_start(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch: Sketch = args.get_unlabeled_kw_arg_typed("profile", &RuntimeType::sketch(), exec_state)?;
let sketch: Sketch = args.get_unlabeled_kw_arg("profile", &RuntimeType::sketch(), exec_state)?;
let ty = sketch.units.into();
let point = inner_profile_start(sketch)?;
Ok(KclValue::from_point2d(point, ty, args.into()))
@ -1064,9 +1058,8 @@ pub(crate) fn inner_profile_start(profile: Sketch) -> Result<[f64; 2], KclError>
/// Close the current sketch.
pub async fn close(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch = inner_close(sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
value: Box::new(new_sketch),
@ -1112,18 +1105,16 @@ pub(crate) async fn inner_close(
/// Draw an arc.
pub async fn arc(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let angle_start: Option<TyF64> = args.get_kw_arg_opt_typed("angleStart", &RuntimeType::degrees(), exec_state)?;
let angle_end: Option<TyF64> = args.get_kw_arg_opt_typed("angleEnd", &RuntimeType::degrees(), exec_state)?;
let radius: Option<TyF64> = args.get_kw_arg_opt_typed("radius", &RuntimeType::length(), exec_state)?;
let diameter: Option<TyF64> = args.get_kw_arg_opt_typed("diameter", &RuntimeType::length(), exec_state)?;
let end_absolute: Option<[TyF64; 2]> =
args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::point2d(), exec_state)?;
let angle_start: Option<TyF64> = args.get_kw_arg_opt("angleStart", &RuntimeType::degrees(), exec_state)?;
let angle_end: Option<TyF64> = args.get_kw_arg_opt("angleEnd", &RuntimeType::degrees(), exec_state)?;
let radius: Option<TyF64> = args.get_kw_arg_opt("radius", &RuntimeType::length(), exec_state)?;
let diameter: Option<TyF64> = args.get_kw_arg_opt("diameter", &RuntimeType::length(), exec_state)?;
let end_absolute: Option<[TyF64; 2]> = args.get_kw_arg_opt("endAbsolute", &RuntimeType::point2d(), exec_state)?;
let interior_absolute: Option<[TyF64; 2]> =
args.get_kw_arg_opt_typed("interiorAbsolute", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
args.get_kw_arg_opt("interiorAbsolute", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch = inner_arc(
sketch,
angle_start,
@ -1304,14 +1295,13 @@ pub async fn relative_arc(
/// Draw a tangential arc to a specific point.
pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let end = args.get_kw_arg_opt_typed("end", &RuntimeType::point2d(), exec_state)?;
let end_absolute = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::point2d(), exec_state)?;
let radius = args.get_kw_arg_opt_typed("radius", &RuntimeType::length(), exec_state)?;
let diameter = args.get_kw_arg_opt_typed("diameter", &RuntimeType::length(), exec_state)?;
let angle = args.get_kw_arg_opt_typed("angle", &RuntimeType::angle(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let end = args.get_kw_arg_opt("end", &RuntimeType::point2d(), exec_state)?;
let end_absolute = args.get_kw_arg_opt("endAbsolute", &RuntimeType::point2d(), exec_state)?;
let radius = args.get_kw_arg_opt("radius", &RuntimeType::length(), exec_state)?;
let diameter = args.get_kw_arg_opt("diameter", &RuntimeType::length(), exec_state)?;
let angle = args.get_kw_arg_opt("angle", &RuntimeType::angle(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch = inner_tangential_arc(
sketch,
@ -1560,15 +1550,14 @@ async fn inner_tangential_arc_to_point(
/// Draw a bezier curve.
pub async fn bezier_curve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let control1 = args.get_kw_arg_opt_typed("control1", &RuntimeType::point2d(), exec_state)?;
let control2 = args.get_kw_arg_opt_typed("control2", &RuntimeType::point2d(), exec_state)?;
let end = args.get_kw_arg_opt_typed("end", &RuntimeType::point2d(), exec_state)?;
let control1_absolute = args.get_kw_arg_opt_typed("control1Absolute", &RuntimeType::point2d(), exec_state)?;
let control2_absolute = args.get_kw_arg_opt_typed("control2Absolute", &RuntimeType::point2d(), exec_state)?;
let end_absolute = args.get_kw_arg_opt_typed("endAbsolute", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt("tag")?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let control1 = args.get_kw_arg_opt("control1", &RuntimeType::point2d(), exec_state)?;
let control2 = args.get_kw_arg_opt("control2", &RuntimeType::point2d(), exec_state)?;
let end = args.get_kw_arg_opt("end", &RuntimeType::point2d(), exec_state)?;
let control1_absolute = args.get_kw_arg_opt("control1Absolute", &RuntimeType::point2d(), exec_state)?;
let control2_absolute = args.get_kw_arg_opt("control2Absolute", &RuntimeType::point2d(), exec_state)?;
let end_absolute = args.get_kw_arg_opt("endAbsolute", &RuntimeType::point2d(), exec_state)?;
let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?;
let new_sketch = inner_bezier_curve(
sketch,
@ -1686,10 +1675,9 @@ async fn inner_bezier_curve(
/// Use a sketch to cut a hole in another sketch.
pub async fn subtract_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let sketch = args.get_unlabeled_kw_arg("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let tool: Vec<Sketch> = args.get_kw_arg_typed(
let tool: Vec<Sketch> = args.get_kw_arg(
"tool",
&RuntimeType::Array(
Box::new(RuntimeType::Primitive(PrimitiveType::Sketch)),

View File

@ -29,17 +29,17 @@ pub enum SweepPath {
/// Extrude a sketch along a path.
pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let path: SweepPath = args.get_kw_arg_typed(
let sketches = args.get_unlabeled_kw_arg("sketches", &RuntimeType::sketches(), exec_state)?;
let path: SweepPath = args.get_kw_arg(
"path",
&RuntimeType::Union(vec![RuntimeType::sketch(), RuntimeType::helix()]),
exec_state,
)?;
let sectional = args.get_kw_arg_opt_typed("sectional", &RuntimeType::bool(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
let relative_to: Option<String> = args.get_kw_arg_opt_typed("relativeTo", &RuntimeType::string(), exec_state)?;
let tag_start = args.get_kw_arg_opt("tagStart")?;
let tag_end = args.get_kw_arg_opt("tagEnd")?;
let sectional = args.get_kw_arg_opt("sectional", &RuntimeType::bool(), exec_state)?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt("tolerance", &RuntimeType::length(), exec_state)?;
let relative_to: Option<String> = args.get_kw_arg_opt("relativeTo", &RuntimeType::string(), exec_state)?;
let tag_start = args.get_kw_arg_opt("tagStart", &RuntimeType::tag_decl(), exec_state)?;
let tag_end = args.get_kw_arg_opt("tagEnd", &RuntimeType::tag_decl(), exec_state)?;
let value = inner_sweep(
sketches,

View File

@ -21,7 +21,7 @@ use crate::{
/// Scale a solid or a sketch.
pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let objects = args.get_unlabeled_kw_arg_typed(
let objects = args.get_unlabeled_kw_arg(
"objects",
&RuntimeType::Union(vec![
RuntimeType::sketches(),
@ -30,10 +30,10 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
]),
exec_state,
)?;
let scale_x: Option<TyF64> = args.get_kw_arg_opt_typed("x", &RuntimeType::count(), exec_state)?;
let scale_y: Option<TyF64> = args.get_kw_arg_opt_typed("y", &RuntimeType::count(), exec_state)?;
let scale_z: Option<TyF64> = args.get_kw_arg_opt_typed("z", &RuntimeType::count(), exec_state)?;
let global = args.get_kw_arg_opt_typed("global", &RuntimeType::bool(), exec_state)?;
let scale_x: Option<TyF64> = args.get_kw_arg_opt("x", &RuntimeType::count(), exec_state)?;
let scale_y: Option<TyF64> = args.get_kw_arg_opt("y", &RuntimeType::count(), exec_state)?;
let scale_z: Option<TyF64> = args.get_kw_arg_opt("z", &RuntimeType::count(), exec_state)?;
let global = args.get_kw_arg_opt("global", &RuntimeType::bool(), exec_state)?;
// Ensure at least one scale value is provided.
if scale_x.is_none() && scale_y.is_none() && scale_z.is_none() {
@ -103,7 +103,7 @@ async fn inner_scale(
/// Move a solid or a sketch.
pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let objects = args.get_unlabeled_kw_arg_typed(
let objects = args.get_unlabeled_kw_arg(
"objects",
&RuntimeType::Union(vec![
RuntimeType::sketches(),
@ -112,10 +112,10 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
]),
exec_state,
)?;
let translate_x: Option<TyF64> = args.get_kw_arg_opt_typed("x", &RuntimeType::length(), exec_state)?;
let translate_y: Option<TyF64> = args.get_kw_arg_opt_typed("y", &RuntimeType::length(), exec_state)?;
let translate_z: Option<TyF64> = args.get_kw_arg_opt_typed("z", &RuntimeType::length(), exec_state)?;
let global = args.get_kw_arg_opt_typed("global", &RuntimeType::bool(), exec_state)?;
let translate_x: Option<TyF64> = args.get_kw_arg_opt("x", &RuntimeType::length(), exec_state)?;
let translate_y: Option<TyF64> = args.get_kw_arg_opt("y", &RuntimeType::length(), exec_state)?;
let translate_z: Option<TyF64> = args.get_kw_arg_opt("z", &RuntimeType::length(), exec_state)?;
let global = args.get_kw_arg_opt("global", &RuntimeType::bool(), exec_state)?;
// Ensure at least one translation value is provided.
if translate_x.is_none() && translate_y.is_none() && translate_z.is_none() {
@ -176,7 +176,7 @@ async fn inner_translate(
/// Rotate a solid or a sketch.
pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let objects = args.get_unlabeled_kw_arg_typed(
let objects = args.get_unlabeled_kw_arg(
"objects",
&RuntimeType::Union(vec![
RuntimeType::sketches(),
@ -185,10 +185,10 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
]),
exec_state,
)?;
let roll: Option<TyF64> = args.get_kw_arg_opt_typed("roll", &RuntimeType::degrees(), exec_state)?;
let pitch: Option<TyF64> = args.get_kw_arg_opt_typed("pitch", &RuntimeType::degrees(), exec_state)?;
let yaw: Option<TyF64> = args.get_kw_arg_opt_typed("yaw", &RuntimeType::degrees(), exec_state)?;
let axis: Option<Axis3dOrPoint3d> = args.get_kw_arg_opt_typed(
let roll: Option<TyF64> = args.get_kw_arg_opt("roll", &RuntimeType::degrees(), exec_state)?;
let pitch: Option<TyF64> = args.get_kw_arg_opt("pitch", &RuntimeType::degrees(), exec_state)?;
let yaw: Option<TyF64> = args.get_kw_arg_opt("yaw", &RuntimeType::degrees(), exec_state)?;
let axis: Option<Axis3dOrPoint3d> = args.get_kw_arg_opt(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Axis3d),
@ -197,8 +197,8 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
exec_state,
)?;
let axis = axis.map(|a| a.to_point3d());
let angle: Option<TyF64> = args.get_kw_arg_opt_typed("angle", &RuntimeType::degrees(), exec_state)?;
let global = args.get_kw_arg_opt_typed("global", &RuntimeType::bool(), exec_state)?;
let angle: Option<TyF64> = args.get_kw_arg_opt("angle", &RuntimeType::degrees(), exec_state)?;
let global = args.get_kw_arg_opt("global", &RuntimeType::bool(), exec_state)?;
// Check if no rotation values are provided.
if roll.is_none() && pitch.is_none() && yaw.is_none() && axis.is_none() && angle.is_none() {