2023-07-23 22:05:54 +02:00
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2023-07-13 17:34:13 +02:00
package cli
import (
"fmt"
"log"
"os"
"path/filepath"
2023-08-17 23:03:03 +02:00
"strings"
2023-07-13 17:34:13 +02:00
"time"
C "github.com/urfave/cli/v2"
)
2023-07-17 13:55:35 +02:00
func writeTupleType ( f * os . File , symbol string , i int ) {
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , "Tuple%d[" , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
2023-07-17 13:55:35 +02:00
fmt . Fprintf ( f , "%s%d" , symbol , j )
2023-07-13 17:34:13 +02:00
}
fmt . Fprintf ( f , "]" )
}
2023-08-17 23:03:03 +02:00
func makeTupleType ( name string ) func ( i int ) string {
return func ( i int ) string {
var buf strings . Builder
buf . WriteString ( fmt . Sprintf ( "Tuple%d[" , i ) )
for j := 0 ; j < i ; j ++ {
if j > 0 {
buf . WriteString ( ", " )
}
buf . WriteString ( fmt . Sprintf ( "%s%d" , name , j + 1 ) )
}
buf . WriteString ( "]" )
return buf . String ( )
}
}
func generatePush ( f * os . File , i int ) {
tuple1 := makeTupleType ( "T" ) ( i )
tuple2 := makeTupleType ( "T" ) ( i + 1 )
// Create the replicate version
fmt . Fprintf ( f , "\n// Push%d creates a [Tuple%d] from a [Tuple%d] by appending a constant value\n" , i , i + 1 , i )
fmt . Fprintf ( f , "func Push%d[" , i )
// function prototypes
for j := 0 ; j <= i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j + 1 )
}
fmt . Fprintf ( f , " any](value T%d) func(%s) %s {\n" , i + 1 , tuple1 , tuple2 )
fmt . Fprintf ( f , " return func(t %s) %s {\n" , tuple1 , tuple2 )
fmt . Fprintf ( f , " return MakeTuple%d(" , i + 1 )
for j := 0 ; j < i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "t.F%d" , j + 1 )
}
fmt . Fprintf ( f , ", value)\n" )
fmt . Fprintf ( f , " }\n" )
fmt . Fprintf ( f , "}\n" )
}
2023-07-17 13:55:35 +02:00
func generateReplicate ( f * os . File , i int ) {
2023-08-17 23:03:03 +02:00
// Create the replicate version
2023-07-17 13:55:35 +02:00
fmt . Fprintf ( f , "\n// Replicate%d creates a [Tuple%d] with all fields set to the input value `t`\n" , i , i )
fmt . Fprintf ( f , "func Replicate%d[T any](t T) Tuple%d[" , i , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T" )
}
fmt . Fprintf ( f , "] {\n" )
// execute the mapping
fmt . Fprintf ( f , " return MakeTuple%d(" , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "t" )
}
fmt . Fprintf ( f , ")\n" )
fmt . Fprintf ( f , "}\n" )
}
func generateMap ( f * os . File , i int ) {
// Create the optionize version
fmt . Fprintf ( f , "\n// Map%d maps each value of a [Tuple%d] via a mapping function\n" , i , i )
fmt . Fprintf ( f , "func Map%d[" , i )
// function prototypes
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "F%d ~func(T%d) R%d" , j , j , j )
}
for j := 1 ; j <= i ; j ++ {
fmt . Fprintf ( f , ", T%d, R%d" , j , j )
}
fmt . Fprintf ( f , " any](" )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "f%d F%d" , j , j )
}
fmt . Fprintf ( f , ") func(" )
writeTupleType ( f , "T" , i )
fmt . Fprintf ( f , ") " )
writeTupleType ( f , "R" , i )
fmt . Fprintf ( f , " {\n" )
fmt . Fprintf ( f , " return func(t " )
writeTupleType ( f , "T" , i )
fmt . Fprintf ( f , ") " )
writeTupleType ( f , "R" , i )
fmt . Fprintf ( f , " {\n" )
// execute the mapping
fmt . Fprintf ( f , " return MakeTuple%d(\n" , i )
for j := 1 ; j <= i ; j ++ {
fmt . Fprintf ( f , " f%d(t.F%d),\n" , j , j )
}
fmt . Fprintf ( f , " )\n" )
fmt . Fprintf ( f , " }\n" )
fmt . Fprintf ( f , "}\n" )
}
2023-07-13 17:34:13 +02:00
func generateMonoid ( f * os . File , i int ) {
// Create the optionize version
fmt . Fprintf ( f , "\n// Monoid%d creates a [Monoid] for a [Tuple%d] based on %d monoids for the contained types\n" , i , i , i )
fmt . Fprintf ( f , "func Monoid%d[" , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j )
}
fmt . Fprintf ( f , " any](" )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "m%d M.Monoid[T%d]" , j , j )
}
fmt . Fprintf ( f , ") M.Monoid[" )
2023-07-17 13:55:35 +02:00
writeTupleType ( f , "T" , i )
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , "] {\n" )
fmt . Fprintf ( f , " return M.MakeMonoid(func(l, r " )
2023-07-17 13:55:35 +02:00
writeTupleType ( f , "T" , i )
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , ") " )
2023-07-17 13:55:35 +02:00
writeTupleType ( f , "T" , i )
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , "{\n" )
fmt . Fprintf ( f , " return MakeTuple%d(" , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "m%d.Concat(l.F%d, r.F%d)" , j , j , j )
}
fmt . Fprintf ( f , ")\n" )
fmt . Fprintf ( f , " }, MakeTuple%d(" , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "m%d.Empty()" , j )
}
fmt . Fprintf ( f , "))\n" )
fmt . Fprintf ( f , "}\n" )
}
func generateOrd ( f * os . File , i int ) {
// Create the optionize version
fmt . Fprintf ( f , "\n// Ord%d creates n [Ord] for a [Tuple%d] based on %d [Ord]s for the contained types\n" , i , i , i )
fmt . Fprintf ( f , "func Ord%d[" , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j )
}
fmt . Fprintf ( f , " any](" )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "o%d O.Ord[T%d]" , j , j )
}
fmt . Fprintf ( f , ") O.Ord[" )
2023-07-17 13:55:35 +02:00
writeTupleType ( f , "T" , i )
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , "] {\n" )
fmt . Fprintf ( f , " return O.MakeOrd(func(l, r " )
2023-07-17 13:55:35 +02:00
writeTupleType ( f , "T" , i )
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , ") int {\n" )
for j := 1 ; j <= i ; j ++ {
fmt . Fprintf ( f , " if c:= o%d.Compare(l.F%d, r.F%d); c != 0 {return c}\n" , j , j , j )
}
fmt . Fprintf ( f , " return 0\n" )
fmt . Fprintf ( f , " }, func(l, r " )
2023-07-17 13:55:35 +02:00
writeTupleType ( f , "T" , i )
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , ") bool {\n" )
fmt . Fprintf ( f , " return " )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , " && " )
}
fmt . Fprintf ( f , "o%d.Equals(l.F%d, r.F%d)" , j , j , j )
}
fmt . Fprintf ( f , "\n" )
fmt . Fprintf ( f , " })\n" )
fmt . Fprintf ( f , "}\n" )
}
func generateTupleType ( f * os . File , i int ) {
// Create the optionize version
fmt . Fprintf ( f , "\n// Tuple%d is a struct that carries %d independently typed values\n" , i , i )
fmt . Fprintf ( f , "type Tuple%d[" , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j )
}
fmt . Fprintf ( f , " any] struct {\n" )
for j := 1 ; j <= i ; j ++ {
fmt . Fprintf ( f , " F%d T%d\n" , j , j )
}
fmt . Fprintf ( f , "}\n" )
}
func generateMakeTupleType ( f * os . File , i int ) {
// Create the optionize version
fmt . Fprintf ( f , "\n// MakeTuple%d is a function that converts its %d parameters into a [Tuple%d]\n" , i , i , i )
fmt . Fprintf ( f , "func MakeTuple%d[" , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j )
}
fmt . Fprintf ( f , " any](" )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "t%d T%d" , j , j )
}
fmt . Fprintf ( f , ") " )
2023-07-17 13:55:35 +02:00
writeTupleType ( f , "T" , i )
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , " {\n" )
fmt . Fprintf ( f , " return Tuple%d[" , i )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j )
}
fmt . Fprintf ( f , "]{" )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "t%d" , j )
}
fmt . Fprintf ( f , "}\n" )
fmt . Fprintf ( f , "}\n" )
}
func generateUntupled ( f * os . File , i int ) {
// Create the optionize version
fmt . Fprintf ( f , "\n// Untupled%d converts a function with a [Tuple%d] parameter into a function with %d parameters\n// The inverse function is [Tupled%d]\n" , i , i , i , i )
fmt . Fprintf ( f , "func Untupled%d[F ~func(Tuple%d[" , i , i )
for j := 0 ; j < i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j + 1 )
}
fmt . Fprintf ( f , "]) R" )
for j := 0 ; j < i ; j ++ {
fmt . Fprintf ( f , ", T%d" , j + 1 )
}
fmt . Fprintf ( f , ", R any](f F) func(" )
for j := 0 ; j < i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j + 1 )
}
fmt . Fprintf ( f , ") R {\n" )
fmt . Fprintf ( f , " return func(" )
for j := 0 ; j < i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "t%d T%d" , j + 1 , j + 1 )
}
fmt . Fprintf ( f , ") R {\n" )
fmt . Fprintf ( f , " return f(MakeTuple%d(" , i )
for j := 0 ; j < i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "t%d" , j + 1 )
}
fmt . Fprintln ( f , "))" )
fmt . Fprintln ( f , " }" )
fmt . Fprintln ( f , "}" )
}
func generateTupled ( f * os . File , i int ) {
// Create the optionize version
2023-09-15 17:01:11 -07:00
fmt . Fprintf ( f , "\n// Tupled%d converts a function with %d parameters into a function taking a Tuple%d\n// The inverse function is [Untupled%d]\n" , i , i , i , i )
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , "func Tupled%d[F ~func(" , i )
for j := 0 ; j < i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j + 1 )
}
fmt . Fprintf ( f , ") R" )
for j := 0 ; j < i ; j ++ {
fmt . Fprintf ( f , ", T%d" , j + 1 )
}
fmt . Fprintf ( f , ", R any](f F) func(Tuple%d[" , i )
for j := 0 ; j < i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j + 1 )
}
fmt . Fprintf ( f , "]) R {\n" )
fmt . Fprintf ( f , " return func(t Tuple%d[" , i )
for j := 0 ; j < i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "T%d" , j + 1 )
}
fmt . Fprintf ( f , "]) R {\n" )
fmt . Fprintf ( f , " return f(" )
for j := 0 ; j < i ; j ++ {
if j > 0 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "t.F%d" , j + 1 )
}
fmt . Fprintf ( f , ")\n" )
fmt . Fprintf ( f , " }\n" )
fmt . Fprintln ( f , "}" )
}
func generateTupleHelpers ( filename string , count int ) error {
dir , err := os . Getwd ( )
if err != nil {
return err
}
absDir , err := filepath . Abs ( dir )
if err != nil {
return err
}
pkg := filepath . Base ( absDir )
2023-07-13 22:24:04 +02:00
f , err := os . Create ( filepath . Clean ( filename ) )
2023-07-13 17:34:13 +02:00
if err != nil {
return err
}
defer f . Close ( )
// log
log . Printf ( "Generating code in [%s] for package [%s] with [%d] repetitions ..." , filename , pkg , count )
// some header
fmt . Fprintln ( f , "// Code generated by go generate; DO NOT EDIT." )
fmt . Fprintln ( f , "// This file was generated by robots at" )
2023-08-11 11:56:11 +02:00
fmt . Fprintf ( f , "// %s\n\n" , time . Now ( ) )
2023-07-13 17:34:13 +02:00
fmt . Fprintf ( f , "package %s\n\n" , pkg )
fmt . Fprintf ( f , `
import (
2023-07-18 15:57:54 +02:00
M "github.com/IBM/fp-go/monoid"
2023-07-28 15:50:03 +02:00
O "github.com/IBM/fp-go/ord"
2023-07-13 17:34:13 +02:00
)
` )
for i := 1 ; i <= count ; i ++ {
// tuple type
generateTupleType ( f , i )
}
for i := 1 ; i <= count ; i ++ {
// tuple generator
generateMakeTupleType ( f , i )
// tupled wrapper
generateTupled ( f , i )
// untupled wrapper
generateUntupled ( f , i )
// monoid
generateMonoid ( f , i )
// generate order
generateOrd ( f , i )
2023-07-17 13:55:35 +02:00
// generate map
generateMap ( f , i )
// generate replicate
generateReplicate ( f , i )
2023-07-28 15:50:03 +02:00
// generate tuple functions such as string and fmt
generateTupleString ( f , i )
// generate json support
generateTupleMarshal ( f , i )
// generate json support
generateTupleUnmarshal ( f , i )
// generate toArray
generateToArray ( f , i )
// generate fromArray
generateFromArray ( f , i )
2023-08-17 23:03:03 +02:00
// generate push
if i < count {
generatePush ( f , i )
}
2023-07-13 17:34:13 +02:00
}
return nil
}
2023-07-28 15:50:03 +02:00
func generateTupleMarshal ( f * os . File , i int ) {
// Create the stringify version
fmt . Fprintf ( f , "\n// MarshalJSON marshals the [Tuple%d] into a JSON array\n" , i )
fmt . Fprintf ( f , "func (t " )
writeTupleType ( f , "T" , i )
fmt . Fprintf ( f , ") MarshalJSON() ([]byte, error) {\n" )
2024-02-08 08:41:51 +01:00
fmt . Fprintf ( f , " return tupleMarshalJSON(" )
2023-07-28 15:50:03 +02:00
// function prototypes
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "t.F%d" , j )
}
2024-02-08 08:41:51 +01:00
fmt . Fprintf ( f , ")\n" )
2023-07-28 15:50:03 +02:00
fmt . Fprintf ( f , "}\n" )
}
func generateTupleUnmarshal ( f * os . File , i int ) {
// Create the stringify version
fmt . Fprintf ( f , "\n// UnmarshalJSON unmarshals a JSON array into a [Tuple%d]\n" , i )
fmt . Fprintf ( f , "func (t *" )
writeTupleType ( f , "T" , i )
fmt . Fprintf ( f , ") UnmarshalJSON(data []byte) error {\n" )
2024-02-08 08:41:51 +01:00
fmt . Fprintf ( f , " return tupleUnmarshalJSON(data" )
// function prototypes
2023-07-28 15:50:03 +02:00
for j := 1 ; j <= i ; j ++ {
2024-02-08 08:41:51 +01:00
fmt . Fprintf ( f , ", &t.F%d" , j )
2023-07-28 15:50:03 +02:00
}
2024-02-08 08:41:51 +01:00
fmt . Fprintf ( f , ")\n" )
2023-07-28 15:50:03 +02:00
fmt . Fprintf ( f , "}\n" )
}
func generateToArray ( f * os . File , i int ) {
// Create the stringify version
fmt . Fprintf ( f , "\n// ToArray converts the [Tuple%d] into an array of type [R] using %d transformation functions from [T] to [R]\n// The inverse function is [FromArray%d]\n" , i , i , i )
fmt . Fprintf ( f , "func ToArray%d[" , i )
// function prototypes
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "F%d ~func(T%d) R" , j , j )
}
for j := 1 ; j <= i ; j ++ {
fmt . Fprintf ( f , ", T%d" , j )
}
fmt . Fprintf ( f , ", R any](" )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "f%d F%d" , j , j )
}
fmt . Fprintf ( f , ") func(t " )
writeTupleType ( f , "T" , i )
fmt . Fprintf ( f , ") []R {\n" )
fmt . Fprintf ( f , " return func(t " )
writeTupleType ( f , "T" , i )
fmt . Fprintf ( f , ") []R {\n" )
fmt . Fprintf ( f , " return []R{\n" )
for j := 1 ; j <= i ; j ++ {
fmt . Fprintf ( f , " f%d(t.F%d),\n" , j , j )
}
fmt . Fprintf ( f , " }\n" )
fmt . Fprintf ( f , " }\n" )
fmt . Fprintf ( f , "}\n" )
}
func generateFromArray ( f * os . File , i int ) {
// Create the stringify version
fmt . Fprintf ( f , "\n// FromArray converts an array of [R] into a [Tuple%d] using %d functions from [R] to [T]\n// The inverse function is [ToArray%d]\n" , i , i , i )
fmt . Fprintf ( f , "func FromArray%d[" , i )
// function prototypes
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "F%d ~func(R) T%d" , j , j )
}
for j := 1 ; j <= i ; j ++ {
fmt . Fprintf ( f , ", T%d" , j )
}
fmt . Fprintf ( f , ", R any](" )
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "f%d F%d" , j , j )
}
fmt . Fprintf ( f , ") func(r []R) " )
writeTupleType ( f , "T" , i )
fmt . Fprintf ( f , " {\n" )
fmt . Fprintf ( f , " return func(r []R) " )
writeTupleType ( f , "T" , i )
fmt . Fprintf ( f , " {\n" )
fmt . Fprintf ( f , " return MakeTuple%d(\n" , i )
for j := 1 ; j <= i ; j ++ {
fmt . Fprintf ( f , " f%d(r[%d]),\n" , j , j - 1 )
}
fmt . Fprintf ( f , " )\n" )
fmt . Fprintf ( f , " }\n" )
fmt . Fprintf ( f , "}\n" )
}
func generateTupleString ( f * os . File , i int ) {
// Create the stringify version
fmt . Fprintf ( f , "\n// String prints some debug info for the [Tuple%d]\n" , i )
fmt . Fprintf ( f , "func (t " )
writeTupleType ( f , "T" , i )
fmt . Fprintf ( f , ") String() string {\n" )
// convert to string
2024-02-08 08:41:51 +01:00
fmt . Fprint ( f , " return tupleString(" )
2023-07-28 15:50:03 +02:00
for j := 1 ; j <= i ; j ++ {
if j > 1 {
fmt . Fprintf ( f , ", " )
}
fmt . Fprintf ( f , "t.F%d" , j )
}
fmt . Fprintf ( f , ")\n" )
fmt . Fprintf ( f , "}\n" )
}
// func generateTupleJson(f *os.File, i int) {
// // Create the stringify version
// fmt.Fprintf(f, "\n// MarshalJSON converts the [Tuple%d] into a JSON byte stream\n", i)
// fmt.Fprintf(f, "func (t ")
// writeTupleType(f, "T", i)
// fmt.Fprintf(f, ") MarshalJSON() ([]byte, error) {\n")
// // convert to string
// fmt.Fprintf(f, " return fmt.Sprintf(\"Tuple%d[", i)
// for j := 1; j <= i; j++ {
// if j > 1 {
// fmt.Fprintf(f, ", ")
// }
// fmt.Fprintf(f, "%s", "%T")
// }
// fmt.Fprintf(f, "](")
// for j := 1; j <= i; j++ {
// if j > 1 {
// fmt.Fprintf(f, ", ")
// }
// fmt.Fprintf(f, "%s", "%v")
// }
// fmt.Fprintf(f, ")\", ")
// for j := 1; j <= i; j++ {
// if j > 1 {
// fmt.Fprintf(f, ", ")
// }
// fmt.Fprintf(f, "t.F%d", j)
// }
// for j := 1; j <= i; j++ {
// fmt.Fprintf(f, ", t.F%d", j)
// }
// fmt.Fprintf(f, ")\n")
// fmt.Fprintf(f, "}\n")
// }
2023-07-13 17:34:13 +02:00
func TupleCommand ( ) * C . Command {
return & C . Command {
Name : "tuple" ,
Usage : "generate code for Tuple" ,
Flags : [ ] C . Flag {
flagCount ,
flagFilename ,
} ,
Action : func ( ctx * C . Context ) error {
return generateTupleHelpers (
ctx . String ( keyFilename ) ,
ctx . Int ( keyCount ) ,
)
} ,
}
}