Tag as top level construct (#2769)
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* udpages
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* fixes
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* update
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* better functions
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* backwards compat everywhere
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* update docs
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* udpates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* fixes
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* fixes
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* add lsp symbols stuff;
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* tests for dupes
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* Revert "tests for dupes"
This reverts commit 6acaf5a9fa
.
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* initial test updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* tests
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* fixes
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* test
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* fixes
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* fix tests
Signed-off-by: Jess Frazelle <github@jessfraz.com>
---------
Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -13,6 +13,7 @@ pub mod segment;
|
||||
pub mod shapes;
|
||||
pub mod shell;
|
||||
pub mod sketch;
|
||||
pub mod string_or_struct;
|
||||
pub mod types;
|
||||
pub mod utils;
|
||||
|
||||
@ -27,12 +28,12 @@ use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
ast::types::parse_json_number_as_f64,
|
||||
ast::types::{parse_json_number_as_f64, TagDeclarator},
|
||||
docs::StdLibFn,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
executor::{
|
||||
ExecutorContext, ExtrudeGroup, ExtrudeGroupSet, ExtrudeSurface, MemoryItem, Metadata, ProgramMemory,
|
||||
SketchGroup, SketchGroupSet, SketchSurface, SourceRange,
|
||||
SketchGroup, SketchGroupSet, SketchSurface, SourceRange, TagIdentifier,
|
||||
},
|
||||
std::{kcl_stdlib::KclStdLibFn, sketch::FaceTag},
|
||||
};
|
||||
@ -361,7 +362,15 @@ impl Args {
|
||||
|
||||
fn get_circle_args(
|
||||
&self,
|
||||
) -> Result<([f64; 2], f64, crate::std::shapes::SketchSurfaceOrGroup, Option<String>), KclError> {
|
||||
) -> Result<
|
||||
(
|
||||
[f64; 2],
|
||||
f64,
|
||||
crate::std::shapes::SketchSurfaceOrGroup,
|
||||
Option<TagDeclarator>,
|
||||
),
|
||||
KclError,
|
||||
> {
|
||||
let first_value = self
|
||||
.args
|
||||
.first()
|
||||
@ -443,41 +452,26 @@ impl Args {
|
||||
}));
|
||||
};
|
||||
|
||||
if let Some(fourth_value) = self.args.get(3) {
|
||||
let tag: String = serde_json::from_value(fourth_value.get_json_value()?).map_err(|e| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("Failed to deserialize String from JSON: {}", e),
|
||||
source_ranges: vec![self.source_range],
|
||||
})
|
||||
})?;
|
||||
Ok((center, radius, sketch_group_or_surface, Some(tag)))
|
||||
let tag = if let Some(tag) = self.args.get(3) {
|
||||
tag.get_tag_declarator_opt()?
|
||||
} else {
|
||||
Ok((center, radius, sketch_group_or_surface, None))
|
||||
}
|
||||
None
|
||||
};
|
||||
|
||||
Ok((center, radius, sketch_group_or_surface, tag))
|
||||
}
|
||||
|
||||
fn get_segment_name_sketch_group(&self) -> Result<(String, Box<SketchGroup>), KclError> {
|
||||
fn get_segment_name_sketch_group(&self) -> Result<(TagIdentifier, Box<SketchGroup>), KclError> {
|
||||
// Iterate over our args, the first argument should be a UserVal with a string value.
|
||||
// The second argument should be a SketchGroup.
|
||||
let first_value = self
|
||||
.args
|
||||
.first()
|
||||
.ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("Expected a string as the first argument, found `{:?}`", self.args),
|
||||
source_ranges: vec![self.source_range],
|
||||
})
|
||||
})?
|
||||
.get_json_value()?;
|
||||
|
||||
let segment_name = if let serde_json::Value::String(s) = first_value {
|
||||
s.to_string()
|
||||
} else {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
let first_value = self.args.first().ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("Expected a string as the first argument, found `{:?}`", self.args),
|
||||
source_ranges: vec![self.source_range],
|
||||
}));
|
||||
};
|
||||
})
|
||||
})?;
|
||||
|
||||
let segment_name = first_value.get_tag_identifier()?;
|
||||
|
||||
let second_value = self.args.get(1).ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
@ -609,7 +603,7 @@ impl Args {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_sketch_group_and_optional_tag(&self) -> Result<(Box<SketchGroup>, Option<String>), KclError> {
|
||||
fn get_sketch_group_and_optional_tag(&self) -> Result<(Box<SketchGroup>, Option<TagDeclarator>), KclError> {
|
||||
let first_value = self.args.first().ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("Expected a SketchGroup as the first argument, found `{:?}`", self.args),
|
||||
@ -626,17 +620,13 @@ impl Args {
|
||||
}));
|
||||
};
|
||||
|
||||
if let Some(second_value) = self.args.get(1) {
|
||||
let tag: String = serde_json::from_value(second_value.get_json_value()?).map_err(|e| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("Failed to deserialize String from JSON: {}", e),
|
||||
source_ranges: vec![self.source_range],
|
||||
})
|
||||
})?;
|
||||
Ok((sketch_group, Some(tag)))
|
||||
let tag = if let Some(tag) = self.args.get(1) {
|
||||
tag.get_tag_declarator_opt()?
|
||||
} else {
|
||||
Ok((sketch_group, None))
|
||||
}
|
||||
None
|
||||
};
|
||||
|
||||
Ok((sketch_group, tag))
|
||||
}
|
||||
|
||||
fn get_data_and_optional_tag<T: serde::de::DeserializeOwned>(&self) -> Result<(T, Option<FaceTag>), KclError> {
|
||||
@ -750,7 +740,7 @@ impl Args {
|
||||
|
||||
fn get_data_and_sketch_group_and_tag<T: serde::de::DeserializeOwned>(
|
||||
&self,
|
||||
) -> Result<(T, Box<SketchGroup>, Option<String>), KclError> {
|
||||
) -> Result<(T, Box<SketchGroup>, Option<TagDeclarator>), KclError> {
|
||||
let first_value = self
|
||||
.args
|
||||
.first()
|
||||
@ -785,7 +775,7 @@ impl Args {
|
||||
}));
|
||||
};
|
||||
let tag = if let Some(tag) = self.args.get(2) {
|
||||
tag.get_json_opt()?
|
||||
tag.get_tag_declarator_opt()?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -795,7 +785,7 @@ impl Args {
|
||||
|
||||
fn get_data_and_sketch_surface<T: serde::de::DeserializeOwned>(
|
||||
&self,
|
||||
) -> Result<(T, SketchSurface, Option<String>), KclError> {
|
||||
) -> Result<(T, SketchSurface, Option<TagDeclarator>), KclError> {
|
||||
let first_value = self
|
||||
.args
|
||||
.first()
|
||||
@ -834,8 +824,9 @@ impl Args {
|
||||
source_ranges: vec![self.source_range],
|
||||
}));
|
||||
};
|
||||
|
||||
let tag = if let Some(tag) = self.args.get(2) {
|
||||
tag.get_json_opt()?
|
||||
tag.get_tag_declarator_opt()?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -931,7 +922,7 @@ impl Args {
|
||||
|
||||
fn get_data_and_extrude_group_and_tag<T: serde::de::DeserializeOwned>(
|
||||
&self,
|
||||
) -> Result<(T, Box<ExtrudeGroup>, Option<String>), KclError> {
|
||||
) -> Result<(T, Box<ExtrudeGroup>, Option<TagDeclarator>), KclError> {
|
||||
let first_value = self
|
||||
.args
|
||||
.first()
|
||||
@ -971,8 +962,9 @@ impl Args {
|
||||
source_ranges: vec![self.source_range],
|
||||
}));
|
||||
};
|
||||
|
||||
let tag = if let Some(tag) = self.args.get(2) {
|
||||
tag.get_json_opt()?
|
||||
tag.get_tag_declarator_opt()?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -980,30 +972,54 @@ impl Args {
|
||||
Ok((data, extrude_group, tag))
|
||||
}
|
||||
|
||||
fn get_segment_name_to_number_sketch_group(&self) -> Result<(String, f64, Box<SketchGroup>), KclError> {
|
||||
// Iterate over our args, the first argument should be a UserVal with a string value.
|
||||
// The second argument should be a number.
|
||||
// The third argument should be a SketchGroup.
|
||||
let first_value = self
|
||||
.args
|
||||
.first()
|
||||
.ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("Expected a string as the first argument, found `{:?}`", self.args),
|
||||
source_ranges: vec![self.source_range],
|
||||
})
|
||||
})?
|
||||
.get_json_value()?;
|
||||
fn get_tag_and_extrude_group(&self) -> Result<(TagIdentifier, Box<ExtrudeGroup>), KclError> {
|
||||
let first_value = self.args.first().ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("Expected a struct as the first argument, found `{:?}`", self.args),
|
||||
source_ranges: vec![self.source_range],
|
||||
})
|
||||
})?;
|
||||
|
||||
let segment_name = if let serde_json::Value::String(s) = first_value {
|
||||
s.to_string()
|
||||
let tag = first_value.get_tag_identifier()?;
|
||||
|
||||
let second_value = self.args.get(1).ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!(
|
||||
"Expected an ExtrudeGroup as the second argument, found `{:?}`",
|
||||
self.args
|
||||
),
|
||||
source_ranges: vec![self.source_range],
|
||||
})
|
||||
})?;
|
||||
|
||||
let extrude_group = if let MemoryItem::ExtrudeGroup(eg) = second_value {
|
||||
eg.clone()
|
||||
} else {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
message: format!("Expected a string as the first argument, found `{:?}`", self.args),
|
||||
message: format!(
|
||||
"Expected an ExtrudeGroup as the second argument, found `{:?}`",
|
||||
self.args
|
||||
),
|
||||
source_ranges: vec![self.source_range],
|
||||
}));
|
||||
};
|
||||
|
||||
Ok((tag, extrude_group))
|
||||
}
|
||||
|
||||
fn get_segment_name_to_number_sketch_group(&self) -> Result<(TagIdentifier, f64, Box<SketchGroup>), KclError> {
|
||||
// Iterate over our args, the first argument should be a UserVal with a string value.
|
||||
// The second argument should be a number.
|
||||
// The third argument should be a SketchGroup.
|
||||
let first_value = self.args.first().ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("Expected a string as the first argument, found `{:?}`", self.args),
|
||||
source_ranges: vec![self.source_range],
|
||||
})
|
||||
})?;
|
||||
|
||||
let segment_name = first_value.get_tag_identifier()?;
|
||||
|
||||
let second_value = self
|
||||
.args
|
||||
.get(1)
|
||||
@ -1075,10 +1091,10 @@ impl Args {
|
||||
pub async fn get_adjacent_face_to_tag(
|
||||
&self,
|
||||
extrude_group: &ExtrudeGroup,
|
||||
tag: &str,
|
||||
tag: &TagIdentifier,
|
||||
must_be_planar: bool,
|
||||
) -> Result<uuid::Uuid, KclError> {
|
||||
if tag.is_empty() {
|
||||
if tag.value.is_empty() {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
message: "Expected a non-empty tag for the face".to_string(),
|
||||
source_ranges: vec![self.source_range],
|
||||
@ -1089,16 +1105,33 @@ impl Args {
|
||||
.value
|
||||
.iter()
|
||||
.find_map(|extrude_surface| match extrude_surface {
|
||||
ExtrudeSurface::ExtrudePlane(extrude_plane) if extrude_plane.name == tag => {
|
||||
Some(Ok(extrude_plane.face_id))
|
||||
ExtrudeSurface::ExtrudePlane(extrude_plane) => {
|
||||
if let Some(plane_tag) = &extrude_plane.tag {
|
||||
if plane_tag.name == tag.value {
|
||||
Some(Ok(extrude_plane.face_id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
// The must be planar check must be called before the arc check.
|
||||
ExtrudeSurface::ExtrudeArc(_) if must_be_planar => Some(Err(KclError::Type(KclErrorDetails {
|
||||
message: format!("Tag `{}` is a non-planar surface", tag),
|
||||
message: format!("Tag `{}` is a non-planar surface", tag.value),
|
||||
source_ranges: vec![self.source_range],
|
||||
}))),
|
||||
ExtrudeSurface::ExtrudeArc(extrude_arc) if extrude_arc.name == tag => Some(Ok(extrude_arc.face_id)),
|
||||
ExtrudeSurface::ExtrudePlane(_) | ExtrudeSurface::ExtrudeArc(_) => None,
|
||||
ExtrudeSurface::ExtrudeArc(extrude_arc) => {
|
||||
if let Some(arc_tag) = &extrude_arc.tag {
|
||||
if arc_tag.name == tag.value {
|
||||
Some(Ok(extrude_arc.face_id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
{
|
||||
return face_from_surface;
|
||||
@ -1106,8 +1139,12 @@ impl Args {
|
||||
|
||||
// A face could also be the result of a chamfer or fillet.
|
||||
if let Some(face_from_chamfer_fillet) = extrude_group.fillet_or_chamfers.iter().find_map(|fc| {
|
||||
if fc.tag() == Some(tag) {
|
||||
Some(Ok(fc.id()))
|
||||
if let Some(ntag) = &fc.tag() {
|
||||
if ntag.name == tag.value {
|
||||
Some(Ok(fc.id()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -1120,7 +1157,7 @@ impl Args {
|
||||
|
||||
// If we still haven't found the face, return an error.
|
||||
Err(KclError::Type(KclErrorDetails {
|
||||
message: format!("Expected a face with the tag `{}`", tag),
|
||||
message: format!("Expected a face with the tag `{}`", tag.value),
|
||||
source_ranges: vec![self.source_range],
|
||||
}))
|
||||
}
|
||||
|
Reference in New Issue
Block a user