Reputation: 6121
With some help, I've been able to create this code which tries to describe a range of numbers:
#[derive(Debug, Default)]
struct Inclusive;
#[derive(Debug, Default)]
struct Exclusive;
#[derive(Deserialize)]
struct Range<S, E, V: Ord>(
Option<V>,
Option<V>,
#[serde(skip)] S,
#[serde(skip)] E,
);
fn main () {
let data = "[[1, null]]";
let rs: Vec<Range<Inclusive, Exclusive, i32>> = serde_json::from_str(data)
.expect("Error");
println!("Range from {:?} to {:?}", rs[0].0, rs[0].1);
}
Is it possible to describe via types that Range
should have at least one bound so that [null, null]
would throw a deserialization error at runtime?
Upvotes: 1
Views: 74
Reputation: 58735
It's better to model the problem to capture the invariants statically, rather than relying on runtime checks. Matthieu's suggestion of using an enum
might look like this:
enum RangeBound<V> {
Between(V, V),
LowerBounded(V),
UpperBounded(V),
}
struct Range<S, E, V: Ord>(
RangeBound<V>,
#[serde(skip)] S,
#[serde(skip)] E,
);
It is not possible to create a RangeBound
without at least one value.
This approach will probably require a custom Deserialize
implementation though.
Upvotes: 2