mirror of https://github.com/open-feature/cli.git
145 lines
3.1 KiB
Go
145 lines
3.1 KiB
Go
package csharp
|
|
|
|
import (
|
|
_ "embed"
|
|
"fmt"
|
|
"maps"
|
|
"slices"
|
|
"strings"
|
|
"text/template"
|
|
|
|
"github.com/open-feature/cli/internal/flagset"
|
|
"github.com/open-feature/cli/internal/generators"
|
|
)
|
|
|
|
type CsharpGenerator struct {
|
|
generators.CommonGenerator
|
|
}
|
|
|
|
type Params struct {
|
|
// Add C# specific parameters here if needed
|
|
Namespace string
|
|
}
|
|
|
|
//go:embed csharp.tmpl
|
|
var csharpTmpl string
|
|
|
|
func openFeatureType(t flagset.FlagType) string {
|
|
switch t {
|
|
case flagset.IntType:
|
|
return "int"
|
|
case flagset.FloatType:
|
|
return "double" // .NET uses double, not float
|
|
case flagset.BoolType:
|
|
return "bool"
|
|
case flagset.StringType:
|
|
return "string"
|
|
case flagset.ObjectType:
|
|
return "object"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func formatDefaultValue(flag flagset.Flag) string {
|
|
switch flag.Type {
|
|
case flagset.StringType:
|
|
return fmt.Sprintf("\"%s\"", flag.DefaultValue)
|
|
case flagset.BoolType:
|
|
if flag.DefaultValue == true {
|
|
return "true"
|
|
}
|
|
return "false"
|
|
default:
|
|
return fmt.Sprintf("%v", flag.DefaultValue)
|
|
}
|
|
}
|
|
|
|
func toCSharpDict(value any) string {
|
|
assertedMap, ok := value.(map[string]any)
|
|
if !ok {
|
|
return "null"
|
|
}
|
|
|
|
keys := slices.Sorted(maps.Keys(assertedMap))
|
|
|
|
var builder strings.Builder
|
|
builder.WriteString("new Value(Structure.Builder()")
|
|
|
|
for _, key := range keys {
|
|
val := assertedMap[key]
|
|
|
|
builder.WriteString(fmt.Sprintf(".Set(%q, %s)", key, formatNestedValue(val)))
|
|
}
|
|
builder.WriteString(".Build())")
|
|
|
|
return builder.String()
|
|
}
|
|
|
|
func formatNestedValue(value any) string {
|
|
switch val := value.(type) {
|
|
case string:
|
|
flag := flagset.Flag{
|
|
Type: flagset.StringType,
|
|
DefaultValue: val,
|
|
}
|
|
return formatDefaultValue(flag)
|
|
case bool:
|
|
flag := flagset.Flag{
|
|
Type: flagset.BoolType,
|
|
DefaultValue: val,
|
|
}
|
|
return formatDefaultValue(flag)
|
|
case int, int64:
|
|
flag := flagset.Flag{
|
|
Type: flagset.IntType,
|
|
DefaultValue: val,
|
|
}
|
|
return formatDefaultValue(flag)
|
|
case float64:
|
|
flag := flagset.Flag{
|
|
Type: flagset.FloatType,
|
|
DefaultValue: val,
|
|
}
|
|
return formatDefaultValue(flag)
|
|
case map[string]any:
|
|
return toCSharpDict(val)
|
|
case []any:
|
|
var sliceBuilder strings.Builder
|
|
sliceBuilder.WriteString("new Value(new List<Value>{")
|
|
for index, elem := range val {
|
|
if index > 0 {
|
|
sliceBuilder.WriteString(", ")
|
|
}
|
|
|
|
sliceBuilder.WriteString(formatNestedValue(elem))
|
|
}
|
|
sliceBuilder.WriteString("})")
|
|
return sliceBuilder.String()
|
|
default:
|
|
return fmt.Sprintf("new Value(%s)", val)
|
|
}
|
|
}
|
|
|
|
func (g *CsharpGenerator) Generate(params *generators.Params[Params]) error {
|
|
funcs := template.FuncMap{
|
|
"OpenFeatureType": openFeatureType,
|
|
"FormatDefaultValue": formatDefaultValue,
|
|
"ToCSharpDict": toCSharpDict,
|
|
}
|
|
|
|
newParams := &generators.Params[any]{
|
|
OutputPath: params.OutputPath,
|
|
Custom: params.Custom,
|
|
}
|
|
|
|
return g.GenerateFile(funcs, csharpTmpl, newParams, "OpenFeature.g.cs")
|
|
}
|
|
|
|
// NewGenerator creates a generator for C#.
|
|
func NewGenerator(fs *flagset.Flagset) *CsharpGenerator {
|
|
return &CsharpGenerator{
|
|
CommonGenerator: *generators.NewGenerator(fs, map[flagset.FlagType]bool{}),
|
|
}
|
|
}
|