Skip to content

Commit

Permalink
Impl execution_plan::Value for many modeling command types
Browse files Browse the repository at this point in the history
Finally, the macro is advanced enough to derive Value for the huge `OkModelingCmdResponse` enum! The only missing piece was that Vec<T: Value> didn't impl Value, but I've added that now.
  • Loading branch information
adamchalmers committed Dec 21, 2023
1 parent e8d8787 commit 8045e19
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 110 deletions.
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);
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

0 comments on commit 8045e19

Please sign in to comment.