Impl composite for Modeling Command types (#1196)

This commit is contained in:
Adam Chalmers
2023-12-12 09:26:36 -06:00
committed by GitHub
parent 793e3510cc
commit b01357b49e
5 changed files with 417 additions and 35 deletions

270
src/wasm-lib/Cargo.lock generated
View File

@ -127,6 +127,12 @@ dependencies = [
"backtrace",
]
[[package]]
name = "approx"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94"
[[package]]
name = "arc-swap"
version = "1.6.0"
@ -243,7 +249,7 @@ dependencies = [
"libm",
"num-bigint",
"num-integer",
"num-traits",
"num-traits 0.2.17",
"serde",
]
@ -329,7 +335,7 @@ dependencies = [
"indexmap 1.9.3",
"js-sys",
"once_cell",
"rand",
"rand 0.8.5",
"serde",
"serde_bytes",
"serde_json",
@ -394,6 +400,18 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cgmath"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
dependencies = [
"approx",
"mint",
"num-traits 0.1.43",
"rand 0.4.6",
]
[[package]]
name = "chrono"
version = "0.4.31"
@ -402,8 +420,10 @@ checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"js-sys",
"num-traits 0.2.17",
"serde",
"wasm-bindgen",
"windows-targets 0.48.5",
]
@ -580,7 +600,7 @@ dependencies = [
"criterion-plot",
"is-terminal",
"itertools 0.10.5",
"num-traits",
"num-traits 0.2.17",
"once_cell",
"oorandom",
"plotters",
@ -677,9 +697,9 @@ dependencies = [
[[package]]
name = "data-encoding"
version = "2.4.0"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
[[package]]
name = "databake"
@ -742,6 +762,49 @@ dependencies = [
"syn 2.0.39",
]
[[package]]
name = "diesel"
version = "2.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8"
dependencies = [
"bigdecimal",
"bitflags 2.4.1",
"byteorder",
"chrono",
"diesel_derives",
"mysqlclient-sys",
"num-bigint",
"num-integer",
"num-traits 0.2.17",
"percent-encoding",
"r2d2",
"serde_json",
"url",
"uuid",
]
[[package]]
name = "diesel_derives"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44"
dependencies = [
"diesel_table_macro_syntax",
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "diesel_table_macro_syntax"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5"
dependencies = [
"syn 2.0.39",
]
[[package]]
name = "diff"
version = "0.1.13"
@ -806,6 +869,26 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "enum-iterator"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7add3873b5dd076766ee79c8e406ad1a472c385476b9e38849f8eec24f1be689"
dependencies = [
"enum-iterator-derive",
]
[[package]]
name = "enum-iterator-derive"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@ -822,14 +905,26 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "euler"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f19d11568a4a46aee488bdab3a2963e5e2c3cfd6091aa0abceaddcea82c0bc1"
dependencies = [
"approx",
"cgmath",
]
[[package]]
name = "execution-plan"
version = "0.1.0"
dependencies = [
"bytes",
"kittycad",
"kittycad-modeling-cmds",
"serde",
"thiserror",
"uuid",
]
[[package]]
@ -946,6 +1041,12 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "funty"
version = "2.0.0"
@ -1299,7 +1400,7 @@ dependencies = [
"gif",
"jpeg-decoder",
"num-rational",
"num-traits",
"num-traits 0.2.17",
"png",
"qoi",
"tiff",
@ -1338,6 +1439,12 @@ dependencies = [
"serde",
]
[[package]]
name = "inflections"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a"
[[package]]
name = "insta"
version = "1.34.0"
@ -1504,7 +1611,7 @@ dependencies = [
"log",
"parse-display",
"phonenumber",
"rand",
"rand 0.8.5",
"reqwest",
"reqwest-conditional-middleware",
"reqwest-middleware",
@ -1521,6 +1628,42 @@ dependencies = [
"uuid",
]
[[package]]
name = "kittycad-modeling-cmds"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3217f9ffe9dce4b16303eeef539e7e27b743bc1c46eff8ce64657745a2b75ca"
dependencies = [
"chrono",
"data-encoding",
"diesel",
"diesel_derives",
"enum-iterator",
"enum-iterator-derive",
"euler",
"http",
"kittycad-unit-conversion-derive",
"measurements",
"parse-display",
"parse-display-derive",
"schemars",
"serde",
"serde_bytes",
"uuid",
]
[[package]]
name = "kittycad-unit-conversion-derive"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7001c46a92c1edce6722a3900539b198230980799035f02d92b4e7df3fc08738"
dependencies = [
"inflections",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -1620,6 +1763,15 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "measurements"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5b734b4e8187ea5777bc29c086f0970a27d8de42061b48f5af32cafc0ca904b"
dependencies = [
"libm",
]
[[package]]
name = "memchr"
version = "2.6.4"
@ -1667,6 +1819,12 @@ dependencies = [
"simd-adler32",
]
[[package]]
name = "mint"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff"
[[package]]
name = "mio"
version = "0.8.9"
@ -1678,6 +1836,16 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "mysqlclient-sys"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f61b381528ba293005c42a409dd73d034508e273bf90481f17ec2e964a6e969b"
dependencies = [
"pkg-config",
"vcpkg",
]
[[package]]
name = "newline-converter"
version = "0.3.0"
@ -1705,7 +1873,7 @@ checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
"num-traits 0.2.17",
]
[[package]]
@ -1715,7 +1883,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
"num-traits 0.2.17",
]
[[package]]
@ -1726,7 +1894,16 @@ checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
"num-traits 0.2.17",
]
[[package]]
name = "num-traits"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
dependencies = [
"num-traits 0.2.17",
]
[[package]]
@ -1812,7 +1989,7 @@ dependencies = [
"phonenumber",
"proc-macro2",
"quote",
"rand",
"rand 0.8.5",
"regex",
"reqwest",
"reqwest-middleware",
@ -1864,7 +2041,7 @@ dependencies = [
"lazy_static",
"percent-encoding",
"pin-project",
"rand",
"rand 0.8.5",
"thiserror",
]
@ -2019,7 +2196,7 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45"
dependencies = [
"num-traits",
"num-traits 0.2.17",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
@ -2136,12 +2313,36 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r2d2"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
dependencies = [
"log",
"parking_lot 0.12.1",
"scheduled-thread-pool",
]
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi",
]
[[package]]
name = "rand"
version = "0.8.5"
@ -2150,7 +2351,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
@ -2160,9 +2361,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]]
name = "rand_core"
version = "0.6.4"
@ -2192,6 +2408,15 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
@ -2400,7 +2625,7 @@ checksum = "e09bbcb5003282bcb688f0bae741b278e9c7e8f378f561522c9806c58e075d9b"
dependencies = [
"anyhow",
"chrono",
"rand",
"rand 0.8.5",
]
[[package]]
@ -2528,6 +2753,15 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "scheduled-thread-pool"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19"
dependencies = [
"parking_lot 0.12.1",
]
[[package]]
name = "schemars"
version = "0.8.16"
@ -3444,7 +3678,7 @@ dependencies = [
"http",
"httparse",
"log",
"rand",
"rand 0.8.5",
"rustls",
"sha1",
"thiserror",

View File

@ -9,5 +9,7 @@ description = "A DSL for composing KittyCAD API queries"
[dependencies]
bytes = "1.5"
kittycad = { workspace = true, features = ["requests"] }
kittycad-modeling-cmds = "0.1.4"
serde = { version = "1", features = ["derive"] }
thiserror = "1"
uuid = "1.6.1"

View File

@ -1,14 +1,18 @@
use crate::{ExecutionError, Value};
use kittycad_modeling_cmds::{id::ModelingCmdId, shared::Point3d, MovePathPen};
use uuid::Uuid;
use crate::{Address, ExecutionError, Value};
use super::Composite;
impl Composite for kittycad::types::Point3D {
impl<T> Composite for kittycad_modeling_cmds::shared::Point3d<T>
where
Value: From<T>,
T: TryFrom<Value, Error = ExecutionError>,
{
fn into_parts(self) -> Vec<Value> {
let points = [self.x, self.y, self.z];
points
.into_iter()
.map(|x| Value::NumericValue(crate::NumericValue::Float(x)))
.collect()
points.into_iter().map(|component| component.into()).collect()
}
fn from_parts(values: &[Option<Value>]) -> Result<Self, ExecutionError> {
@ -20,3 +24,75 @@ impl Composite for kittycad::types::Point3D {
Ok(Self { x, y, z })
}
}
const START_PATH: &str = "StartPath";
const MOVE_PATH_PEN: &str = "MovePathPen";
impl Composite for MovePathPen {
fn into_parts(self) -> Vec<Value> {
let MovePathPen { path, to } = self;
let to = to.into_parts();
let mut vals = Vec::with_capacity(1 + to.len());
vals.push(Value::Uuid(path.into()));
vals.extend(to);
vals
}
fn from_parts(values: &[Option<Value>]) -> Result<Self, ExecutionError> {
let path = get_some(values, 0)?;
let path = Uuid::try_from(path)?;
let path = ModelingCmdId::from(path);
let to = Point3d::from_parts(&values[1..])?;
let params = MovePathPen { path, to };
Ok(params)
}
}
/// Memory layout for modeling commands:
/// Field 0 is the command's name.
/// Fields 1 onwards are the command's fields.
impl Composite for kittycad_modeling_cmds::ModelingCmd {
fn into_parts(self) -> Vec<Value> {
let (endpoint_name, params) = match self {
kittycad_modeling_cmds::ModelingCmd::StartPath => (START_PATH, vec![]),
kittycad_modeling_cmds::ModelingCmd::MovePathPen(MovePathPen { path, to }) => {
let to = to.into_parts();
let mut vals = Vec::with_capacity(1 + to.len());
vals.push(Value::Uuid(path.into()));
vals.extend(to);
(MOVE_PATH_PEN, vals)
}
_ => todo!(),
};
let mut out = Vec::with_capacity(params.len() + 1);
out.push(endpoint_name.to_owned().into());
out.extend(params);
out
}
fn from_parts(values: &[Option<Value>]) -> Result<Self, ExecutionError> {
// Check the array has an element at index 0
let first_memory = values
.get(0)
.ok_or(ExecutionError::MemoryWrongSize { expected: 1 })?
.to_owned();
// The element should be Some
let first_memory = first_memory.ok_or(ExecutionError::MemoryWrongSize { expected: 1 })?;
let endpoint_name: String = first_memory.try_into()?;
match endpoint_name.as_str() {
START_PATH => Ok(Self::StartPath),
MOVE_PATH_PEN => {
let params = MovePathPen::from_parts(&values[1..])?;
Ok(Self::MovePathPen(params))
}
other => Err(ExecutionError::UnrecognizedEndpoint(other.to_owned())),
}
}
}
fn get_some(values: &[Option<Value>], i: usize) -> Result<Value, ExecutionError> {
let addr = Address(0); // TODO: pass the `start` addr in
let v = values.get(i).ok_or(ExecutionError::MemoryEmpty { addr })?.to_owned();
let v = v.ok_or(ExecutionError::MemoryEmpty { addr })?.to_owned();
Ok(v)
}

View File

@ -9,6 +9,7 @@
use composite::Composite;
use serde::{Deserialize, Serialize};
use std::fmt;
use uuid::Uuid;
mod composite;
#[cfg(test)]
@ -78,8 +79,56 @@ impl Memory {
pub enum Value {
String(String),
NumericValue(NumericValue),
Uuid(Uuid),
}
impl From<Uuid> for Value {
fn from(u: Uuid) -> Self {
Self::Uuid(u)
}
}
impl From<String> for Value {
fn from(value: String) -> Self {
Self::String(value)
}
}
impl From<f64> for Value {
fn from(value: f64) -> Self {
Self::NumericValue(NumericValue::Float(value))
}
}
impl TryFrom<Value> for String {
type Error = ExecutionError;
fn try_from(value: Value) -> Result<Self, Self::Error> {
if let Value::String(s) = value {
Ok(s)
} else {
Err(ExecutionError::MemoryWrongType {
expected: "string",
actual: format!("{value:?}"),
})
}
}
}
impl TryFrom<Value> for Uuid {
type Error = ExecutionError;
fn try_from(value: Value) -> Result<Self, Self::Error> {
if let Value::Uuid(u) = value {
Ok(u)
} else {
Err(ExecutionError::MemoryWrongType {
expected: "uuid",
actual: format!("{value:?}"),
})
}
}
}
impl TryFrom<Value> for f64 {
type Error = ExecutionError;
@ -95,13 +144,6 @@ impl TryFrom<Value> for f64 {
}
}
#[cfg(test)]
impl From<f64> for Value {
fn from(value: f64) -> Self {
Self::NumericValue(NumericValue::Float(value))
}
}
#[cfg(test)]
impl From<usize> for Value {
fn from(value: usize) -> Self {
@ -276,4 +318,6 @@ pub enum ExecutionError {
MemoryWrongType { expected: &'static str, actual: String },
#[error("Wanted {expected} values but did not get enough")]
MemoryWrongSize { expected: usize },
#[error("No endpoint {0} recognized")]
UnrecognizedEndpoint(String),
}

View File

@ -1,4 +1,4 @@
use kittycad::types::Point3D;
use kittycad_modeling_cmds::{id::ModelingCmdId, shared::Point3d, ModelingCmd, MovePathPen};
use super::*;
@ -57,7 +57,11 @@ fn add_to_composite_value() {
let mut mem = Memory::default();
// Write a point to memory.
let point_before = Point3D { x: 2.0, y: 3.0, z: 4.0 };
let point_before = Point3d {
x: 2.0f64,
y: 3.0,
z: 4.0,
};
let start_addr = Address(0);
mem.set_composite(point_before, start_addr);
assert_eq!(mem.0[0], Some(2.0.into()));
@ -79,13 +83,35 @@ fn add_to_composite_value() {
.unwrap();
// Read the point out of memory, validate it.
let point_after: Point3D = mem.get_composite(start_addr).unwrap();
let point_after: Point3d<f64> = mem.get_composite(start_addr).unwrap();
assert_eq!(
point_after,
Point3D {
Point3d {
x: 42.0,
y: 3.0,
z: 4.0
}
)
}
#[test]
fn api_types() {
let mut mem = Memory::default();
let start_addr = Address(0);
let id = ModelingCmdId(Uuid::parse_str("6306afa2-3999-4b03-af30-1efad7cdc6fc").unwrap());
let p = Point3d {
x: 2.0f64,
y: 3.0,
z: 4.0,
};
let val_in = ModelingCmd::MovePathPen(MovePathPen { path: id, to: p });
mem.set_composite(val_in, start_addr);
let val_out: ModelingCmd = mem.get_composite(start_addr).unwrap();
match val_out {
ModelingCmd::MovePathPen(params) => {
assert_eq!(params.to, p);
assert_eq!(params.path, id);
}
_ => panic!("unexpected ModelingCmd variant"),
}
}