// Copyright Earl Warren // Copyright Loïc Dachary // SPDX-License-Identifier: MIT package f3 import ( "encoding/json" "fmt" "os" "github.com/santhosh-tekuri/jsonschema/v6" ) // Load project data from file, with optional validation func Load(filename string, data any, validation bool) error { bs, err := os.ReadFile(filename) if err != nil { return err } if validation { err := validate(bs, data) if err != nil { return err } } return unmarshal(bs, data) } func Store(filename string, data any) error { f, err := os.Create(filename) if err != nil { return err } defer f.Close() bs, err := json.MarshalIndent(data, "", " ") if err != nil { return err } if _, err := f.Write(bs); err != nil { return err } if _, err := f.Write([]byte("\n")); err != nil { return err } return nil } func unmarshal(bs []byte, data any) error { return json.Unmarshal(bs, data) } func getSchema(filename string) (*jsonschema.Schema, error) { c := jsonschema.NewCompiler() return c.Compile(filename) } func validate(bs []byte, datatype any) error { var v any err := unmarshal(bs, &v) if err != nil { return err } var schemaFilename string switch datatype := datatype.(type) { case *User: schemaFilename = "schemas/user.json" case *Organization: schemaFilename = "schemas/organization.json" case *Project: schemaFilename = "schemas/project.json" case *Topic: schemaFilename = "schemas/topic.json" case *Issue: schemaFilename = "schemas/issue.json" case *PullRequest: schemaFilename = "schemas/pullrequest.json" case *Label: schemaFilename = "schemas/label.json" case *Milestone: schemaFilename = "schemas/milestone.json" case *Release: schemaFilename = "schemas/release.json" case *ReleaseAsset: schemaFilename = "schemas/releaseasset.json" case *Comment: schemaFilename = "schemas/comment.json" case *Reaction: schemaFilename = "schemas/reaction.json" case *Repository: schemaFilename = "schemas/repository.json" case *Review: schemaFilename = "schemas/review.json" case *ReviewComment: schemaFilename = "schemas/reviewcomment.json" case *CI: schemaFilename = "schemas/ci.json" default: return fmt.Errorf("file_format:validate: %T does not have a schema that could be used for validation", datatype) } sch, err := getSchema(schemaFilename) if err != nil { return err } return sch.Validate(v) }