Java & Rust Implementation Differences
The following, for reference, is a combined view of the semantic model from the Smithy Overview. Clearly this view is language-neutral and is unlikely to produce an idiomatic interface if implemented as-is.
The Java Model
The Java model includes a number of additional abstract classes to take advantage of implementation inheritance provided by the Java object model.
Points of interest:
MemberShapeand all the model shapes share a commonShapebase class.- The
ShapeTypeandNodeTypeenumerations allow for type determination between shapes and nodes at runtime. - The use of Java’s
Numberclass allows for a wide range of concrete numeric types.
The Rust model
The corresponding Rust model on the other hand makes little use of inheritance, except for a few traits, but makes use of enumerations instead.
Points of interest:
Nodehas been renamed asValue, a more approachable and less generic term.TopLevelShapehas been introduced as the container type for all non-member shape types.- Neither
TopLevelShape, orMemberShape, share a common parent type but do implement the common traitsHasIdentity,HasTraits, andNonTraitEq. - The use of Rust enumerations for
ShapeKind,Simple, andValueallow for run-time type determination without explicit “Type” values. - The
Service::renameandResource::identifiersvalues map betweenShapeIDandIdentifierrather than theShapeIDandStringused in Java. - Nullable values translate to Rust
Optiontype. - Java
Listcontainers translate to RustVeccontainers. - Java
Setcontainers translate to RustHashSetcontainers. - Java
Mapcontainers translate to RustHashMapcontainers.
Traits
The Java implementation uses Java service discovery to describe traits as Java classes and apply them to models. There isn’t a direct comparison in Rust to the Java service framework and so traits have to be dealt with in a more static manner (details TBD).
Model Operations
The Java implementation incorporates a number of operations, such as builders, serialization and validation, into the core model which is common for Java. Rust on the other hand tends toward smaller units of packaging and therefore more decoupling of these operations from the model itself.
The core crate provides the following modules which are further extended in separate crates.
- action; the
Action,Linter,Validator, andTransformertraits used to perform the corresponding operations on models. The module also provides some basic lint, transform, and validate implementations. - builder; a set of builder types providing a more fluent style for model construction.
- io; the
ModelReaderandModelWritertraits for implementing serialization of different representations. - model; just the types necessary to hold the in-memory semantic model.
Additionally, the following crates externalize operations.