startype

package module
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 14, 2023 License: MIT Imports: 5 Imported by: 0

README

Startype 🤩

Startype makes it easy to automatically convert (two-way) between Go types and Starlark-Go API types.

Features

  • Two-way conversion between Go and Starlark-Go types
  • Two-way conversion for primitive types like bool, integer, float, and string types
  • Convert Go slice, array, map, and struct types to compatible Starlark types
  • Convert Starlark Dict, StringDict, List, Set, and StarlarkStruct to compatible Go types
  • Map Starlark keyword args (from built-in functions) to Go struct values
  • Support for type pointers and and empty interface (any) types

Examples

Convert Go value to Starlark value

The following converts a Go struct to a (comptible) *starlarkstruct.Struct value:

func main() {
    data := struct {
		Name  string
		Count int
	}{
		Name:  "test",
		Count: 24,
	}

	var star starlarkstruct.Struct
	if err := startype.Go(data).Starlark(&star); err != nil {
		log.Fatal(err)
	}

	nameVal, err := star.Attr("name")
	if err != nil {
		log.Fatal(err)
	}
	if nameVal.String() != `"test"` {
		log.Fatal("unexpected attr name value: %s", nameVal.String())
	}
}
Convert Starlark value to Go value

Startype can easily convert a Starlark-API value into a standard Go value. The following converts a starlark.Dict dictionary value to a Go map[string]string value.

func main() {
    dict := starlark.NewDict(2)
    dict.SetKey(starlark.String("msg0"), starlark.String("Hello"))
    dict.SetKey(starlark.String("msg1"), starlark.String("World!"))

    gomap := make(map[string]string)
    if err := startype.Starlark(val).Go(&gomap); err != nil {
        log.Fatalf("failed to convert starlark to go value: %s", err)
    }
	
    if gomap["msg0"] != "Hello" {
        log.Fatalf("unexpected map[msg] value: %v", gomap["msg"])
    }
    if gomap["msg1"] != "World!" {
        log.Fatalf("unexpected map[msg] value: %v", gomap["msg"])
    }
}
Use struct annotations to control conversion

Startype supports struct annotations to describe field names to target during conversion. For instance, the following example uses the provided struct tags when creating Starlark-Go values.

func main() {
    data := struct {
		Name  string `name:"msg0"`
		Count int    `name:"msg1"`
	}{
		Name:  "test",
		Count: 24,
	}

	star := make.Struct
	if err := startype.Go(data).Starlark(&star); err != nil {
		t.Fatal(err)
	}

    // starlark struct field created with annotated name
    nameVal, err := star.Attr("msg0")
	if err != nil {
		t.Fatal(err)
	}
	if nameVal.String() != `"test"` {
		t.Errorf("unexpected attr name value: %s", nameVal.String())
	}
}

Similarly, Startype can use struct tags to copy Starlark-API Go values during conversion to Go values, as shown below:

func main() {
    dict := starlark.StringDict{
        "mymsg0": starlark.String("Hello"),
        "mymsg1": starlark.String("World!"),
    }
    star := starlarkstruct.FromStringDict(starlark.String("struct"), dict)
    
    var godata struct {
        Salutation string   `name:"mymsg0"`
        Message string      `name:"mymsg1"`
	}

	if err := Starlark(&star).Go(&goData); err != nil {
		t.Errorf("conversion failed: %s", err)
	}

	if godata.Message != "World!" {
		log.Errorf("unexpected go struct field value: %s", godata.Message)
	}
}

Starlark keyword argument processing

Startype makes it easy to capture and process Starlark keyword arguments (passed as tuples in built-in functions) by automatically map the provided arguments to a Go struct value. For instance, the following maps kwargs (a stand in for a actual keyword arguments) to Go struct args:


func main() {
    kwargs := []starlark.Tuple{
        {starlark.String("msg"), starlark.String("hello")},
        {starlark.String("cnt"), starlark.MakeInt(32)},
    }
    var args struct {
        Message string   `name:"msg"`
        Count int64      `name:"cnt"`
    }
	if err := startype.Kwargs(kwargs).Go(&val); err != nil {
		t.Fatal(err)
	}

    fmt.Printl(args.Message) // prints hello
}

