use anyhow::Result;
use derive_docs::stdlib;
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd};
use kittycad_modeling_cmds as kcmc;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
executor::{ExecState, KclValue, Solid},
std::Args,
};
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
pub struct HelixData {
pub revolutions: f64,
#[serde(rename = "angleStart", alias = "angle_start")]
pub angle_start: f64,
#[serde(default)]
pub ccw: bool,
pub length: Option<f64>,
}
pub async fn helix(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, solid): (HelixData, Box<Solid>) = args.get_data_and_solid()?;
let solid = inner_helix(data, solid, args).await?;
Ok(KclValue::Solid(solid))
}
#[stdlib {
name = "helix",
}]
async fn inner_helix(data: HelixData, solid: Box<Solid>, args: Args) -> Result<Box<Solid>, KclError> {
let id = uuid::Uuid::new_v4();
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::EntityMakeHelix {
cylinder_id: solid.id,
is_clockwise: !data.ccw,
length: LengthUnit(data.length.unwrap_or(solid.height)),
revolutions: data.revolutions,
start_angle: Angle::from_degrees(data.angle_start),
}),
)
.await?;
Ok(solid)
}