5
5
//! - This canonical ordering is the order of the struct's fields in its Rust source code definition.
6
6
//! - Enums get laid out by first putting the variant as a string, then putting the variant's fields.
7
7
use kittycad_modeling_cmds:: {
8
+ base64:: Base64Data ,
8
9
ok_response:: OkModelingCmdResponse ,
9
10
output,
10
- shared:: { Angle , PathSegment , Point2d , Point3d } ,
11
+ shared:: { Angle , PathSegment , Point2d , Point3d , Point4d } ,
11
12
} ;
13
+ use uuid:: Uuid ;
12
14
13
15
use super :: Value ;
14
16
use crate :: { ExecutionError , Primitive } ;
@@ -25,45 +27,98 @@ fn err() -> ExecutionError {
25
27
ExecutionError :: MemoryWrongSize
26
28
}
27
29
30
+ /// Macro to generate an `impl Value` for the given type `$subject`.
31
+ /// The type `$subject` must be "primitive-ish",
32
+ /// i.e. something that can be converted Into a Primitive and TryFrom a primitive
33
+ macro_rules! impl_value_on_primitive_ish {
34
+ ( $subject: ident) => {
35
+ impl Value for $subject {
36
+ fn into_parts( self ) -> Vec <Primitive > {
37
+ vec![ self . into( ) ]
38
+ }
39
+
40
+ fn from_parts<I >( values: & mut I ) -> Result <Self , ExecutionError >
41
+ where
42
+ I : Iterator <Item = Option <Primitive >>,
43
+ {
44
+ values. next( ) . ok_or( err( ) ) ?. to_owned( ) . ok_or( err( ) ) ?. try_into( )
45
+ }
46
+ }
47
+ } ;
48
+ }
49
+
50
+ impl_value_on_primitive_ish ! ( f32 ) ;
51
+ impl_value_on_primitive_ish ! ( f64 ) ;
52
+ impl_value_on_primitive_ish ! ( bool ) ;
53
+ impl_value_on_primitive_ish ! ( String ) ;
54
+ impl_value_on_primitive_ish ! ( Uuid ) ;
55
+ type VecU8 = Vec < u8 > ;
56
+ impl_value_on_primitive_ish ! ( VecU8 ) ;
57
+ impl_value_on_primitive_ish ! ( Angle ) ;
58
+ impl_value_on_primitive_ish ! ( usize ) ;
59
+ impl_value_on_primitive_ish ! ( Base64Data ) ;
60
+
61
+ /// Macro to generate the methods of trait `Value` for the given fields.
62
+ /// Args:
63
+ /// `$field`: Repeated 0 or more times. Listing of each field in the struct.
64
+ /// The order in which these fields are given determines the order that fields are
65
+ /// written to and read from memory.
66
+ macro_rules! impl_value_on_struct_fields {
67
+ ( $( $field: ident) ,* ) => {
68
+ fn into_parts( self ) -> Vec <Primitive > {
69
+ let mut parts = Vec :: new( ) ;
70
+ $(
71
+ parts. extend( self . $field. into_parts( ) ) ;
72
+ ) *
73
+ parts
74
+ }
75
+
76
+ fn from_parts<I >( values: & mut I ) -> Result <Self , ExecutionError >
77
+ where
78
+ I : Iterator <Item = Option <Primitive >>,
79
+ {
80
+ $(
81
+ let $field = Value :: from_parts( values) ?;
82
+ ) *
83
+ Ok ( Self {
84
+ $(
85
+ $field,
86
+ ) *
87
+ } )
88
+ }
89
+ } ;
90
+ }
91
+
28
92
impl < T > Value for Point2d < T >
29
93
where
30
94
Primitive : From < T > ,
31
- T : TryFrom < Primitive , Error = ExecutionError > ,
95
+ T : Value ,
32
96
{
33
- fn into_parts ( self ) -> Vec < Primitive > {
34
- let points = [ self . x , self . y ] ;
35
- points. into_iter ( ) . map ( |component| component. into ( ) ) . collect ( )
36
- }
37
-
38
- fn from_parts < I > ( values : & mut I ) -> Result < Self , ExecutionError >
39
- where
40
- I : Iterator < Item = Option < Primitive > > ,
41
- {
42
- let x = values. next ( ) . ok_or ( err ( ) ) ?. to_owned ( ) . ok_or ( err ( ) ) ?. try_into ( ) ?;
43
- let y = values. next ( ) . ok_or ( err ( ) ) ?. to_owned ( ) . ok_or ( err ( ) ) ?. try_into ( ) ?;
44
- Ok ( Self { x, y } )
45
- }
97
+ impl_value_on_struct_fields ! ( x, y) ;
46
98
}
47
99
48
100
impl < T > Value for Point3d < T >
49
101
where
50
102
Primitive : From < T > ,
51
- T : TryFrom < Primitive , Error = ExecutionError > ,
103
+ T : Value ,
52
104
{
53
- fn into_parts ( self ) -> Vec < Primitive > {
54
- let points = [ self . x , self . y , self . z ] ;
55
- points. into_iter ( ) . map ( |component| component. into ( ) ) . collect ( )
56
- }
105
+ impl_value_on_struct_fields ! ( x, y, z) ;
106
+ }
57
107
58
- fn from_parts < I > ( values : & mut I ) -> Result < Self , ExecutionError >
59
- where
60
- I : Iterator < Item = Option < Primitive > > ,
61
- {
62
- let x = values. next ( ) . ok_or ( err ( ) ) ?. to_owned ( ) . ok_or ( err ( ) ) ?. try_into ( ) ?;
63
- let y = values. next ( ) . ok_or ( err ( ) ) ?. to_owned ( ) . ok_or ( err ( ) ) ?. try_into ( ) ?;
64
- let z = values. next ( ) . ok_or ( err ( ) ) ?. to_owned ( ) . ok_or ( err ( ) ) ?. try_into ( ) ?;
65
- Ok ( Self { x, y, z } )
66
- }
108
+ impl < T > Value for Point4d < T >
109
+ where
110
+ Primitive : From < T > ,
111
+ T : Value ,
112
+ {
113
+ impl_value_on_struct_fields ! ( x, y, z, w) ;
114
+ }
115
+
116
+ impl Value for kittycad_modeling_cmds:: shared:: Color {
117
+ impl_value_on_struct_fields ! ( r, g, b, a) ;
118
+ }
119
+
120
+ impl Value for kittycad_modeling_cmds:: shared:: ExportFile {
121
+ impl_value_on_struct_fields ! ( name, contents) ;
67
122
}
68
123
69
124
/// Layout:
0 commit comments