123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- package yaml_checker
- import (
- "github.com/pkg/errors"
- "gopkg.in/yaml.v3"
- "os"
- )
- const (
- schemaNodeTypeObject = "object"
- schemaNodeTypeField = "field"
- )
- type SchemaDoc struct {
- rootSchemas []SchemaNode
- }
- type SchemaDocYaml struct {
- RootSchemas []SchemaYaml `yaml:"schema"`
- }
- type SchemaYaml struct {
- Type string `yaml:"type"`
- Name string `yaml:"name"`
- Describe string `yaml:"describe"`
- Required bool `yaml:"required"`
- AsArray bool `yaml:"as_array"`
- // object
- Fields []SchemaYaml `yaml:"fields"`
- // field
- FieldType string `yaml:"field_type"`
- }
- func NewSchemaDoc(schemaFilePath string) (*SchemaDoc, error) {
- if isStringEmpty(schemaFilePath) || !pathExists(schemaFilePath) {
- return nil, errors.New("schema文件不存在")
- }
- validatorFileBytes, err := os.ReadFile(schemaFilePath)
- if err != nil {
- return nil, errors.New("读取schema文件错误: " + err.Error())
- }
- schemaDocYaml := new(SchemaDocYaml)
- err = yaml.Unmarshal(validatorFileBytes, schemaDocYaml)
- if err != nil {
- return nil, errors.New("schema文件unmarshal错误: " + err.Error())
- }
- if schemaDocYaml.RootSchemas == nil || len(schemaDocYaml.RootSchemas) == 0 {
- return nil, errors.New("schema文件结构错误: 没有根节点")
- }
- doc := new(SchemaDoc)
- for _, rootSchema := range schemaDocYaml.RootSchemas {
- rootSchemaNode, err := newSchemaNode(&rootSchema)
- if err != nil {
- return nil, err
- }
- doc.rootSchemas = append(doc.rootSchemas, rootSchemaNode)
- }
- return doc, nil
- }
- func newSchemaNode(schemaNodeYaml *SchemaYaml) (SchemaNode, error) {
- switch schemaNodeYaml.Type {
- case schemaNodeTypeObject:
- return newObjectSchemaNode(schemaNodeYaml)
- case schemaNodeTypeField:
- return newFieldSchemaNode(schemaNodeYaml)
- default:
- return nil, errors.New("不支持的schema节点类型")
- }
- }
- func newObjectSchemaNode(schemaNodeYaml *SchemaYaml) (*ObjectSchemaNode, error) {
- if schemaNodeYaml.Type != schemaNodeTypeObject {
- return nil, errors.New("schema节点类型错误: 期望类型" + schemaNodeTypeObject + " 实际类型" + schemaNodeYaml.Type)
- }
- if isStringEmpty(schemaNodeYaml.Name) {
- return nil, errors.New(schemaNodeTypeObject + "schema类型必须有name属性")
- }
- if isStringEmpty(schemaNodeYaml.Describe) {
- return nil, errors.New(schemaNodeTypeObject + "schema类型必须有describe属性")
- }
- if schemaNodeYaml.Fields == nil || len(schemaNodeYaml.Fields) == 0 {
- return nil, errors.New(schemaNodeTypeObject + "schema类型必须有fields属性")
- }
- fieldSchemaNodes := make([]SchemaNode, 0)
- for _, field := range schemaNodeYaml.Fields {
- fieldSchemaNode, err := newSchemaNode(&field)
- if err != nil {
- return nil, err
- }
- fieldSchemaNodes = append(fieldSchemaNodes, fieldSchemaNode)
- }
- return &ObjectSchemaNode{
- BaseNamingSchemaNode: BaseNamingSchemaNode{
- Type: schemaNodeYaml.Type,
- Name: schemaNodeYaml.Name,
- Describe: schemaNodeYaml.Describe,
- Required: schemaNodeYaml.Required,
- },
- AsArray: schemaNodeYaml.AsArray,
- Fields: fieldSchemaNodes,
- }, nil
- }
- func newFieldSchemaNode(schemaNodeYaml *SchemaYaml) (*FieldSchemaNode, error) {
- if schemaNodeYaml.Type != schemaNodeTypeField {
- return nil, errors.New("schema节点类型错误: 期望类型" + schemaNodeTypeField + " 实际类型" + schemaNodeYaml.Type)
- }
- if isStringEmpty(schemaNodeYaml.Name) {
- return nil, errors.New(schemaNodeTypeObject + "schema类型必须有name属性")
- }
- if isStringEmpty(schemaNodeYaml.Describe) {
- return nil, errors.New(schemaNodeTypeObject + "schema类型必须有describe属性")
- }
- if isStringEmpty(schemaNodeYaml.FieldType) {
- return nil, errors.New(schemaNodeTypeObject + "schema类型必须有field_type属性")
- }
- return &FieldSchemaNode{
- BaseNamingSchemaNode: BaseNamingSchemaNode{
- Type: schemaNodeYaml.Type,
- Name: schemaNodeYaml.Name,
- Describe: schemaNodeYaml.Describe,
- Required: schemaNodeYaml.Required,
- },
- AsArray: schemaNodeYaml.AsArray,
- FieldType: schemaNodeYaml.FieldType,
- }, nil
- }
- func (schemaDoc *SchemaDoc) ValidateFile(filePath string) error {
- if !pathExists(filePath) {
- return errors.New("文件不存在: " + filePath)
- }
- fileBytes, err := os.ReadFile(filePath)
- if err != nil {
- return errors.New("读取文件错误: " + err.Error())
- }
- yamlMap := make(map[string]any)
- err = yaml.Unmarshal(fileBytes, yamlMap)
- if err != nil {
- return errors.New("unmarshal文件错误: " + err.Error())
- }
- return schemaDoc.validate(yamlMap)
- }
- func (schemaDoc *SchemaDoc) ValidateMap(yamlMap map[string]any) error {
- if yamlMap == nil || len(yamlMap) == 0 {
- return errors.New("没有yaml的map")
- }
- return schemaDoc.validate(yamlMap)
- }
- func (schemaDoc *SchemaDoc) validate(yamlMap map[string]any) error {
- for _, rootSchemaNode := range schemaDoc.rootSchemas {
- err := rootSchemaNode.Validate(yamlMap)
- if err != nil {
- return err
- }
- }
- return nil
- }
|