null means for it. There are three answers:
required
null is a violation. Otherwise its block runs on the value.ifPresent
null is valid. A value is checked by its block.forbidden
Anything but
null is a violation.required or ifPresent, the value inside the block has the non-null type: String, not String?. Every
constraint works on that type, so your IDE offers only the constraints that fit it, and none of them has to think about
null.
Client.kt
And a person who sends a company name breaks
forbidden:
required
::email required { email() } reports is required, with the code required, when the property is null, and the
block does not run, so there is never a second violation about a missing value. When the value is there, the block runs
on it.
To change the message of one property, call it as a function, with the message first:
messages.required.
A block can be empty:
::street required {} only checks that the street is there.ifPresent
::nickname ifPresent { minLength(3) } accepts null, and checks the value when there is one. Use it for optional
fields that still have a shape when they are filled in.
forbidden
::companyName.forbidden() reports must be null, with the code forbidden, when the property has a value. It is
usually inside a condition, for a field that one kind of object must not have:
::password.forbidden("a guest has no password").
Values that are not properties
required and ifPresent also take a path and a value, for something that is not a property, such as a value computed
from others or read from a map:
notNull, for elements
Inside an each over a collection of nullable values, the element can still be null, and there is no property to
call required on. notNull() checks it, with the message of required (is required) and the code notNull: