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:
MemberShape
and all the model shapes share a commonShape
base class.- The
ShapeType
andNodeType
enumerations allow for type determination between shapes and nodes at runtime. - The use of Java’s
Number
class 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:
Node
has been renamed asValue
, a more approachable and less generic term.TopLevelShape
has 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
, andValue
allow for run-time type determination without explicit “Type” values. - The
Service::rename
andResource::identifiers
values map betweenShapeID
andIdentifier
rather than theShapeID
andString
used in Java. - Nullable values translate to Rust
Option
type. - Java
List
containers translate to RustVec
containers. - Java
Set
containers translate to RustHashSet
containers. - Java
Map
containers translate to RustHashMap
containers.
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
, andTransformer
traits 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
ModelReader
andModelWriter
traits for implementing serialization of different representations. - model; just the types necessary to hold the in-memory semantic model.
Additionally, the following crates externalize operations.