Consider following schema:
ENTITY a;
x: REAL;
END_ENTITY;
ENTITY by SUBTYPE_OF a;
y: REAL;
END_ENTITY;
ENTITY bz SUBTYPE_OF a;
z: REAL;
END_ENTITY;
STEP exchange format allows complex entity like
#1 = (A(1.0), BY(2.0), BZ(3.0));
This #1 should be regarded as { a: { x: 1.0, y: 2.0, z: 3.0} } (in JSON format).
We may have two way to implement this:
Define a "composed" type instead of "any" type
struct ByExtension {
y: f64,
}
struct BzExtension {
z: f64,
}
struct AComposed {
x: f64,
by_extension: Option<Box<ByExtension>>,
bz_extension: Option<Box<BzExtension>>,
}
Option<Box<Extension>> is used because it increases the size_of::<AComposed>(), although this hurts memory locality. In this case x and y will be placed in different memory pages, and it may cause performance issue.
Generate concrete types for every combination and add them to "any" type
To keep every components continuous in memory, we can define every possible struct:
struct ByBz {
x: f64,
y: f64,
z: f64,
}
enum AAny {
A(Box<A>),
By(Box<By>),
Bz(Box<Bz>),
ByBz(Box<ByBz>),
}
This is better in terms of memory, but the compile of generated Rust code becomes slower and slower.
Consider following schema:
STEP exchange format allows complex entity like
This
#1should be regarded as{ a: { x: 1.0, y: 2.0, z: 3.0} }(in JSON format).We may have two way to implement this:
Define a "composed" type instead of "any" type
Option<Box<Extension>>is used because it increases thesize_of::<AComposed>(), although this hurts memory locality. In this casexandywill be placed in different memory pages, and it may cause performance issue.Generate concrete types for every combination and add them to "any" type
To keep every components continuous in memory, we can define every possible struct:
This is better in terms of memory, but the compile of generated Rust code becomes slower and slower.