Closed popematt closed 1 year ago
The field_names
constraint defines the type and/or constraints for all field names within a struct. Field names are symbols and will be represented as symbol values for the purpose of validation.
<FIELD_NAMES> ::= field_names: distinct::<TYPE_REFERENCE>
| field_names: <TYPE_REFERENCE>
struct
is invalidnull.struct
is invalidlist
of symbol
. That list is validated as if field_names
was an element
constraint on the container of field names.This assumes that the distinct::
modifier has been implemented as in #43.
This is an example of one way of implementing the constraint to serve as a reference for the correct behavior. There is no requirement that it must be implemented this way.
private fun test(value: IonValue, typeRef: Type): Boolean {
if (value !is IonStruct || value.isNullValue) return false
val nameList = value.mapTo(ionSystem.newEmptyList()) { ionSystem.newSymbol(it.fieldName) }
return ElementConstraint.test(nameList, typeRef)
}
Resolved by #76
Problem
Right now, the only way to prescribe certain field names is to specify them in the
fields
constraint. However, there is no way to generally constrain field names (for example, require that all field names must be lower case) without listing each possible field name.Possible Solutions
Here are some possible solutions. (These are just suggestions, and not intended to limit the possible solutions.)
Solution 1 –
field_names
constraint for validating the field names in structsThe
field_names
constraint would be roughly analogous to theelement
constraint, but instead of constraining the field values of a struct, it would constrain the field names of a struct. Field names are not true Ion values, but they are similar to symbols, and could be validated as such. The implicit schema for field names is:The
field_names
constraint could accept aTYPE_REFERENCE
, and all field names would be validated against that type, as if the field name was an Ion Symbol value (rather than just being a symbol token). For example:The
field_names
constraint could also allow adistinct::
annotation, which would indicate that there should be no duplicate field names in the struct. This proposed solution would also be a way to solve https://github.com/amzn/ion-schema/issues/14. For example:Example grammar:
Solution 2 –
field_names
regex-based constraint validating the field names in structsThis is like the
regex
constraint, except that it validates the field names of a struct, and it has an additionaldistinct::
annotation, which would indicate that there should be no duplicate field names in the struct (to solve https://github.com/amzn/ion-schema/issues/14).Here is an example:
While this is simpler to implement than Solution 1, it has the disadvantage of not allowing code re-use (e.g.
field_names: distinct::uuid_string
vs. having to copy/paste the regex for a UUID string), and it doesn't provide as much functionality as Solution 1 because there is no equivalent tofield_names: { utf8_byte_length: range::[1, 16] }
.Solution 3 – Update
fields
constraint to operate on a bag of tuplesUpdate
fields
to allow a list of rules defining what is a valid name/value pair in a struct. Eg.An interesting capability is that it allows us to specify that certain types of fields should have certain types of field names, and vice versa For example, this is how one could constraint fields with a name starting with
f_
to be floats andi_
to be ints. (And in this example, it works both ways, all ints must have a field name starting withi_
.)