Support for Mutually Exclusive Keys in Hashes
I'd like to be able to define keys within a hash that are mutually exclusive (i.e., only one of them should exist).
# Good
{
"foo": "bar"
}
# Good
{
"fu": "ba"
}
# Bad
{
"foo": "bar",
"fu": "ba"
}
Maybe it could look like something like:
RSchema.define({
exclusive("foo", :with => "fu") => type(_String),
exclusive("fu", :with => "foo") => type(_String)
})
There are a couple of ways to do this currently (in RSchema v3).
If those are the only keys in the hash, you can just use either:
RSchema.define do
either(Hash('foo' => _String), Hash('fu' => _String))
end
If there are other keys in the hash, you can use two separate schemas:
BAZ_FU = RSchema.define_hash {{
'other_key' => _Integer,
'fu' => _String,
}}
BAZ_FOO = RSchema.define do
# this is new, currently undocumented syntax that might change
Hash_based_on(BAZ_FU, {
'fu' => nil, # removes 'fu' element
'foo' => _String, #adds new 'foo' element
})
end
BAZ = RSchema.define { either(BAZ_FU, BAZ_FOO) }
Trying to building this into the hash schema raises a few questions. What if there are 3 exclusive keys instead of 2? What if a hash should have either the single key "name", or both of the keys "first_name" and "last_name"? I'd like to come up with a design that addresses these questions. I'll need some time to think about it.