gluamapper

package module
v0.0.0-...-04745e4 Latest Latest
Warning

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

Go to latest
Published: Dec 24, 2020 License: MIT Imports: 6 Imported by: 0

README

gluamapper: maps a GopherLua value to a Go value

Build Status codecov PkgGoDev

gluamapper provides an easy way to map GopherLua values to Go values.

Installation

go get github.com/jinq0123/gluamapper

API

See Go doc.

Usage

    type Role struct {
        Name string
    }

    type Person struct {
        Name      string
        Age       int
        WorkPlace string
        Role      []*Role
    }

    L := lua.NewState()
    if err := L.DoString(`
      person = {
        Name = "Michel",
        Age  = 31,
        WorkPlace = "San Jose",
        Role = {
          {
            Name = "Administrator"
          },
          {
            Name = "Operator"
          }
        }
      }
    `); err != nil {
        panic(err)
    }
    var person Person
    if err := gluamapper.Map(L.GetGlobal("person"), &person); err != nil {
        panic(err)
    }
    fmt.Printf("%s %d", person.Name, person.Age)

License

MIT

Author

  • Yusuke Inuzuka
  • Jin Qing

Differences from yuin/gluamapper

  • Speedup

    • Converts directly from Lua table to Go struct, while yuin/gluamapper converts the table to map[string]interface{}, and then converts it to a Go struct using mapstructure.
    • No "weak" conversions
      • returns error if types are different
      • only convert Lua number to int types
    • Always ignores unused keys
  • New feature

    • Maps Lua types other than table to Go types
    • Maps Lua user data to Go value
  • Bugfix

    • TODO: circular reference

TODO

  • handle embedded fields

Documentation

Overview

gluamapper provides an easy way to map GopherLua values to Go values.

Field Tags

When mapping to a struct, gluamapper will use the field name by default to perform the mapping. For example, if a struct has a field "Username" then gluamapper will look for a key in the Lua table of "Username". You can use struct tags to look for a different key name in the Lua table. See example Mapper (tagName)

Unexported fields

Since unexported (private) struct fields cannot be set outside the package where they are defined, gluamapper will simply skip them.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	OutputValueIsNilError = errors.New("output value is nil")
)

Functions

func Map

func Map(lv lua.LValue, output interface{}) error

Map maps the Lua value to the Go value pointed by output. If output is not a pointer, Map returns OutputIsNotAPointerError. If output is nil, Map returns OutputValueIsNilError. If the Lua value is nil, the Go value will be set to its zero value. Is the Lua value is a *lua.LUserData, the Go value will be set to the value of the LUserData if they are the same type, or TypeError will be returned if they are not the same type.

Map will allocate maps, slices, and pointers as necessary, with the following additional rules:

To map Lua value into a pointer, Map allocates a new value.

To map Lua table into a struct, Map matches incoming Lua table keys to the struct field name or its tag. Lua table keys which don't have a corresponding struct field are ignored.

To map Lua value into an interface value, Map stores one of these in the interface value:

bool, for Lua booleans
float64, for Lua numbers
string, for Lua strings
[]interface{}, for Lua arrays
map[string]interface{}, for Lua tables
nil for Lua nil

To map a Lua array into a slice, Map sets the slice len as Lua array len. If the slice capacity is not large enough, Map resets the slice to a new one

To map a Lua array into a Go array, Map maps Lua array elements into corresponding Go array elements. If the Go array is smaller than the Lua array, the additional Lua array elements are discarded. If the Lua array is smaller than the Go array, the additional Go array elements are set to zero values.

To map a Lua table into a map, Map first allocates a map to use if the old map is nil or not empty. Map then stores key-value pairs from the Lua table into the map. The Lua table's key-values are ignored if the Lua key can not be mapped into a Go key or the Lua value can not be mapped into a Go value

If tag name is needed, please use NewMapperWithTagName(tagName).Map(...)

Example
type Role struct {
	Name string
}

type Person struct {
	Name      string
	Age       int
	WorkPlace string
	Role      []*Role
}

