-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
1,007 additions
and
1,625 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
//go:build tools | ||
// +build tools | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/Xuanwo/gg" | ||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
func generateIterator(path string) { | ||
data := []string{ | ||
"Block", | ||
"Object", | ||
"Part", | ||
"Storager", | ||
} | ||
|
||
f := gg.NewGroup() | ||
f.AddLineComment("Code generated by go generate cmd/definitions; DO NOT EDIT.") | ||
f.AddPackage("types") | ||
f.NewImport(). | ||
AddPath("context"). | ||
AddPath("errors"). | ||
AddPath("fmt") | ||
|
||
f.NewInterface("Continuable"). | ||
NewFunction("ContinuationToken"). | ||
AddResult("", "string") | ||
|
||
for _, name := range data { | ||
typ := name | ||
// Add a `*` if the type is not an interface. | ||
if name != "Storager" { | ||
typ = "*" + typ | ||
} | ||
|
||
nextFuncName := fmt.Sprintf("Next%sFunc", name) | ||
pageStructName := fmt.Sprintf("%sPage", name) | ||
iteratorStructName := fmt.Sprintf("%sIterator", name) | ||
|
||
f.AddLineComment(`%s is the func used in iterator. | ||
Notes | ||
- ErrDone should be return while there are no items any more. | ||
- Input %s slice should be set every time. | ||
`, nextFuncName, name) | ||
f.AddType( | ||
nextFuncName, | ||
gg.Function(""). | ||
AddParameter("ctx", "context.Context"). | ||
AddParameter("page", "*"+pageStructName). | ||
AddResult("", "error")) | ||
|
||
f.NewStruct(pageStructName). | ||
AddField("Status", "Continuable"). | ||
AddField("Data", "[]"+typ) | ||
|
||
f.NewStruct(iteratorStructName). | ||
AddField("ctx", "context.Context"). | ||
AddField("next", nextFuncName). | ||
AddLine(). | ||
AddField("index", "int"). | ||
AddField("done", "bool"). | ||
AddLine(). | ||
AddField("o", pageStructName) | ||
|
||
f.NewFunction("New"+iteratorStructName). | ||
AddParameter("ctx", "context.Context"). | ||
AddParameter("next", nextFuncName). | ||
AddParameter("status", "Continuable"). | ||
AddResult("", "*"+iteratorStructName). | ||
AddBody(gg.Return( | ||
gg.Value("&"+iteratorStructName). | ||
AddField("ctx", "ctx"). | ||
AddField("next", "next"). | ||
AddField("o", gg.Value(pageStructName). | ||
AddField("Status", "status")))) | ||
|
||
f.NewFunction("ContinuationToken"). | ||
WithReceiver("it", "*"+iteratorStructName). | ||
AddResult("", "string"). | ||
AddBody(gg.Return( | ||
gg.Call("ContinuationToken").WithOwner("it.o.Status"))) | ||
|
||
f.NewFunction("Next"). | ||
WithReceiver("it", "*"+iteratorStructName). | ||
AddResult("object", typ). | ||
AddResult("err", "error"). | ||
AddBody( | ||
gg.LineComment("Consume Data via index."), | ||
gg.S(`// Consume Data via index. | ||
if it.index < len(it.o.Data) { | ||
it.index++ | ||
return it.o.Data[it.index-1], nil | ||
} | ||
// Return IterateDone if iterator is already done. | ||
if it.done { | ||
return nil, IterateDone | ||
} | ||
// Reset buf before call next. | ||
it.o.Data = it.o.Data[:0] | ||
err = it.next(it.ctx ,&it.o) | ||
if err != nil && !errors.Is(err, IterateDone) { | ||
return nil, fmt.Errorf("iterator next failed: %w", err) | ||
} | ||
// Make iterator to done so that we will not fetch from upstream anymore. | ||
if err != nil { | ||
it.done = true | ||
} | ||
// Return IterateDone directly if we don't have any data. | ||
if len(it.o.Data) == 0 { | ||
return nil, IterateDone | ||
} | ||
// Return the first object. | ||
it.index = 1 | ||
return it.o.Data[0], nil`)) | ||
} | ||
|
||
err := f.WriteFile(path) | ||
if err != nil { | ||
log.Fatalf("generate to %s: %v", path, err) | ||
} | ||
} |
Oops, something went wrong.