Home

cfg-playground @0d225cf70d9943c827fed720edf2b68cee28587b - refs - log -
-
https://git.jolheiser.com/cfg-playground.git
cfg playground
cfg-playground / main.go
- raw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main

import (
	_ "embed"
	"encoding/json"
	"fmt"
	"log/slog"
	"net/http"
	"os"
	"os/signal"

	"github.com/peterbourgon/ff/v3"
	"go.jolheiser.com/cfg"
	"go.jolheiser.com/cfg-playground/static"
	"go.jolheiser.com/ffjsonnet"
	"go.jolheiser.com/tailroute"
)

//go:embed static/index.html
var indexHTML []byte

func maine() error {
	args, fs := Flags()
	fs.String("config", "cfg.jsonnet", "Config file")
	if err := ff.Parse(fs, os.Args[1:],
		ff.WithEnvVarPrefix("CFG_PLAYGROUND"),
		ff.WithConfigFileFlag("config"),
		ff.WithAllowMissingConfigFile(true),
		ff.WithConfigFileParser(ffjsonnet.Parser),
	); err != nil {
		return err
	}

	if args.Verbose {
		slog.SetLogLoggerLevel(slog.LevelDebug)
	}

	if args.AuthKey != "" {
		os.Setenv("TS_AUTHKEY", args.AuthKey)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("GET /", index)
	mux.HandleFunc("GET /tailwind.css", static.TailwindHandler)
	mux.HandleFunc("POST /convert", convert)

	tr := tailroute.Router{
		Tailnet: mux,
	}
	go func() {
		fmt.Printf("Tailnet listening on http://%s\n", args.Hostname)
		if err := tr.Serve(args.Hostname, args.DataDir); err != nil {
			panic(err)
		}
	}()

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, os.Kill, os.Interrupt)
	<-ch
	return nil
}

func index(w http.ResponseWriter, r *http.Request) {
	if _, err := w.Write(indexHTML); err != nil {
		slog.Debug("could not write output", slog.Any("error", err))
		return
	}
}

func convert(w http.ResponseWriter, r *http.Request) {
	payload := struct {
		Input string
		From  string
		To    string
	}{}
	if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
		slog.Debug("could not decode JSON body", slog.Any("error", err))
		return
	}
	defer r.Body.Close()

	inputFormat, err := cfg.ParseEncoding(payload.From)
	if err != nil {
		slog.Debug("could not parse input encoding", slog.Any("error", err))
		return
	}
	outputFormat, err := cfg.ParseEncoding(payload.To)
	if err != nil {
		slog.Debug("could not parse output encoding", slog.Any("error", err))
		return
	}

	var data any
	if err := inputFormat.Unmarshal([]byte(payload.Input), &data); err != nil {
		slog.Debug("could not unmarshal input", slog.Any("error", err))
		return
	}
	out, err := outputFormat.Marshal(data)
	if err != nil {
		slog.Debug("could not marshal output", slog.Any("error", err))
		return
	}

	if _, err := w.Write(out); err != nil {
		slog.Debug("could not write output", slog.Any("error", err))
		return
	}
}

func main() {
	if err := maine(); err != nil {
		slog.Error("error running cfg-playground", slog.Any("error", err))
	}
}