Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impl execution_plan::Value for many modeling command types #45

Merged
merged 1 commit into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions execution-plan-macros/tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ fn test_derive_on_enum() {
(
"named fields",
FooEnum::A { x: 3 },
vec![Primitive::from("A".to_owned()), Primitive::from(3)],
vec![Primitive::from("A".to_owned()), Primitive::from(3u32)],
),
(
"named fields with Option::Some",
FooEnum::B { y: Some(3) },
vec![
Primitive::from("B".to_owned()),
Primitive::from("Some".to_owned()),
Primitive::from(3),
Primitive::from(3u32),
],
),
(
Expand All @@ -66,7 +66,7 @@ fn test_derive_on_enum() {
FooEnum::C(4, "hello".to_owned()),
vec![
Primitive::from("C".to_owned()),
Primitive::from(4),
Primitive::from(4u32),
Primitive::from("hello".to_owned()),
],
),
Expand Down Expand Up @@ -106,7 +106,7 @@ fn test_derive_on_struct() {
},
vec![
Primitive::from(1.2),
Primitive::from(2),
Primitive::from(2u32),
Primitive::from("Some".to_owned()),
Primitive::from(true),
Primitive::from("hello".to_owned()),
Expand All @@ -122,7 +122,7 @@ fn test_derive_on_struct() {
},
vec![
Primitive::from(1.2),
Primitive::from(2),
Primitive::from(2u32),
Primitive::from("None".to_owned()),
Primitive::from("hello".to_owned()),
],
Expand Down
28 changes: 28 additions & 0 deletions execution-plan-traits/src/containers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{MemoryError, Primitive, Value};
const NONE: &str = "None";
const SOME: &str = "Some";

/// Use the standard enum convention (a string for the variant tag, then all fields of the variant)
impl<T> Value for Option<T>
where
T: Value,
Expand Down Expand Up @@ -42,3 +43,30 @@ where
}
}
}

/// Store the vec's length as the first primitive, then lay out all elements.
impl<T> Value for Vec<T>
where
T: Value,
{
fn into_parts(self) -> Vec<Primitive> {
let mut parts: Vec<Primitive> = Vec::with_capacity(self.len() + 1);
parts.push(self.len().into());
parts.extend(self.into_iter().flat_map(|part| part.into_parts()));
parts
}

fn from_parts<I>(values: &mut I) -> Result<Self, MemoryError>
where
I: Iterator<Item = Option<Primitive>>,
{
// Read the length of the vec -- how many elements does it have?
let n: usize = values
.next()
.flatten()
.ok_or(MemoryError::MemoryWrongSize)?
.try_into()?;
// Read `n` elements from the parts.
(0..n).map(|_| T::from_parts(values)).collect()
}
}
25 changes: 25 additions & 0 deletions execution-plan-traits/src/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,36 @@ impl TryFrom<Primitive> for usize {
}
}

impl TryFrom<Primitive> for u32 {
type Error = MemoryError;

fn try_from(value: Primitive) -> Result<Self, Self::Error> {
if let Primitive::NumericValue(NumericPrimitive::Integer(x)) = value {
Ok(x.try_into().map_err(|_| MemoryError::MemoryWrongType {
expected: "u32",
actual: x.to_string(),
})?)
} else {
Err(MemoryError::MemoryWrongType {
expected: "u32",
actual: format!("{value:?}"),
})
}
}
}

impl From<usize> for Primitive {
fn from(value: usize) -> Self {
Self::NumericValue(NumericPrimitive::Integer(value))
}
}

impl From<u32> for Primitive {
fn from(value: u32) -> Self {
Self::NumericValue(NumericPrimitive::Integer(value as usize))
}
}

/// Various kinds of number.
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum NumericPrimitive {
Expand Down Expand Up @@ -202,3 +226,4 @@ impl_value_on_primitive_ish!(Value, Uuid);
type VecU8 = Vec<u8>;
impl_value_on_primitive_ish!(Value, VecU8);
impl_value_on_primitive_ish!(Value, usize);
impl_value_on_primitive_ish!(Value, u32);
14 changes: 7 additions & 7 deletions execution-plan/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ async fn add_literals() {
let plan = vec![Instruction::Arithmetic {
arithmetic: Arithmetic {
operation: Operation::Add,
operand0: Operand::Literal(3.into()),
operand1: Operand::Literal(2.into()),
operand0: Operand::Literal(3u32.into()),
operand1: Operand::Literal(2u32.into()),
},
destination: Address(1),
}];
let mut mem = Memory::default();
let client = test_client().await;
execute(&mut mem, plan, client).await.expect("failed to execute plan");
assert_eq!(mem.get(&Address(1)), Some(&5.into()))
assert_eq!(mem.get(&Address(1)), Some(&5u32.into()))
}

#[tokio::test]
Expand All @@ -60,14 +60,14 @@ async fn add_literal_to_reference() {
// Memory addr 0 contains 450
Instruction::Set {
address: Address(0),
value: 450.into(),
value: 450u32.into(),
},
// Add 20 to addr 0
Instruction::Arithmetic {
arithmetic: Arithmetic {
operation: Operation::Add,
operand0: Operand::Reference(Address(0)),
operand1: Operand::Literal(20.into()),
operand1: Operand::Literal(20u32.into()),
},
destination: Address(1),
},
Expand All @@ -76,7 +76,7 @@ async fn add_literal_to_reference() {
let mut mem = Memory::default();
let client = test_client().await;
execute(&mut mem, plan, client).await.expect("failed to execute plan");
assert_eq!(mem.get(&Address(1)), Some(&470.into()))
assert_eq!(mem.get(&Address(1)), Some(&470u32.into()))
}

#[tokio::test]
Expand All @@ -103,7 +103,7 @@ async fn add_to_composite_value() {
arithmetic: Arithmetic {
operation: Operation::Add,
operand0: Operand::Reference(start_addr),
operand1: Operand::Literal(40.into()),
operand1: Operand::Literal(40u32.into()),
},
destination: start_addr,
}],
Expand Down
22 changes: 22 additions & 0 deletions modeling-cmds/src/id.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use kittycad_execution_plan_traits::{MemoryError, Primitive};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
Expand Down Expand Up @@ -32,3 +33,24 @@ impl std::fmt::Display for ModelingCmdId {
self.0.fmt(f)
}
}

impl From<ModelingCmdId> for Primitive {
fn from(id: ModelingCmdId) -> Self {
Self::Uuid(id.into())
}
}

impl TryFrom<Primitive> for ModelingCmdId {
type Error = MemoryError;

fn try_from(value: Primitive) -> Result<Self, Self::Error> {
if let Primitive::Uuid(u) = value {
Ok(u.into())
} else {
Err(MemoryError::MemoryWrongType {
expected: "uuid",
actual: format!("{value:?}"),
})
}
}
}
3 changes: 2 additions & 1 deletion modeling-cmds/src/kcep_primitive.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use kittycad_execution_plan_traits::{impl_value_on_primitive_ish, MemoryError, NumericPrimitive, Primitive, Value};

use crate::{base64::Base64Data, shared::Angle};
use crate::{base64::Base64Data, id::ModelingCmdId, shared::Angle};

/// Angle is always stored as f64 degrees.
impl From<Angle> for Primitive {
Expand Down Expand Up @@ -40,3 +40,4 @@ impl TryFrom<Primitive> for Base64Data {

impl_value_on_primitive_ish!(Value, Angle);
impl_value_on_primitive_ish!(Value, Base64Data);
impl_value_on_primitive_ish!(Value, ModelingCmdId);
71 changes: 0 additions & 71 deletions modeling-cmds/src/kcep_value.rs

This file was deleted.

1 change: 0 additions & 1 deletion modeling-cmds/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ pub mod id;
pub mod impl_extern_type;
mod impl_traits;
mod kcep_primitive;
mod kcep_value;
/// When a modeling command is successful, these responses could be returned.
pub mod ok_response;
/// Output of each modeling command.
Expand Down
3 changes: 2 additions & 1 deletion modeling-cmds/src/ok_response.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use kittycad_execution_plan_macros::ExecutionPlanValue;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

Expand All @@ -7,7 +8,7 @@ macro_rules! build_enum {
($( $variant:ident ),* ) => {
/// A successful response from a modeling command.
/// This can be one of several types of responses, depending on the command.
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
#[derive(Debug, Serialize, Deserialize, JsonSchema, ExecutionPlanValue)]
#[serde(rename_all = "snake_case", tag = "type", content = "data")]
pub enum OkModelingCmdResponse {
/// An empty response, used for any command that does not explicitly have a response
Expand Down
Loading
Loading