An argument can be marked as optional to avoid error if it is not provided. For instance, if argument cnt is not provided in the kwargs tuple, function KwargsToGo will not report an error.


func main() {
    kwargs := []starlark.Tuple{
        {starlark.String("msg"), starlark.String("hello")},
    }
    var args struct {
        Message string   `name:"msg"`
        Count int64      `name:"cnt optional:true"`
    }
	if err := startype.Kwargs(kwargs).Go(&val); err != nil {
		t.Fatal(err)
	}

    fmt.Printl(args.Message) // prints hello
}

For additional conversion examples, see the test functions in the test files.

Documentation

Overview

Package startype provides type conversion, and other utilities, between Go types and Starlark types.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GoStructToStringDict

func GoStructToStringDict(gostruct interface{}) (starlark.StringDict, error)

GoStructToStringDict is a helper func that converts a Go struct type to starlark.StringDict.

Types

type GoValue

type GoValue struct {
	// contains filtered or unexported fields
}

GoValue represents an inherent Go value which can be converted to a Starlark value/type

func Go

func Go(val interface{}) *GoValue

Go wraps a Go value into GoValue so that it can be converted to a Starlark value.

func (*GoValue) Starlark

func (v *GoValue) Starlark(starval interface{}) error

Starlark translates Go value to a starlark.Value value using the following type mapping:

bool                -- starlark.Bool
int{8,16,32,64}     -- starlark.Int
uint{8,16,32,64}    -- starlark.Int
float{32,64}        -- starlark.Float
string              -- starlark.String
[]T, [n]T           -- starlark.Tuple
map[K]T	            -- *starlark.Dict

The specified Starlark value must be provided as a pointer to the target Starlark type.

Example:

num := 64
var starInt starlark.Int
Go(num).Starlark(&starInt)

For starlark.List and starlark.Set refer to their respective namesake methods.

func (*GoValue) StarlarkList

func (v *GoValue) StarlarkList(starval interface{}) error

StarlarkList converts a slice of Go values to a starlark.Tuple, then converts that tuple into a starlark.List

func (*GoValue) StarlarkSet

func (v *GoValue) StarlarkSet(starval interface{}) error

StarlarkSet converts a slice of Go values to a starlark.Tuple, then converts that tuple into a starlark.Set

func (*GoValue) Value

func (v *GoValue) Value() interface{}

Value returns the original Go value as an interface{}

type KwargsValue added in v0.0.2

type KwargsValue struct {
	// contains filtered or unexported fields
}

func Kwargs added in v0.0.2

func Kwargs(kwargs []starlark.Tuple) *KwargsValue

Kwargs starts the conversion of a Starlark kwargs (keyword args) value to a Go struct. The function uses annotated fields on the struct to describe the keyword argument mapping as:

var Param struct {
    OutputFile  string   `name:"output_file" optional:"true"`
    SourcePaths []string `name:"output_path"`
}

The struct can be mapped to the following keyword args:

kwargs := []starlark.Tuple{
   {starlark.String("output_file"), starlark.String("/tmp/out.tar.gz")},
   {starlark.String("source_paths"), starlark.NewList([]starlark.Value{starlark.String("/tmp/myfile")})},
}

Example

Kwargs(kwargs).Go(&Param)

Supported annotation: `name:"arg_name" required:"true|false" (default false)`

func (*KwargsValue) Go added in v0.0.2

func (v *KwargsValue) Go(gostruct any) error

type StarValue

type StarValue struct {
	// contains filtered or unexported fields
}

func Starlark

func Starlark(val starlark.Value) *StarValue

Starlark wraps a Starlark value val so it can be converted to a Go value.

func (*StarValue) Go

func (v *StarValue) Go(goin interface{}) error

func (*StarValue) Value

func (v *StarValue) Value() starlark.Value

Value returns the wrapped Starlark value

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL