105 lines
3.1 KiB
Go
105 lines
3.1 KiB
Go
// Run from the framework root with: go run ./examples/developerTools
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"strconv"
|
|
_ "time/tzdata" // This example embeds zones; production builds can use -tags timetzdata.
|
|
|
|
"git.yuntuo.hk/k2safe/go-omni/config"
|
|
"git.yuntuo.hk/k2safe/go-omni/copyx"
|
|
mysql "git.yuntuo.hk/k2safe/go-omni/database/mysql"
|
|
"git.yuntuo.hk/k2safe/go-omni/httpc"
|
|
"git.yuntuo.hk/k2safe/go-omni/logx"
|
|
)
|
|
|
|
type Config struct {
|
|
Database mysql.Config `json:"database"`
|
|
Server config.Config `json:"server"`
|
|
}
|
|
|
|
func Default() Config {
|
|
c := config.Default()
|
|
c.Log.Output = "stdout"
|
|
return Config{Database: mysql.DefaultConfig(), Server: c}
|
|
}
|
|
func (c Config) Validate() error {
|
|
if err := c.Database.Validate(); err != nil {
|
|
return config.AtField("database", err)
|
|
}
|
|
return config.AtField("server", c.Server.Validate())
|
|
}
|
|
|
|
type Input struct{ Values []TextValue }
|
|
type TextValue struct{ Number string }
|
|
type Result struct{ Values []NumberValue }
|
|
type NumberValue struct{ Number int }
|
|
|
|
func run(path string) error {
|
|
cfg, err := config.LoadProject(path, Default())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Validation only: this example never opens a database.
|
|
logger, err := logx.New(cfg.Server.Log)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer logger.Close()
|
|
logger.InfoContext(context.Background(), "instance time zone", "configuredZone", cfg.Server.Log.TimeZone)
|
|
if err := copyx.Check[Input, Result](); !errors.Is(err, copyx.ErrType) {
|
|
return fmt.Errorf("expected a type mismatch, got %v", err)
|
|
}
|
|
// Explicit Go converter owns the number conversion; no JSON mapping file.
|
|
options := []copyx.Option{copyx.WithConverter(strconv.Atoi)}
|
|
if err := copyx.Check[Input, Result](options...); err != nil {
|
|
return err
|
|
}
|
|
var output Result
|
|
if err := copyx.Copy(&output, Input{Values: []TextValue{{Number: "42"}}}, options...); err != nil {
|
|
return err
|
|
}
|
|
fmt.Printf("type check and copy succeeded: %d\n", output.Values[0].Number)
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path == "/created" {
|
|
w.WriteHeader(http.StatusCreated)
|
|
}
|
|
io.WriteString(w, `{"value":"example"}`)
|
|
}))
|
|
defer server.Close()
|
|
client, err := httpc.New(httpc.Config{DisableLogging: true})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer client.Close()
|
|
var reply struct {
|
|
Value string `json:"value"`
|
|
}
|
|
if err := client.JSON(context.Background(), http.MethodGet, server.URL, nil, &reply, httpc.WithSuccessStatuses(http.StatusOK)); err != nil {
|
|
return err
|
|
}
|
|
err = client.JSON(context.Background(), http.MethodGet, server.URL+"/created", nil, &reply, httpc.WithSuccessStatuses(http.StatusOK))
|
|
var status *httpc.StatusError
|
|
if !errors.As(err, &status) || status.StatusCode != http.StatusCreated {
|
|
return fmt.Errorf("expected status rejection, got %v", err)
|
|
}
|
|
fmt.Println("strict JSON: 200 accepted, 201 rejected")
|
|
return nil
|
|
}
|
|
func main() {
|
|
path := flag.String("config", "examples/developerTools/config.yaml", "selected configuration file")
|
|
flag.Parse()
|
|
if err := run(*path); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|