pub enum ShapeCase {
Bool(Option<bool>),
String(Option<String>),
Int(Option<i64>),
Float,
Null,
Array {
prefix: Vec<Shape>,
tail: Shape,
},
Object {
fields: IndexMap<String, Shape>,
rest: Shape,
},
One(IndexSet<Shape>),
All(IndexSet<Shape>),
Name(String, Vec<NamedShapePathKey>),
None,
Error {
message: String,
range: OffsetRange,
partial: Option<Shape>,
},
}
Expand description
The ShapeCase
enum attempts to capture all the common shapes of JSON
values, not just the JSON types themselves, but also patterns of usage (such
as using JSON arrays as either static tuples or dynamic lists).
A ShapeCase
enum variant like ShapeCase::One
may temporarily
represent a structure that has not been fully simplified, but simplication
is required to turn the ShapeCase
into a Shape
, using the
ShapeCase::simplify(&self) -> Shape
method.
Variants§
Bool(Option<bool>)
The Bool
, String
, and Int
variants can either represent a general
shape using None
for the Option
, or a specific shape using Some
.
For example, ShapeCase::Bool(None)
is a shape satisfied by either true
or false, like the Rust bool type, while ShapeCase::Bool(Some(true))
is a shape satisfied only by true
(and likewise for false
).
String(Option<String>)
Similar to ShapeCase::Bool
, ShapeCase::String
represents a shape
matching either any string (in the None
case) or some specific string
(in the Some
case).
Int(Option<i64>)
Similar to ShapeCase::Bool
and ShapeCase::String
,
ShapeCase::Int
can represent either any integer or some specific
integer.
Float
ShapeCase::Float
is a shape that captures the set of all floating
point numbers. We do not allow singleton floating point value shapes,
since floating point equality is unreliable.
Null
ShapeCase::Null
is a singleton shape whose only possible value is
null
. Note that ShapeCase::Null
is different from
ShapeCase::None
, which represents the absence of a value.
Array
ShapeCase::Array
represents a prefix
of statically known shapes
(like a tuple type), followed by an optional tail
shape for all other
(dynamic) elements. When only the prefix
elements are defined, the
tail
shape is ShapeCase::None
. ShapeCase::Array(vec![], ShapeCase::None)
is the shape of an empty array.
Object
ShapeCase::Object
is a map of statically known field names to field
shapes, together with an optional type for all other string keys. When
dynamic string indexing is disabled, the rest shape will be
ShapeCase::None
. Note that accessing the dynamic map always returns
ShapeCase::One([rest_shape, ShapeCase::None])
, to reflect the
uncertainty of the shape of dynamic keys not present in the static
fields.
One(IndexSet<Shape>)
A union of shapes, satisfied by values that satisfy any of the shapes in the set.
All(IndexSet<Shape>)
An intersection of shapes, satisfied by values that satisfy all of the
shapes in the set. When applied to multiple ShapeCase::Object
shapes, ShapeCase::All
represents merging the fields of the objects,
as reflected by the simplification logic.
Name(String, Vec<NamedShapePathKey>)
ShapeCase::Name
refers to a shape declared with the given name,
possibly in the future. When shape processing needs to refer to the
shape of some subproperty of a named shape, it uses the
Vec<NamedShapePathKey>
subpath to represent the nested shape. When the
named shape is eventually declared, the subpath can be used to resolve
the actual shape of the nested property path.
As of now, the name String
is expected to be either an identifier or a
variable name like $root
or $this
or $args
, allowing
ShapeCase::Name
to represent types of subproperties of variables as
well as named types from some schema.
None
Represents the absence of a value, or the shape of a property not
present in an object. Used by the rest parameters of both
ShapeCase::Array
and ShapeCase::Object
to indicate no additional
dynamic elements are allowed, and with ShapeCase::One
to represent
optionality of values, e.g. One<Bool, None>
.
Error
Represents a local failure of shape processing.
Implementations§
Source§impl ShapeCase
impl ShapeCase
pub fn is_none(&self) -> bool
pub fn is_null(&self) -> bool
pub fn error(message: &str) -> Self
pub fn error_with_range(message: &str, range: OffsetRange) -> Self
pub fn error_with_partial(message: &str, partial: Shape) -> Self
pub fn error_with_range_and_partial( message: &str, range: OffsetRange, partial: Shape, ) -> Self
Source§impl ShapeCase
impl ShapeCase
pub fn from_json(json: &JSON) -> Self
pub fn from_json_bytes(json: &JSONBytes) -> Self
Source§impl ShapeCase
impl ShapeCase
Sourcepub fn simplify(self) -> Shape
pub fn simplify(self) -> Shape
Returns a Shape
wrapper around a simplified ShapeCase
. This
function is a primary bottleneck for constructing a Shape
, and helps
guarantee all Shape
values have been reliably simplified and hashed.
Note that this method takes ownership of self in order to efficiently return case unmodified in already-simplified cases.
Trait Implementations§
Source§impl Hash for ShapeCase
Because ShapeCase uses IndexMap and IndexSet for its Object, One, and All
variants, the default derived Hash trait implementation does not work.
Instead, we hash those cases manually, using a commutative operation to
combine the order-insensitive hashes of the elements.
impl Hash for ShapeCase
Because ShapeCase uses IndexMap and IndexSet for its Object, One, and All variants, the default derived Hash trait implementation does not work. Instead, we hash those cases manually, using a commutative operation to combine the order-insensitive hashes of the elements.
impl Eq for ShapeCase
impl StructuralPartialEq for ShapeCase
Auto Trait Implementations§
impl Freeze for ShapeCase
impl RefUnwindSafe for ShapeCase
impl Send for ShapeCase
impl Sync for ShapeCase
impl Unpin for ShapeCase
impl UnwindSafe for ShapeCase
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.