Validate takes in a reference to a data struct (pointer, map of, slice of)
and validates each of its fields against their dv8 field tags.
It recurses into nested structs.
A nil ctx is tolerated and replaced with context.Background.
Validator implements a single method that returns an error if a struct is invalid.
DV8 calls this method during validation on any type in the object graph that implements it.