Skip to content

Commit 0996da7

Browse files
committed
New ExecKclProject command
This command takes in a KCL project (which is a list of files, like a virtual filesystem directory) and returns the same Ok/Err result type that the frontend usually gets for KCL execution. Internally, it validates the filepaths (to make sure they're all relative to the KCL project root), and uses types from the frontend, which have been moved into a kcl-api crate.
1 parent d1dc6ff commit 0996da7

4 files changed

Lines changed: 86 additions & 36 deletions

File tree

Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modeling-cmds/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ tabled = ["dep:tabled"]
1818
ts-rs = ["dep:ts-rs"]
1919
slog = ["dep:slog"]
2020
cxx = ["dep:cxx"]
21-
websocket = ["dep:serde_json"]
21+
websocket = []
2222
webrtc = ["dep:webrtc"]
2323
unstable_exhaustive = []
2424
python = ["dep:pyo3", "dep:pyo3-stub-gen"]
@@ -36,6 +36,7 @@ enum-iterator-derive = "1.2.1"
3636
euler = "0.4.1"
3737
http = "1.4.0"
3838
kittycad-modeling-cmds-macros = { workspace = true }
39+
kcl-api = { version = "0.2.161", git = "https://github.com/KittyCAD/modeling-app", branch = "achalmers/kcl-in-engine" }
3940
kittycad-unit-conversion-derive = "0.1.0"
4041
# Fork of <crates.io/crates/measurements>
4142
measurements = { package = "kittycad-measurements", version = "0.11.2" }
@@ -50,7 +51,7 @@ pyo3-stub-gen = { version = "0.22.3", optional = true, default-features = false,
5051
schemars = { version = "0.8.22", features = ["bigdecimal04", "chrono", "url", "uuid1"] }
5152
serde = { version = "1.0.219", features = ["derive"] }
5253
serde_bytes = "0.11.19"
53-
serde_json = { version = "1.0.150", optional = true }
54+
serde_json = "1.0.150"
5455
slog = { version = "2.8.2", optional = true }
5556
tabled = { version = "0.20", optional = true }
5657
ts-rs = { version = "12.0.1", optional = true, features = ["chrono-impl", "uuid-impl", "no-serde-warnings", "serde-json-impl"] }

modeling-cmds/src/exec_kcl.rs

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,83 @@
11
use bon::Builder;
22
use schemars::JsonSchema;
3-
use serde::Deserialize;
4-
use serde::Serialize;
3+
use serde::{Deserialize, Serialize};
54

6-
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Builder)]
5+
use crate::shared::safe_filepath::SafeFilepath;
6+
7+
/// A KCL project that can be executed.
8+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Default, Builder)]
79
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
810
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
911
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1012
#[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
11-
pub struct ExecKclProjectOk {}
13+
pub struct KclProject {
14+
/// All files in the project.
15+
pub files: Vec<KclFile>,
16+
/// Which file is the entrypoint?
17+
/// This is the first KCL file to be executed,
18+
/// the root of the KCL module tree.
19+
pub entrypoint: SafeFilePath,
20+
}
1221

13-
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Builder)]
22+
/// Region-creation algorithm version.
23+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Default, Builder)]
1424
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1525
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1626
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1727
#[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
18-
pub struct ExecKclProjectErr {}
28+
pub struct KclFile {
29+
/// Where is the file, relative to the project directory?
30+
pub path: SafeFilepath,
31+
/// Contents of the file, as UTF-8 encoded bytes.
32+
#[serde(deserialize_with = "serde_bytes::deserialize")]
33+
#[serde(serialize_with = "serde_bytes::serialize")]
34+
pub contents: Vec<u8>,
35+
}
36+
37+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Builder)]
38+
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
39+
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
40+
#[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
41+
/// Successful KCL project execution response.
42+
pub struct ExecKclProjectOk {
43+
/// Scene graph updates and execution metadata produced by running the KCL project.
44+
pub scene_graph_delta:
45+
kcl_api::SceneGraphDelta<kcl_api::SceneGraph<serde_json::Value, serde_json::Value>, serde_json::Value>,
46+
}
47+
48+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Builder)]
49+
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
50+
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
51+
#[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
52+
/// Failed KCL project execution response.
53+
pub struct ExecKclProjectErr {
54+
/// Error produced while executing the KCL project.
55+
pub error: kcl_api::Error,
56+
}
57+
58+
#[cfg(feature = "arbitrary")]
59+
// TODO: Impl this properly for fuzzing.
60+
impl<'a> arbitrary::Arbitrary<'a> for ExecKclProjectOk {
61+
fn arbitrary(_u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
62+
Ok(Self {
63+
scene_graph_delta: kcl_api::SceneGraphDelta::new(
64+
kcl_api::SceneGraph::empty(kcl_api::ProjectId(0), kcl_api::FileId(0), kcl_api::Version(0)),
65+
Vec::new(),
66+
false,
67+
serde_json::Value::Null,
68+
),
69+
})
70+
}
71+
}
72+
73+
#[cfg(feature = "arbitrary")]
74+
// TODO: Impl this properly for fuzzing.
75+
impl<'a> arbitrary::Arbitrary<'a> for ExecKclProjectErr {
76+
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
77+
Ok(Self {
78+
error: kcl_api::Error {
79+
msg: <String as arbitrary::Arbitrary>::arbitrary(u)?,
80+
},
81+
})
82+
}
83+
}

modeling-cmds/src/shared.rs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ use crate::{
1212
def_enum::negative_one,
1313
length_unit::LengthUnit,
1414
output::ExtrusionFaceInfo,
15-
shared::safe_filepath::SafeFilepath,
1615
units::{self, UnitAngle},
1716
};
1817

1918
mod point;
20-
mod safe_filepath;
19+
pub mod safe_filepath;
2120

2221
/// An edge can be referenced by its uuid or by the faces that uniquely define it.
2322
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Builder)]
@@ -2184,29 +2183,3 @@ impl From<BodiesUpdated> for BodiesCreated {
21842183
fn one() -> f32 {
21852184
1.0
21862185
}
2187-
2188-
/// A KCL project that can be executed.
2189-
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Default, Builder)]
2190-
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2191-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2192-
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2193-
#[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2194-
pub struct KclProject {
2195-
/// All files in the project.
2196-
files: Vec<KclFile>,
2197-
}
2198-
2199-
/// Region-creation algorithm version.
2200-
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Default, Builder)]
2201-
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2202-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2203-
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2204-
#[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2205-
pub struct KclFile {
2206-
/// Where is the file, relative to the project directory?
2207-
pub path: SafeFilepath,
2208-
/// Contents of the file, as UTF-8 encoded bytes.
2209-
#[serde(deserialize_with = "serde_bytes::deserialize")]
2210-
#[serde(serialize_with = "serde_bytes::serialize")]
2211-
pub contents: Vec<u8>,
2212-
}

0 commit comments

Comments
 (0)