schema: handle required tags.
This commit is contained in:
@@ -49,6 +49,7 @@ type Schema struct {
|
|||||||
|
|
||||||
type KindSchema struct {
|
type KindSchema struct {
|
||||||
Content nextSpec `yaml:"content"`
|
Content nextSpec `yaml:"content"`
|
||||||
|
Required []string `yaml:"required"`
|
||||||
Tags []tagSpec `yaml:"tags"`
|
Tags []tagSpec `yaml:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +71,8 @@ type nextSpec struct {
|
|||||||
|
|
||||||
type Validator struct {
|
type Validator struct {
|
||||||
Schema Schema
|
Schema Schema
|
||||||
FailOnUnknown bool
|
FailOnUnknownKind bool
|
||||||
|
FailOnUnknownType bool
|
||||||
TypeValidators map[string]func(string, *nextSpec) error
|
TypeValidators map[string]func(string, *nextSpec) error
|
||||||
UnknownTypes []string
|
UnknownTypes []string
|
||||||
}
|
}
|
||||||
@@ -220,6 +222,14 @@ func (te TagError) Error() string {
|
|||||||
return fmt.Sprintf("tag[%d][%d]: %s", te.Tag, te.Item, te.Err)
|
return fmt.Sprintf("tag[%d][%d]: %s", te.Tag, te.Item, te.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RequiredTagError struct {
|
||||||
|
Missing []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rte RequiredTagError) Error() string {
|
||||||
|
return fmt.Sprintf("missing tags: %v", rte.Missing)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *Validator) ValidateEvent(evt nostr.Event) error {
|
func (v *Validator) ValidateEvent(evt nostr.Event) error {
|
||||||
if !isTrimmed(evt.Content) {
|
if !isTrimmed(evt.Content) {
|
||||||
return ContentError{ErrDanglingSpace}
|
return ContentError{ErrDanglingSpace}
|
||||||
@@ -231,17 +241,30 @@ func (v *Validator) ValidateEvent(evt nostr.Event) error {
|
|||||||
return ContentError{err}
|
return ContentError{err}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if v.FailOnUnknown {
|
if v.FailOnUnknownType {
|
||||||
return ContentError{ErrUnknownContent}
|
return ContentError{ErrUnknownContent}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var requiredTags []string
|
||||||
|
if len(sch.Required) > 0 {
|
||||||
|
requiredTags = append(requiredTags, sch.Required...)
|
||||||
|
}
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
for ti, tag := range evt.Tags {
|
for ti, tag := range evt.Tags {
|
||||||
if len(tag) == 0 {
|
if len(tag) == 0 {
|
||||||
return ErrEmptyTag
|
return ErrEmptyTag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if requiredTags != nil {
|
||||||
|
// swap-delete this from the list of requirements
|
||||||
|
if idx := slices.Index(requiredTags, tag[0]); idx != -1 {
|
||||||
|
requiredTags[idx] = requiredTags[len(requiredTags)-1]
|
||||||
|
requiredTags = requiredTags[0 : len(requiredTags)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var lastErr error
|
var lastErr error
|
||||||
var tagWasValidated bool
|
var tagWasValidated bool
|
||||||
specs:
|
specs:
|
||||||
@@ -275,9 +298,13 @@ func (v *Validator) ValidateEvent(evt nostr.Event) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(requiredTags) > 0 {
|
||||||
|
return RequiredTagError{requiredTags}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.FailOnUnknown {
|
if v.FailOnUnknownKind {
|
||||||
return ErrUnknownKind
|
return ErrUnknownKind
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +365,7 @@ func (v *Validator) validateNext(tag nostr.Tag, index int, this *nextSpec) (fail
|
|||||||
this.Type, tag[index], tag[0], index, err)
|
this.Type, tag[index], tag[0], index, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if v.FailOnUnknown {
|
if v.FailOnUnknownType {
|
||||||
return index, ErrUnknownTagType
|
return index, ErrUnknownTagType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user