validations.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package spec
  2. // CommonValidations describe common JSON-schema validations
  3. type CommonValidations struct {
  4. Maximum *float64 `json:"maximum,omitempty"`
  5. ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
  6. Minimum *float64 `json:"minimum,omitempty"`
  7. ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
  8. MaxLength *int64 `json:"maxLength,omitempty"`
  9. MinLength *int64 `json:"minLength,omitempty"`
  10. Pattern string `json:"pattern,omitempty"`
  11. MaxItems *int64 `json:"maxItems,omitempty"`
  12. MinItems *int64 `json:"minItems,omitempty"`
  13. UniqueItems bool `json:"uniqueItems,omitempty"`
  14. MultipleOf *float64 `json:"multipleOf,omitempty"`
  15. Enum []interface{} `json:"enum,omitempty"`
  16. }
  17. // SetValidations defines all validations for a simple schema.
  18. //
  19. // NOTE: the input is the larger set of validations available for schemas.
  20. // For simple schemas, MinProperties and MaxProperties are ignored.
  21. func (v *CommonValidations) SetValidations(val SchemaValidations) {
  22. v.Maximum = val.Maximum
  23. v.ExclusiveMaximum = val.ExclusiveMaximum
  24. v.Minimum = val.Minimum
  25. v.ExclusiveMinimum = val.ExclusiveMinimum
  26. v.MaxLength = val.MaxLength
  27. v.MinLength = val.MinLength
  28. v.Pattern = val.Pattern
  29. v.MaxItems = val.MaxItems
  30. v.MinItems = val.MinItems
  31. v.UniqueItems = val.UniqueItems
  32. v.MultipleOf = val.MultipleOf
  33. v.Enum = val.Enum
  34. }
  35. type clearedValidation struct {
  36. Validation string
  37. Value interface{}
  38. }
  39. type clearedValidations []clearedValidation
  40. func (c clearedValidations) apply(cbs []func(string, interface{})) {
  41. for _, cb := range cbs {
  42. for _, cleared := range c {
  43. cb(cleared.Validation, cleared.Value)
  44. }
  45. }
  46. }
  47. // ClearNumberValidations clears all number validations.
  48. //
  49. // Some callbacks may be set by the caller to capture changed values.
  50. func (v *CommonValidations) ClearNumberValidations(cbs ...func(string, interface{})) {
  51. done := make(clearedValidations, 0, 5)
  52. defer func() {
  53. done.apply(cbs)
  54. }()
  55. if v.Minimum != nil {
  56. done = append(done, clearedValidation{Validation: "minimum", Value: v.Minimum})
  57. v.Minimum = nil
  58. }
  59. if v.Maximum != nil {
  60. done = append(done, clearedValidation{Validation: "maximum", Value: v.Maximum})
  61. v.Maximum = nil
  62. }
  63. if v.ExclusiveMaximum {
  64. done = append(done, clearedValidation{Validation: "exclusiveMaximum", Value: v.ExclusiveMaximum})
  65. v.ExclusiveMaximum = false
  66. }
  67. if v.ExclusiveMinimum {
  68. done = append(done, clearedValidation{Validation: "exclusiveMinimum", Value: v.ExclusiveMinimum})
  69. v.ExclusiveMinimum = false
  70. }
  71. if v.MultipleOf != nil {
  72. done = append(done, clearedValidation{Validation: "multipleOf", Value: v.MultipleOf})
  73. v.MultipleOf = nil
  74. }
  75. }
  76. // ClearStringValidations clears all string validations.
  77. //
  78. // Some callbacks may be set by the caller to capture changed values.
  79. func (v *CommonValidations) ClearStringValidations(cbs ...func(string, interface{})) {
  80. done := make(clearedValidations, 0, 3)
  81. defer func() {
  82. done.apply(cbs)
  83. }()
  84. if v.Pattern != "" {
  85. done = append(done, clearedValidation{Validation: "pattern", Value: v.Pattern})
  86. v.Pattern = ""
  87. }
  88. if v.MinLength != nil {
  89. done = append(done, clearedValidation{Validation: "minLength", Value: v.MinLength})
  90. v.MinLength = nil
  91. }
  92. if v.MaxLength != nil {
  93. done = append(done, clearedValidation{Validation: "maxLength", Value: v.MaxLength})
  94. v.MaxLength = nil
  95. }
  96. }
  97. // ClearArrayValidations clears all array validations.
  98. //
  99. // Some callbacks may be set by the caller to capture changed values.
  100. func (v *CommonValidations) ClearArrayValidations(cbs ...func(string, interface{})) {
  101. done := make(clearedValidations, 0, 3)
  102. defer func() {
  103. done.apply(cbs)
  104. }()
  105. if v.MaxItems != nil {
  106. done = append(done, clearedValidation{Validation: "maxItems", Value: v.MaxItems})
  107. v.MaxItems = nil
  108. }
  109. if v.MinItems != nil {
  110. done = append(done, clearedValidation{Validation: "minItems", Value: v.MinItems})
  111. v.MinItems = nil
  112. }
  113. if v.UniqueItems {
  114. done = append(done, clearedValidation{Validation: "uniqueItems", Value: v.UniqueItems})
  115. v.UniqueItems = false
  116. }
  117. }
  118. // Validations returns a clone of the validations for a simple schema.
  119. //
  120. // NOTE: in the context of simple schema objects, MinProperties, MaxProperties
  121. // and PatternProperties remain unset.
  122. func (v CommonValidations) Validations() SchemaValidations {
  123. return SchemaValidations{
  124. CommonValidations: v,
  125. }
  126. }
  127. // HasNumberValidations indicates if the validations are for numbers or integers
  128. func (v CommonValidations) HasNumberValidations() bool {
  129. return v.Maximum != nil || v.Minimum != nil || v.MultipleOf != nil
  130. }
  131. // HasStringValidations indicates if the validations are for strings
  132. func (v CommonValidations) HasStringValidations() bool {
  133. return v.MaxLength != nil || v.MinLength != nil || v.Pattern != ""
  134. }
  135. // HasArrayValidations indicates if the validations are for arrays
  136. func (v CommonValidations) HasArrayValidations() bool {
  137. return v.MaxItems != nil || v.MinItems != nil || v.UniqueItems
  138. }
  139. // HasEnum indicates if the validation includes some enum constraint
  140. func (v CommonValidations) HasEnum() bool {
  141. return len(v.Enum) > 0
  142. }
  143. // SchemaValidations describes the validation properties of a schema
  144. //
  145. // NOTE: at this moment, this is not embedded in SchemaProps because this would induce a breaking change
  146. // in the exported members: all initializers using litterals would fail.
  147. type SchemaValidations struct {
  148. CommonValidations
  149. PatternProperties SchemaProperties `json:"patternProperties,omitempty"`
  150. MaxProperties *int64 `json:"maxProperties,omitempty"`
  151. MinProperties *int64 `json:"minProperties,omitempty"`
  152. }
  153. // HasObjectValidations indicates if the validations are for objects
  154. func (v SchemaValidations) HasObjectValidations() bool {
  155. return v.MaxProperties != nil || v.MinProperties != nil || v.PatternProperties != nil
  156. }
  157. // SetValidations for schema validations
  158. func (v *SchemaValidations) SetValidations(val SchemaValidations) {
  159. v.CommonValidations.SetValidations(val)
  160. v.PatternProperties = val.PatternProperties
  161. v.MaxProperties = val.MaxProperties
  162. v.MinProperties = val.MinProperties
  163. }
  164. // Validations for a schema
  165. func (v SchemaValidations) Validations() SchemaValidations {
  166. val := v.CommonValidations.Validations()
  167. val.PatternProperties = v.PatternProperties
  168. val.MinProperties = v.MinProperties
  169. val.MaxProperties = v.MaxProperties
  170. return val
  171. }
  172. // ClearObjectValidations returns a clone of the validations with all object validations cleared.
  173. //
  174. // Some callbacks may be set by the caller to capture changed values.
  175. func (v *SchemaValidations) ClearObjectValidations(cbs ...func(string, interface{})) {
  176. done := make(clearedValidations, 0, 3)
  177. defer func() {
  178. done.apply(cbs)
  179. }()
  180. if v.MaxProperties != nil {
  181. done = append(done, clearedValidation{Validation: "maxProperties", Value: v.MaxProperties})
  182. v.MaxProperties = nil
  183. }
  184. if v.MinProperties != nil {
  185. done = append(done, clearedValidation{Validation: "minProperties", Value: v.MinProperties})
  186. v.MinProperties = nil
  187. }
  188. if v.PatternProperties != nil {
  189. done = append(done, clearedValidation{Validation: "patternProperties", Value: v.PatternProperties})
  190. v.PatternProperties = nil
  191. }
  192. }