summaryrefslogtreecommitdiff
path: root/frontend.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2017-11-16 10:08:15 -0500
committerLuke Shumaker <lukeshu@lukeshu.com>2017-11-16 10:08:15 -0500
commitce0f40c125ff838d332c1974c8e505e4be1e409b (patch)
treef78a992881f07421ae9cc5afc259ca5527614df1 /frontend.go
parentefc7a5ebc9e10983571c080017100a8b39eee1d0 (diff)
more
Diffstat (limited to 'frontend.go')
-rw-r--r--frontend.go123
1 files changed, 81 insertions, 42 deletions
diff --git a/frontend.go b/frontend.go
index 73f6d73..405ead4 100644
--- a/frontend.go
+++ b/frontend.go
@@ -1,68 +1,107 @@
package libfastimport
import (
- "io"
"bufio"
+ "io"
+ "strings"
"git.lukeshu.com/go/libfastimport/textproto"
)
+type UnsupportedCommand string
+
+func (e UnsupportedCommand) Error() string {
+ return "Unsupported command: " + string(e)
+}
+
+type cmderror struct {
+ Cmd
+ error
+}
+
+// A Frontend is something that produces a fast-import stream; the
+// Frontend object provides methods for reading from it.
type Frontend struct {
- w *bufio.Writer
- fiw *textproto.FIWriter
- cbr *textproto.CatBlobReader
+ fir *textproto.FIReader
+ cbw *textproto.CatBlobWriter
+ w *bufio.Writer
+ c chan cmderror
}
-func NewFrontend(w io.Writer, r io.Reader) *Frontend {
+func NewFrontend(fastImport io.Reader, catBlob io.Writer) *Frontend {
ret := Frontend{}
- ret.w = bufio.NewWriter(w)
- ret.fiw = textproto.NewFIWriter(ret.w)
- if r != nil {
- ret.cbr = textproto.NewCatBlobReader(r)
+ ret.fir = textproto.NewFIReader(fastImport)
+ if catBlob != nil {
+ ret.w = bufio.NewWriter(catBlob)
+ ret.cbw = textproto.NewCatBlobWriter(ret.w)
}
return &ret
}
-func (f *Frontend) Do(cmd Cmd) error {
- err := cmd.fiWriteCmd(f.fiw)
+func (f *Frontend) nextLine() (line string, err error) {
+retry:
+ line, err = f.fir.ReadLine()
if err != nil {
- return err
+ return
+ }
+ switch {
+ case strings.HasPrefix(line, "#"):
+ f.c <- cmderror{CmdComment{Comment: line[1:]}, nil}
+ goto retry
+ case strings.HasPrefix(line, "cat-blob "):
+ f.c <- parse_cat_blob(line)
+ goto retry
+ case strings.HasPrefix(line, "get-mark "):
+ f.c <- parse_get_mark(line)
+ goto retry
+ default:
+ return
}
- return f.w.Flush()
}
-func (f *Frontend) GetMark(cmd CmdGetMark) (string, error) {
- err := f.Do(cmd)
- if err != nil {
- return "", err
+func (f *Frontend) parse() {
+ for {
+ line, err := f.nextLine()
+ if err != nil {
+ f.c <- cmderror{nil, err}
+ return
+ }
+ switch {
+ case strings.HasPrefix(line, "blob "):
+ case strings.HasPrefix(line, "commit "):
+ case strings.HasPrefix(line, "checkpoint\n"):
+ case strings.HasPrefix(line, "done\n"):
+ case strings.HasPrefix(line, "feature "):
+ case strings.HasPrefix(line, "ls "):
+ case strings.HasPrefix(line, "option "):
+ case strings.HasPrefix(line, "progress "):
+ case strings.HasPrefix(line, "reset "):
+ case strings.HasPrefix(line, "tag "):
+ default:
+ f.c <- cmderror{nil, UnsupportedCommand(line)}
+ return
+ }
}
- line, err := f.cbr.ReadLine()
- if err != nil {
- return "", err
- }
- return cbpGetMark(line)
}
-func (f *Frontend) CatBlob(cmd CmdCatBlob) (sha1 string, data string, err error) {
- err = f.Do(cmd)
- if err != nil {
- return "", "", err
- }
- line, err := f.cbr.ReadLine()
- if err != nil {
- return "", "", err
- }
- return cbpCatBlob(line)
+func (f *Frontend) ReadCmd() (Cmd, error) {
+ cmderror := <-f.c
+ cmd := cmderror.Cmd
+ err := cmderror.error
+ return cmderror.Cmd, cmderror.error
}
-func (f *Frontend) Ls(cmd CmdLs) (mode textproto.Mode, dataref string, path textproto.Path, err error) {
- err = f.Do(cmd)
- if err != nil {
- return 0, "", "", err
- }
- line, err := f.cbr.ReadLine()
- if err != nil {
- return 0, "", "", err
- }
- return cbpLs(line)
+func (f *Frontend) RespondGetMark(sha1 string) error {
+ // TODO
+ return f.w.Flush()
+}
+
+func (f *Frontend) RespondCatBlob(sha1 string, data string) error {
+ // TODO
+ return f.w.Flush()
+}
+
+func (f *Frontend) RespondLs(mode textproto.Mode, dataref string, path textproto.Path) error {
+ // TODO
+ return f.w.Flush()
}