lang.ArrayWithTypeTemplate()
(template API)Unmarshals a data type into a Go struct and returns the results as an array with data type included
This is a template API you can use for your custom data types to wrap around an existing Go marshaller and return a Murex array which is consistent with other structures such as nested JSON or YAML documents.
It should only be called from ReadArrayWithType()
functions.
Because lang.ArrayTemplateWithType()
relies on a
marshaller, it means any types that rely on this API are not going to be
stream-able.
Example calling lang.ArrayTemplate()
function:
package json
import (
"context"
"github.com/lmorg/murex/lang"
"github.com/lmorg/murex/lang/stdio"
"github.com/lmorg/murex/utils/json"
)
func readArray(ctx context.Context, read stdio.Io, callback func([]byte)) error {
// Create a marshaller function to pass to ArrayTemplate
:= func(v interface{}) ([]byte, error) {
marshaller return json.Marshal(v, read.IsTTY())
}
return lang.ArrayTemplate(ctx, marshaller, json.Unmarshal, read, callback)
}
package lang
import (
"context"
"fmt"
"github.com/lmorg/murex/lang/stdio"
"github.com/lmorg/murex/lang/types"
"github.com/lmorg/murex/utils"
"github.com/lmorg/murex/utils/consts"
)
// ArrayWithTypeTemplate is a template function for reading arrays from marshalled data
func ArrayWithTypeTemplate(ctx context.Context, dataType string, marshal func(interface{}) ([]byte, error), unmarshal func([]byte, interface{}) error, read stdio.Io, callback func(interface{}, string)) error {
, err := read.ReadAll()
bif err != nil {
return err
}
if len(utils.CrLfTrim(b)) == 0 {
return nil
}
var v interface{}
= unmarshal(b, &v)
err
if err != nil {
return err
}
switch v := v.(type) {
case []interface{}:
return readArrayWithTypeBySliceInterface(ctx, dataType, marshal, v, callback)
case []string:
return readArrayWithTypeBySliceString(ctx, v, callback)
case []float64:
return readArrayWithTypeBySliceFloat(ctx, v, callback)
case []int:
return readArrayWithTypeBySliceInt(ctx, v, callback)
case []bool:
return readArrayWithTypeBySliceBool(ctx, v, callback)
case string:
return readArrayWithTypeByString(v, callback)
case []byte:
return readArrayWithTypeByString(string(v), callback)
case []rune:
return readArrayWithTypeByString(string(v), callback)
case map[string]string:
return readArrayWithTypeByMap(ctx, dataType, marshal, v, callback)
case map[string]interface{}:
return readArrayWithTypeByMap(ctx, dataType, marshal, v, callback)
case map[interface{}]string:
return readArrayWithTypeByMap(ctx, dataType, marshal, v, callback)
case map[interface{}]interface{}:
return readArrayWithTypeByMap(ctx, dataType, marshal, v, callback)
case map[int]string:
return readArrayWithTypeByMap(ctx, dataType, marshal, v, callback)
case map[int]interface{}:
return readArrayWithTypeByMap(ctx, dataType, marshal, v, callback)
case map[float64]string:
return readArrayWithTypeByMap(ctx, dataType, marshal, v, callback)
case map[float64]interface{}:
return readArrayWithTypeByMap(ctx, dataType, marshal, v, callback)
default:
return fmt.Errorf("cannot turn %T into an array\n%s", v, consts.IssueTrackerURL)
}
}
func readArrayWithTypeByString(v string, callback func(interface{}, string)) error {
(v, types.String)
callback
return nil
}
func readArrayWithTypeBySliceInt(ctx context.Context, v []int, callback func(interface{}, string)) error {
for i := range v {
select {
case <-ctx.Done():
return nil
default:
(v[i], types.Integer)
callback}
}
return nil
}
func readArrayWithTypeBySliceFloat(ctx context.Context, v []float64, callback func(interface{}, string)) error {
for i := range v {
select {
case <-ctx.Done():
return nil
default:
(v[i], types.Number)
callback}
}
return nil
}
func readArrayWithTypeBySliceBool(ctx context.Context, v []bool, callback func(interface{}, string)) error {
for i := range v {
select {
case <-ctx.Done():
return nil
default:
(v[i], types.Boolean)
callback
}
}
return nil
}
func readArrayWithTypeBySliceString(ctx context.Context, v []string, callback func(interface{}, string)) error {
for i := range v {
select {
case <-ctx.Done():
return nil
default:
(v[i], types.String)
callback}
}
return nil
}
func readArrayWithTypeBySliceInterface(ctx context.Context, dataType string, marshal func(interface{}) ([]byte, error), v []interface{}, callback func(interface{}, string)) error {
if len(v) == 0 {
return nil
}
for i := range v {
select {
case <-ctx.Done():
return nil
default:
switch v[i].(type) {
case string:
((v[i].(string)), types.String)
callback
case float64:
(v[i].(float64), types.Number)
callback
case int:
(v[i].(int), types.Integer)
callback
case bool:
if v[i].(bool) {
(true, types.Boolean)
callback} else {
(false, types.Boolean)
callback}
case []byte:
(string(v[i].([]byte)), types.String)
callback
case []rune:
(string(v[i].([]rune)), types.String)
callback
case nil:
(nil, types.Null)
callback
default:
, err := marshal(v[i])
jBytesif err != nil {
return err
}
(jBytes, dataType)
callback}
}
}
return nil
}
func readArrayWithTypeByMap[K comparable, V any](ctx context.Context, dataType string, marshal func(interface{}) ([]byte, error), v map[K]V, callback func(interface{}, string)) error {
for key, val := range v {
select {
case <-ctx.Done():
return nil
default:
:= map[K]any{key: val}
m , err := marshal(m)
bif err != nil {
return err
}
(string(b), dataType)
callback}
}
return nil
}
func(interface{}) ([]byte, error)
: data type’s
marshallerfunc([]byte, interface{}) error
: data type’s
unmarshallerstdio.Io
: stream to read from (eg stdin)func(interface{}, string)
: callback function to write
each array element, with data typeReadArray()
(type): Read from a data type one array element at a timeReadArrayWithType()
(type): Read from a data type one array element at a time and return
the elements contents and data typeReadIndex()
(type): Data type handler for the index, [
,
builtinReadMap()
(type):
Treat data type as a key/value structure and read its contentsReadNotIndex()
(type): Data type handler for the bang-prefixed index,
![
, builtinWriteArray()
(type): Write a data type, one array element at a timelang.IndexTemplateObject()
(template API): Returns element(s) from a data structurelang.IndexTemplateTable()
(template API): Returns element(s) from a tableThis document was generated from lang/stdio/interface_doc.yaml.
This site's content is rebuilt automatically from murex's source code after each merge to the master
branch. Downloadable murex binaries are also built with the website.
Last built on Wed Jan 15 23:07:50 UTC 2025 against commit b4c4296b4c429617fd41527ea0efef33c52c15ef2b64972.
Current version is 6.4.2063 (develop) which has been verified against tests cases.