lang.IndexTemplateObject()
(template API)Returns 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 timelang.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 Thu Aug 15 14:38:34 UTC 2024 against commit 50ed9d650ed9d6df391240d3c2c02e623636e508dfcdad1.
Current version is 6.2.4000 which has been verified against tests cases.