L := lua.NewState()
if err := L.DoString(`
    person = {
      Name = "Michel",
      Age  = 31,
      WorkPlace = "San Jose",
      Role = {
        {
          Name = "Administrator"
        },
        {
          Name = "Operator"
        }
      }
    }
	`); err != nil {
	panic(err)
}
var person Person
if err := Map(L.GetGlobal("person"), &person); err != nil {
	panic(err)
}
fmt.Printf("%s %d", person.Name, person.Age)
Output:

Michel 31

Types

type Mapper

type Mapper struct {
	// A struct tag name for Lua table keys.
	TagName string
}

Mapper maps a Lua table to a Go struct pointer.

Example (TagName)
L := lua.NewState()
_ = L.DoString(`
		tbl = {
			UserName = "UserName",
			my_user_name = "my_user_name"
		}
	`)
type User struct {
	UserName string `mytag:"my_user_name"`
}

// Map will use the default field name
tbl := L.GetGlobal("tbl")
var output User
_ = Map(tbl, &output) // look for default key name
fmt.Printf("default UserName: %s\n", output.UserName)

// use tag mytag to get key name
_ = NewMapperWithTagName("mytag").Map(tbl, &output)
fmt.Printf("with tag name: %s\n", output.UserName)
Output:

default UserName: UserName
with tag name: my_user_name

func NewMapper

func NewMapper() *Mapper

NewMapper returns a new mapper.

func NewMapperWithTagName

func NewMapperWithTagName(tagName string) *Mapper

NewMapperWithTagName returns a new mapper with tag name.

func (*Mapper) Map

func (m *Mapper) Map(lv lua.LValue, output interface{}) error

Map maps the Lua value to the given Go pointer.

Example
L := lua.NewState()
if err := L.DoString(`
      person = {
        name = "Michel",
        age  = 31,
      }
    `); err != nil {
	panic(err)
}

// Person struct with json tag
type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}
var person Person
mapper := NewMapperWithTagName("json") // must use json tag name
if err := mapper.Map(L.GetGlobal("person"), &person); err != nil {
	panic(err)
}
fmt.Printf("%s %d", person.Name, person.Age)
Output:

Michel 31
Example (Map)
L := lua.NewState()
if err := L.DoString(`a = {a=1, b=2, c=3.3, d=true, [123]=123}`); err != nil {
	panic(err)
}

var output map[string]int
if err := NewMapper().Map(L.GetGlobal("a"), &output); err != nil {
	panic(err)
}
fmt.Printf("%v", output)
Output:

map[a:1 b:2 c:3]
Example (Slice)
L := lua.NewState()
if err := L.DoString(`a = {1, 2, 3.3}`); err != nil {
	panic(err)
}

var ints []int
if err := NewMapper().Map(L.GetGlobal("a"), &ints); err != nil {
	panic(err)
}
fmt.Printf("ints: %v\n", ints)

var floats []float32
if err := NewMapper().Map(L.GetGlobal("a"), &floats); err != nil {
	panic(err)
}
fmt.Printf("floats: %v\n", floats)
Output:

ints: [1 2 3]
floats: [1 2 3.3]

func (*Mapper) MapValue

func (m *Mapper) MapValue(lv lua.LValue, rv reflect.Value) error

MapValue maps the Lua value to Go value.

Example
L := lua.NewState()
if err := L.DoString(`
      person = {
        name = "Michel",
        age  = 31,
      }
    `); err != nil {
	panic(err)
}

// Person struct with json tag
type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}
var person Person
mapper := NewMapperWithTagName("json") // must use json tag name
rv := reflect.ValueOf(&person).Elem()
if err := mapper.MapValue(L.GetGlobal("person"), rv); err != nil {
	panic(err)
}
fmt.Printf("%s %d", person.Name, person.Age)
Output:

Michel 31

type OutputIsNotAPointerError

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

func (*OutputIsNotAPointerError) Error

func (o *OutputIsNotAPointerError) Error() string

type TypeError

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

func (*TypeError) Error

func (t *TypeError) Error() string

Jump to

Keyboard shortcuts

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