Skip to content

constraint.SetConditionOnType

marrow16 edited this page Jan 21, 2023 · 4 revisions

Prev Home Next

Constraint: SetConditionOnType

Description

Is a utility constraint that can be used to set a condition in the ValidatorContext indicating the type of the property value to which this constraint is added.

The condition token set will be at least one of the following:

  • "type_null"
  • "type_object"
  • "type_array"
  • "type_boolean"
  • "type_string"
  • "type_integer"
  • "type_number"
  • "type_unknown"

Note that an int value will set both "type_number" and "type_integer" (because an int is both)

On detecting a value represented by a json.Number - the "type_number" will always be set. And this may also be complimented by the "type_integer" (if the json.Number holds an int value). Also, with json.Number values, the following condition tokens may be set

  • "type_invalid_number"
  • "type_nan"
  • "type_inf"

("type_invalid_number" indicating that the json.Number could not be parsed to either int or float)

When handling json.Number values, this constraint can be used in conjunction with a following FailWhen constraint to enforce failures in case of Inf, Nan or unparseable

V8n Tag Abbreviation

ctype

Fields

none

Examples

Programmatic example...
package main

import (
    "fmt"

    "github.com/marrow16/valix"
)

func main() {
    validator := &valix.Validator{
        UseNumber: true,
        Properties: valix.Properties{
            "foo": {
                Type: valix.JsonAny,
                Constraints: valix.Constraints{
                    &valix.SetConditionOnType{},
                    &valix.ConditionalConstraint{
                        When:       valix.Conditions{"type_string"},
                        Constraint: &valix.StringPresetPattern{Preset: "numeric+e"},
                    },
                    &valix.ConditionalConstraint{
                        When: valix.Conditions{"type_integer"},
                        Constraint: &valix.RangeInt{
                            Minimum: 0,
                            Maximum: 9,
                        },
                    },
                    &valix.ConditionalConstraint{
                        When: valix.Conditions{"type_number", "!type_integer"},
                        Constraint: &valix.Range{
                            Minimum:      0,
                            Maximum:      1,
                            ExclusiveMax: true,
                        },
                    },
                },
            },
        },
    }

    ok, violations, _ := validator.ValidateString(`{"foo": "not a number"}`)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateString(`{"foo": 10}`)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateString(`{"foo": 1.1}`)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateString(`{"foo": "1.2E34"}`)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateString(`{"foo": 9}`)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateString(`{"foo": 0.999}`)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }
}

try on go-playground

Struct v8n tag example...
package main

import (
    "fmt"

    "github.com/marrow16/valix"
)

type MyStruct struct {
    Foo interface{} `json:"foo" v8n:"&ctype, &[type_string]strpreset{'numeric+e'}, &[type_integer]rangei{min:0, max:9}, &[type_number,!type_integer]range{min:0, max:1, excMax}"`
}

var validator = valix.MustCompileValidatorFor(MyStruct{}, &valix.ValidatorForOptions{UseNumber: true})

func main() {
    my := &MyStruct{}

    ok, violations, _ := validator.ValidateStringInto(`{"foo": "not a number"}`, my)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateStringInto(`{"foo": 10}`, my)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateStringInto(`{"foo": 1.1}`, my)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateStringInto(`{"foo": "1.2E34"}`, my)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateStringInto(`{"foo": 9}`, my)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }

    ok, violations, _ = validator.ValidateStringInto(`{"foo": 0.999}`, my)
    fmt.Printf("Passed? %v\n", ok)
    for i, v := range violations {
        fmt.Printf("Violation[%d] Message: %s, Property: %s, Path: %s\n", i+1, v.Message, v.Property, v.Path)
    }
}

try on go-playground

Clone this wiki locally