main.go (3094B)
1 // Example: Profile data completion menu. 2 package main 3 4 import ( 5 "context" 6 "flag" 7 "fmt" 8 "io/ioutil" 9 "log" 10 "os" 11 "path" 12 13 testdataloader "github.com/peteole/testdata-loader" 14 15 "git.defalsify.org/vise.git/cache" 16 "git.defalsify.org/vise.git/engine" 17 "git.defalsify.org/vise.git/resource" 18 "git.defalsify.org/vise.git/state" 19 "git.defalsify.org/vise.git/db" 20 fsdb "git.defalsify.org/vise.git/db/fs" 21 ) 22 23 const ( 24 USERFLAG_IDENTIFIED = iota + state.FLAG_USERSTART 25 USERFLAG_HAVENAME 26 USERFLAG_HAVEEMAIL 27 ) 28 29 var ( 30 baseDir = testdataloader.GetBasePath() 31 scriptDir = path.Join(baseDir, "examples", "profile") 32 emptyResult = resource.Result{} 33 ) 34 35 type profileResource struct { 36 *resource.DbResource 37 st *state.State 38 haveEntered bool 39 } 40 41 func newProfileResource(st *state.State, rs *resource.DbResource) resource.Resource { 42 return &profileResource{ 43 rs, 44 st, 45 false, 46 } 47 } 48 49 func(pr *profileResource) checkEntry() error { 50 log.Printf("%v %v", USERFLAG_IDENTIFIED, USERFLAG_HAVENAME) 51 if pr.haveEntered { 52 return nil 53 } 54 one := pr.st.GetFlag(USERFLAG_HAVENAME) 55 two := pr.st.GetFlag(USERFLAG_HAVEEMAIL) 56 if one && two { 57 pr.st.SetFlag(USERFLAG_IDENTIFIED) 58 pr.haveEntered = true 59 } 60 return nil 61 } 62 63 func(pr profileResource) nameSave(ctx context.Context, sym string, input []byte) (resource.Result, error) { 64 log.Printf("writing name to file") 65 fp := path.Join(scriptDir, "myname.txt") 66 err := ioutil.WriteFile(fp, input, 0600) 67 if err != nil { 68 return emptyResult, err 69 } 70 changed := pr.st.SetFlag(USERFLAG_HAVENAME) 71 if changed { 72 pr.checkEntry() 73 } 74 return emptyResult, err 75 } 76 77 func(pr profileResource) emailSave(ctx context.Context, sym string, input []byte) (resource.Result, error) { 78 log.Printf("writing email to file") 79 fp := path.Join(scriptDir, "myemail.txt") 80 err := ioutil.WriteFile(fp, input, 0600) 81 if err != nil { 82 return emptyResult, err 83 } 84 changed := pr.st.SetFlag(USERFLAG_HAVEEMAIL) 85 if changed { 86 pr.checkEntry() 87 } 88 return resource.Result{}, err 89 } 90 91 func main() { 92 var dir string 93 var root string 94 var size uint 95 var sessionId string 96 flag.UintVar(&size, "s", 0, "max size of output") 97 flag.StringVar(&root, "root", "root", "entry point symbol") 98 flag.StringVar(&sessionId, "session-id", "default", "session id") 99 flag.Parse() 100 fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir) 101 102 ctx := context.Background() 103 st := state.NewState(3) 104 store := fsdb.NewFsDb() 105 err := store.Connect(ctx, scriptDir) 106 if err != nil { 107 panic(err) 108 } 109 rsf := resource.NewDbResource(store) 110 rsf.With(db.DATATYPE_STATICLOAD) 111 rs, ok := newProfileResource(st, rsf).(*profileResource) 112 if !ok { 113 os.Exit(1) 114 } 115 rs.AddLocalFunc("do_name_save", rs.nameSave) 116 rs.AddLocalFunc("do_email_save", rs.emailSave) 117 ca := cache.NewCache() 118 cfg := engine.Config{ 119 Root: "root", 120 SessionId: sessionId, 121 OutputSize: uint32(size), 122 } 123 en := engine.NewEngine(cfg, rs) 124 en = en.WithState(st) 125 en = en.WithMemory(ca) 126 127 err = engine.Loop(ctx, en, os.Stdin, os.Stdout, nil) 128 if err != nil { 129 fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err) 130 os.Exit(1) 131 } 132 }