2023-08-23 09:27:23 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"errors"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"sort"
|
|
|
|
|
|
|
|
"github.com/lightninglabs/loop/fsm"
|
2023-08-24 23:46:25 +00:00
|
|
|
"github.com/lightninglabs/loop/instantout/reservation"
|
2023-08-23 09:27:23 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
if err := run(); err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func run() error {
|
|
|
|
out := flag.String("out", "", "outfile")
|
|
|
|
stateMachine := flag.String("fsm", "", "the swap state machine to parse")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
if filepath.Ext(*out) != ".md" {
|
|
|
|
return errors.New("wrong argument: out must be a .md file")
|
|
|
|
}
|
|
|
|
|
|
|
|
fp, err := filepath.Abs(*out)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
switch *stateMachine {
|
|
|
|
case "example":
|
|
|
|
exampleFSM := &fsm.ExampleFSM{}
|
|
|
|
err = writeMermaidFile(fp, exampleFSM.GetStates())
|
|
|
|
if err != nil {
|
2023-08-24 23:46:25 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
case "reservation":
|
|
|
|
reservationFSM := &reservation.FSM{}
|
|
|
|
err = writeMermaidFile(fp, reservationFSM.GetReservationStates())
|
|
|
|
if err != nil {
|
2023-08-23 09:27:23 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
fmt.Println("Missing or wrong argument: fsm must be one of:")
|
|
|
|
fmt.Println("\treservations")
|
|
|
|
fmt.Println("\texample")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func writeMermaidFile(filename string, states fsm.States) error {
|
|
|
|
f, err := os.Create(filename)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
var b bytes.Buffer
|
|
|
|
fmt.Fprint(&b, "```mermaid\nstateDiagram-v2\n")
|
|
|
|
|
|
|
|
sortedStates := sortedKeys(states)
|
|
|
|
for _, state := range sortedStates {
|
|
|
|
edges := states[fsm.StateType(state)]
|
|
|
|
// write state name
|
|
|
|
if len(state) > 0 {
|
|
|
|
fmt.Fprintf(&b, "%s\n", state)
|
|
|
|
} else {
|
|
|
|
state = "[*]"
|
|
|
|
}
|
|
|
|
// write transitions
|
|
|
|
for edge, target := range edges.Transitions {
|
|
|
|
fmt.Fprintf(&b, "%s --> %s: %s\n", state, target, edge)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Fprint(&b, "```")
|
|
|
|
_, err = f.Write(b.Bytes())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func sortedKeys(m fsm.States) []string {
|
|
|
|
keys := make([]string, len(m))
|
|
|
|
i := 0
|
|
|
|
for k := range m {
|
|
|
|
keys[i] = string(k)
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
sort.Strings(keys)
|
|
|
|
return keys
|
|
|
|
}
|