use anyhow::Result;
use derive_docs::stdlib;
use schemars::JsonSchema;
use crate::{
errors::{KclError, KclErrorDetails},
executor::{MemoryItem, SketchGroup, TagIdentifier},
std::{utils::between, Args},
};
pub async fn segment_end_x(args: Args) -> Result<MemoryItem, KclError> {
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
let result = inner_segment_end_x(&segment_name, sketch_group, args.clone())?;
args.make_user_val_from_f64(result)
}
#[stdlib {
name = "segEndX",
}]
fn inner_segment_end_x(
segment_name: &TagIdentifier,
sketch_group: Box<SketchGroup>,
args: Args,
) -> Result<f64, KclError> {
let line = sketch_group.get_base_by_tag_or_start(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a segment name that exists in the given SketchGroup, found `{}`",
segment_name
),
source_ranges: vec![args.source_range],
})
})?;
Ok(line.to[0])
}
pub async fn segment_end_y(args: Args) -> Result<MemoryItem, KclError> {
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
let result = inner_segment_end_y(&segment_name, sketch_group, args.clone())?;
args.make_user_val_from_f64(result)
}
#[stdlib {
name = "segEndY",
}]
fn inner_segment_end_y(
segment_name: &TagIdentifier,
sketch_group: Box<SketchGroup>,
args: Args,
) -> Result<f64, KclError> {
let line = sketch_group.get_base_by_tag_or_start(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a segment name that exists in the given SketchGroup, found `{}`",
segment_name
),
source_ranges: vec![args.source_range],
})
})?;
Ok(line.to[1])
}
pub async fn last_segment_x(args: Args) -> Result<MemoryItem, KclError> {
let sketch_group = args.get_sketch_group()?;
let result = inner_last_segment_x(sketch_group, args.clone())?;
args.make_user_val_from_f64(result)
}
#[stdlib {
name = "lastSegX",
}]
fn inner_last_segment_x(sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
let last_line = sketch_group
.value
.last()
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a SketchGroup with at least one segment, found `{:?}`",
sketch_group
),
source_ranges: vec![args.source_range],
})
})?
.get_base();
Ok(last_line.to[0])
}
pub async fn last_segment_y(args: Args) -> Result<MemoryItem, KclError> {
let sketch_group = args.get_sketch_group()?;
let result = inner_last_segment_y(sketch_group, args.clone())?;
args.make_user_val_from_f64(result)
}
#[stdlib {
name = "lastSegY",
}]
fn inner_last_segment_y(sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
let last_line = sketch_group
.value
.last()
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a SketchGroup with at least one segment, found `{:?}`",
sketch_group
),
source_ranges: vec![args.source_range],
})
})?
.get_base();
Ok(last_line.to[1])
}
pub async fn segment_length(args: Args) -> Result<MemoryItem, KclError> {
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
let result = inner_segment_length(&segment_name, sketch_group, args.clone())?;
args.make_user_val_from_f64(result)
}
#[stdlib {
name = "segLen",
}]
fn inner_segment_length(
segment_name: &TagIdentifier,
sketch_group: Box<SketchGroup>,
args: Args,
) -> Result<f64, KclError> {
let path = sketch_group.get_path_by_tag(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a segment name that exists in the given SketchGroup, found `{}`",
segment_name
),
source_ranges: vec![args.source_range],
})
})?;
let line = path.get_base();
let result = ((line.from[1] - line.to[1]).powi(2) + (line.from[0] - line.to[0]).powi(2)).sqrt();
Ok(result)
}
pub async fn segment_angle(args: Args) -> Result<MemoryItem, KclError> {
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
let result = inner_segment_angle(&segment_name, sketch_group, args.clone())?;
args.make_user_val_from_f64(result)
}
#[stdlib {
name = "segAng",
}]
fn inner_segment_angle(
segment_name: &TagIdentifier,
sketch_group: Box<SketchGroup>,
args: Args,
) -> Result<f64, KclError> {
let path = sketch_group.get_path_by_tag(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a segment name that exists in the given SketchGroup, found `{}`",
segment_name
),
source_ranges: vec![args.source_range],
})
})?;
let line = path.get_base();
let result = between(line.from.into(), line.to.into());
Ok(result.degrees())
}
pub async fn angle_to_match_length_x(args: Args) -> Result<MemoryItem, KclError> {
let (segment_name, to, sketch_group) = args.get_segment_name_to_number_sketch_group()?;
let result = inner_angle_to_match_length_x(&segment_name, to, sketch_group, args.clone())?;
args.make_user_val_from_f64(result)
}
#[stdlib {
name = "angleToMatchLengthX",
}]
fn inner_angle_to_match_length_x(
segment_name: &TagIdentifier,
to: f64,
sketch_group: Box<SketchGroup>,
args: Args,
) -> Result<f64, KclError> {
let path = sketch_group.get_path_by_tag(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a segment name that exists in the given SketchGroup, found `{}`",
segment_name
),
source_ranges: vec![args.source_range],
})
})?;
let line = path.get_base();
let length = ((line.from[1] - line.to[1]).powi(2) + (line.from[0] - line.to[0]).powi(2)).sqrt();
let last_line = sketch_group
.value
.last()
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a SketchGroup with at least one segment, found `{:?}`",
sketch_group
),
source_ranges: vec![args.source_range],
})
})?
.get_base();
let diff = (to - last_line.to[0]).abs();
let angle_r = (diff / length).acos();
if diff > length {
Ok(0.0)
} else {
Ok(angle_r.to_degrees())
}
}
pub async fn angle_to_match_length_y(args: Args) -> Result<MemoryItem, KclError> {
let (segment_name, to, sketch_group) = args.get_segment_name_to_number_sketch_group()?;
let result = inner_angle_to_match_length_y(&segment_name, to, sketch_group, args.clone())?;
args.make_user_val_from_f64(result)
}
#[stdlib {
name = "angleToMatchLengthY",
}]
fn inner_angle_to_match_length_y(
segment_name: &TagIdentifier,
to: f64,
sketch_group: Box<SketchGroup>,
args: Args,
) -> Result<f64, KclError> {
let path = sketch_group.get_path_by_tag(segment_name).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a segment name that exists in the given SketchGroup, found `{}`",
segment_name
),
source_ranges: vec![args.source_range],
})
})?;
let line = path.get_base();
let length = ((line.from[1] - line.to[1]).powi(2) + (line.from[0] - line.to[0]).powi(2)).sqrt();
let last_line = sketch_group
.value
.last()
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected a SketchGroup with at least one segment, found `{:?}`",
sketch_group
),
source_ranges: vec![args.source_range],
})
})?
.get_base();
let diff = (to - last_line.to[1]).abs();
let angle_r = (diff / length).asin();
if diff > length {
Ok(0.0)
} else {
Ok(angle_r.to_degrees())
}
}