-
Notifications
You must be signed in to change notification settings - Fork 2
constraint.StringCharacters
marrow16 edited this page Jan 21, 2023
·
7 revisions
Check that a string contains only allowable characters (and does not contain any disallowed characters)
Note: By default, this constraint is non-strict - if the value being checked is not a string, this constraint does not fail (unless the Strict field is set)
strchars
| Field | Type | Description |
|---|---|---|
AllowRanges |
[]unicode.RangeTable | the ranges of characters (runes) that are allowed - if this slice is non-empty, each character must be in at least one of these |
NamedAllowRanges |
[]string | the named ranges of characters (runes) that are allowed - if this slice is non-empty, each character must be in at least one of these |
DisallowRanges |
[]unicode.RangeTable | the ranges of characters (runes) that are not allowed - if any character in the string is in any of these ranges then the constraint is violated |
NamedDisallowRanges |
[]string | the named ranges of characters (runes) that are not allowed - if any character is in any of these ranges then the constraint is violated |
Message |
string | the violation message to be used if the constraint fails. If empty, the default message is used |
Stop |
bool | when set to true, Stop prevents further validation checks on the property if this constraint fails |
Strict |
bool | when set to true, fails if the value being checked is not a correct type |
For the NamedAllowRanges and NamedDisallowRanges fields, the range names can be:
-
"BMP","SMP"or"SIP"(Basic Multilingual Plane, Supplementary Multilingual Plane or Supplementary Ideographic Plane respectively) - any name from
unicode.Categoriesprefixed with"Category-" - any name from
unicode.Scriptsprefixed with"Script-" - any name from
unicode.Propertiesprefixed with"Property-" - any name from
unicode.FoldCategoryprefixed with"FoldCategory-" - any name from
unicode.FoldScriptprefixed with"FoldScript-"
Programmatic example...
package main
import (
"fmt"
"unicode"
"github.com/marrow16/valix"
)
func main() {
validator := &valix.Validator{
Properties: valix.Properties{
"foo": {
Type: valix.JsonString,
Constraints: valix.Constraints{
&valix.StringCharacters{
AllowRanges: []unicode.RangeTable{
*unicode.Number,
},
Message: "Must not any other chars but unicode numerics",
},
},
},
},
}
ok, violations, _ := validator.ValidateString(`{"foo": "not valid"}`)
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": "0123456789¹²³¼½¾"}`)
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)
}
}It is possible to initialise range tables within v8n tags...
However, even the simplest form can become very verbose - as the following example demonstrates for just normal numerics and superscript 1-3...
package main
import (
"fmt"
"github.com/marrow16/valix"
)
type MyStruct struct {
Foo string `json:"foo" v8n:"&StringCharacters{AllowRanges:[{\"R16\":[{\"Lo\":48,\"Hi\":57,\"Stride\":1},{\"Lo\":178,\"Hi\":179,\"Stride\":1},{\"Lo\":185,\"Hi\":185,\"Stride\":1}]}], Message:'Must not any other chars but unicode numerics'}"`
}
var validator = valix.MustCompileValidatorFor(MyStruct{}, nil)
func main() {
my := &MyStruct{}
ok, violations, _ := validator.ValidateStringInto(`{"foo": "not valid"}`, 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": "0123456789¹²³"}`, 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)
}
}Therefore, it's recommended to register specific unicode allowed characters as new constraints - then use those constraints in v8n tags...
package main
import (
"fmt"
"github.com/marrow16/valix"
"unicode"
)
type MyStruct struct {
Foo string `json:"foo" v8n:"&unicodeNumerics{Message:'Overridden default message'}"`
}
var validator *valix.Validator
func init() {
valix.RegisterNamedConstraint("unicodeNumerics", &valix.StringCharacters{
AllowRanges: []unicode.RangeTable{
{
R16: []unicode.Range16{
{0x0030, 0x0039, 1},
{0x00b2, 0x00b3, 1},
{0x00b9, 0x00b9, 1},
},
},
},
Message: "Characters must be digits or superscript digits",
})
validator = valix.MustCompileValidatorFor(MyStruct{}, nil)
}
func main() {
my := &MyStruct{}
ok, violations, _ := validator.ValidateStringInto(`{"foo": "not valid"}`, 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": "0123456789¹²³"}`, 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)
}
}