lang.IndexTemplateObject()
(template API) - API ReferenceReturns element(s) from a data structure
This is a template API you can use for your custom data types.
It should only be called from ReadIndex()
and ReadNotIndex()
functions.
This function ensures consistency with the index, [
, builtin when used with different Murex data types. Thus making indexing a data type agnostic capability.
Example calling lang.IndexTemplateObject()
function:
package json
import (
"github.com/lmorg/murex/lang"
"github.com/lmorg/murex/utils/json"
)
func index(p *lang.Process, params []string) error {
var jInterface interface{}
b, err := p.Stdin.ReadAll()if err != nil {
return err
}
err = json.Unmarshal(b, &jInterface)if err != nil {
return err
}
func(iface interface{}) ([]byte, error) {
marshaller := return json.Marshal(iface, p.Stdout.IsTTY())
}
return lang.IndexTemplateObject(p, params, &jInterface, marshaller)
}
package lang
import (
"errors"
"fmt"
"strconv"
"strings"
"github.com/lmorg/murex/lang/types"
)
// IndexTemplateObject is a handy standard indexer you can use in your custom data types for structured object types.
// The point of this is to minimize code rewriting and standardising the behavior of the indexer.
func IndexTemplateObject(p *Process, params []string, object *interface{}, marshaller func(interface{}) ([]byte, error)) error {
if p.IsNot {
return itoNot(p, params, object, marshaller)
}return itoIndex(p, params, object, marshaller)
}
// itoIndex allow
func itoIndex(p *Process, params []string, object *interface{}, marshaller func(interface{}) ([]byte, error)) error {
var objArray []interface{}
switch v := (*object).(type) {
case []interface{}:
for _, key := range params {
i, err := strconv.Atoi(key)if err != nil {
return err
}if i < 0 {
//i = len(v) + i
len(v)
i +=
}if i >= len(v) {
return errors.New("key '" + key + "' greater than number of items in array")
}
if len(params) > 1 {
append(objArray, v[i])
objArray =
else {
} switch v[i].(type) {
case nil:
p.Stdout.SetDataType(types.Null)case bool:
p.Stdout.SetDataType(types.Boolean)if v[i].(bool) {
p.Stdout.Write(types.TrueByte)else {
}
p.Stdout.Write(types.FalseByte)
}case int:
p.Stdout.SetDataType(types.Integer)int))
s := strconv.Itoa(v[i].(byte(s))
p.Stdout.Write([]case float64:
p.Stdout.SetDataType(types.Number)float64))
s := types.FloatToString(v[i].(byte(s))
p.Stdout.Write([]case string:
p.Stdout.SetDataType(types.String)byte(v[i].(string)))
p.Stdout.Write([]default:
b, err := marshaller(v[i])if err != nil {
return err
}
p.Stdout.Writeln(b)
}
}
}if len(objArray) > 0 {
b, err := marshaller(objArray)if err != nil {
return err
}
p.Stdout.Writeln(b)
}return nil
case map[string]interface{}:
var (
interface{}
obj error
err
)
for i := range params {
if len(params[i]) > 2 && params[i][0] == '[' && params[i][len(params[i])-1] == ']' {
1:len(params[i])-1])
obj, err = ElementLookup(v, params[i][if err != nil {
return err
}
else {
}
switch {
case v[params[i]] != nil:
obj = v[params[i]]case v[strings.Title(params[i])] != nil:
obj = v[strings.Title(params[i])]case v[strings.ToLower(params[i])] != nil:
obj = v[strings.ToLower(params[i])]case v[strings.ToUpper(params[i])] != nil:
obj = v[strings.ToUpper(params[i])]default:
return errors.New("key '" + params[i] + "' not found")
}
}
if len(params) > 1 {
append(objArray, obj)
objArray =
else {
} switch obj := obj.(type) {
case nil:
p.Stdout.SetDataType(types.Null)case bool:
p.Stdout.SetDataType(types.Boolean)if obj {
p.Stdout.Write(types.TrueByte)else {
}
p.Stdout.Write(types.FalseByte)
}case int:
p.Stdout.SetDataType(types.Integer)
s := strconv.Itoa(obj)byte(s))
p.Stdout.Write([]case float64:
p.Stdout.SetDataType(types.Number)
s := types.FloatToString(obj)byte(s))
p.Stdout.Write([]case string:
p.Stdout.SetDataType(types.String)byte(obj))
p.Stdout.Write([]default:
b, err := marshaller(obj)if err != nil {
return err
}
p.Stdout.Writeln(b)
}
}
}if len(objArray) > 0 {
b, err := marshaller(objArray)if err != nil {
return err
}
p.Stdout.Writeln(b)
}return nil
case map[interface{}]interface{}:
for i := range params {
//if v[key] == nil {
// return errors.New("key '" + key + "' not found.")
//}
switch {
case v[params[i]] != nil:
case v[strings.Title(params[i])] != nil:
params[i] = strings.Title(params[i])case v[strings.ToLower(params[i])] != nil:
params[i] = strings.ToLower(params[i])case v[strings.ToUpper(params[i])] != nil:
params[i] = strings.ToUpper(params[i])//case v[strings.ToTitle(params[i])] != nil:
// params[i] = strings.ToTitle(params[i])
default:
return errors.New("key '" + params[i] + "' not found")
}
if len(params) > 1 {
append(objArray, v[params[i]])
objArray =
else {
} switch v[params[i]].(type) {
case nil:
p.Stdout.SetDataType(types.Null)case bool:
p.Stdout.SetDataType(types.Boolean)if v[params[i]].(bool) {
p.Stdout.Write(types.TrueByte)else {
}
p.Stdout.Write(types.FalseByte)
}case int:
p.Stdout.SetDataType(types.Integer)int))
s := strconv.Itoa(v[params[i]].(byte(s))
p.Stdout.Write([]case float64:
p.Stdout.SetDataType(types.Number)float64))
s := types.FloatToString(v[params[i]].(byte(s))
p.Stdout.Write([]case string:
p.Stdout.SetDataType(types.String)byte(v[params[i]].(string)))
p.Stdout.Write([]default:
b, err := marshaller(v[params[i]])if err != nil {
return err
}
p.Stdout.Writeln(b)
}
}
}if len(objArray) > 0 {
b, err := marshaller(objArray)if err != nil {
return err
}
p.Stdout.Writeln(b)
}return nil
default:
return errors.New("object cannot be indexed")
}
}
// itoNot requires the indexes to be explicit
func itoNot(p *Process, params []string, object *interface{}, marshaller func(interface{}) ([]byte, error)) error {
switch v := (*object).(type) {
case []interface{}:
var objArray []interface{}
make(map[int]bool)
not := for _, key := range params {
i, err := strconv.Atoi(key)if err != nil {
return err
}if i < 0 {
return errors.New("cannot have negative keys in array")
}if i >= len(v) {
return errors.New("Key '" + key + "' greater than number of items in array")
}
true
not[i] =
}
for i := range v {
if !not[i] {
append(objArray, v[i])
objArray =
}
}
//if len(objArray) > 0 {
b, err := marshaller(objArray)if err != nil {
return err
}
_, err = p.Stdout.Writeln(b)//}
return err
case map[string]interface{}:
make(map[string]interface{})
objMap := make(map[string]bool)
not := for _, key := range params {
true
not[key] = true
not[strings.Title(key)] = true
not[strings.ToLower(key)] = true
not[strings.ToUpper(key)] = //not[strings.ToTitle(key)] = true
}
for s := range v {
if !not[s] {
objMap[s] = v[s]
}
}
//if len(objMap) > 0 {
b, err := marshaller(objMap)if err != nil {
return err
}
p.Stdout.Writeln(b)//}
return nil
case map[interface{}]interface{}:
make(map[interface{}]interface{})
objMap := make(map[string]bool)
not := for _, key := range params {
true
not[key] = true
not[strings.Title(key)] = true
not[strings.ToLower(key)] = true
not[strings.ToUpper(key)] = //not[strings.ToTitle(key)] = true
}
for iface := range v {
s := fmt.Sprint(iface)if !not[s] {
objMap[iface] = v[iface]
}
}
//if len(objMap) > 0 {
b, err := marshaller(objMap)if err != nil {
return err
}
_, err = p.Stdout.Writeln(b)//}
return err
default:
return errors.New("object cannot be !indexed")
} }
*lang.Process
: Process’s runtime state. Typically expressed as the variable p
[]string
: slice of parameters used in [
/ ![
*interface{}
: a pointer to the data structure being indexedfunc(interface{}) ([]byte, error)
: data type marshaller functionReadArray()
(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 time[
(index): Outputs an element from an array, map or tablelang.IndexTemplateTable()
(template API): Returns element(s) from a tableThis 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 Fri May 19 22:45:48 UTC 2023 against commit 54b5f6754b5f67b250bbf7353e83c42ed187802584c3ae3.
Current version is 4.1.6140 which has been verified against 14045 tests cases.