Skip to content

Instantly share code, notes, and snippets.

@mniak
Last active May 16, 2024 16:01
Show Gist options
  • Save mniak/dc34f5eca3a71530802e36e291beb63b to your computer and use it in GitHub Desktop.
Save mniak/dc34f5eca3a71530802e36e291beb63b to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"path/filepath"
"strconv"
"github.com/dave/jennifer/jen"
"github.com/samber/lo"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
const (
minParams = 0
maxParams = 15
outdir = ""
failureMessage = "failureMessage"
)
const (
pkgFmt = "fmt"
)
func main() {
for paramCount := minParams; paramCount <= maxParams; paramCount++ {
f := jen.NewFile("try")
name := func(prefix string, n int) string {
return prefix + strconv.Itoa(n)
}
structName := name("from", paramCount)
T := func(n int) string {
return name("T", n)
}
// struct
f.Type().
Id(structName).
TypesFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(T(n)).Any())
}
}).
StructFunc(func(g *jen.Group) {
g.Add(jen.Id("err").Error())
g.Add(jen.Id(failureMessage).String())
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(name("result", n)).Id(T(n)))
}
})
// constructor "from"
declareConstructor := func(ctorName string) {
f.Func().
Id(ctorName).
TypesFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(T(n)).Any())
}
}).
ParamsFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(name("result", n)).Id(T(n)))
}
g.Add(jen.Id("err").Error())
}).
Op("*").Id(structName).
TypesFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(T(n)))
}
}).
Block(
jen.Return(jen.Op("&").Id(structName).
TypesFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(T(n)))
}
}).
Values(
jen.DictFunc(func(d jen.Dict) {
d[jen.Id("err")] = jen.Id("err")
for n := 1; n <= paramCount; n++ {
d[jen.Id(name("result", n))] = jen.Id(name("result", n))
}
}),
)),
)
f.Line()
}
declareConstructor(name("From", paramCount))
if paramCount == 1 {
declareConstructor("From")
}
// failure message
f.Func().
Params(jen.Id("self").Op("*").Id(structName).TypesFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(T(n)))
}
})).
Id(titleCase(failureMessage)).
Params(jen.Id("msg").String()).
Params(jen.Op("*").Id(structName).TypesFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(T(n)))
}
})).
Block(
jen.Id("self").Dot(failureMessage).Op("=").Id("msg"),
jen.Return(jen.Id("self")),
)
f.Line()
// unwrap
f.Func().
Params(jen.Id("self").Op("*").Id(structName).TypesFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(T(n)))
}
})).
Id("Unwrap").
Params().
ParamsFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id(T(n)))
}
}).
Block(
jen.If(
jen.Id("self").Dot("err").Op("!=").Nil(),
).Block(
jen.If(
jen.Id("self").Dot(failureMessage).Op("!=").Lit(""),
).Block(
jen.Panic(jen.Qual(pkgFmt, "Sprintf").Call(
jen.Lit("%s: %s"),
jen.Id("self").Dot(failureMessage),
jen.Id("self").Dot("err"),
)),
).Else().Block(
jen.Panic(jen.Id("self").Dot("err")),
),
),
jen.ReturnFunc(func(g *jen.Group) {
for n := 1; n <= paramCount; n++ {
g.Add(jen.Id("self").Dot(name("result", n)))
}
}),
)
lo.Must0(f.Save(filepath.Join(outdir, fmt.Sprintf("try%d.go", paramCount))))
fmt.Printf("%#v", f)
}
}
func titleCase(text string) string {
return cases.Title(language.English, cases.NoLower).String(text)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment