/* * Hexacode Types * Package: gitlab.hexacode.org/go-libs/hctypes * Maintainer: Azzis Arswendo * * Copyright (C) 2023 Hexacode Teknologi Indonesia * All Rights Reserved */ package hctypes import ( "bytes" "encoding/json" "strings" "github.com/TylerBrock/colorjson" ) type Item interface{} type List []Item type Dict map[string]Item func (list List) GetString(i int) (String, bool) { if len(list) <= i { return "", false } val, ok := list[i].(String) return val, ok } func (list List) GetDict(i int) (Dict, bool) { if len(list) <= i { return nil, false } val, ok := list[i].(Dict) return val, ok } func (list List) GetList(i int) (List, bool) { if len(list) <= i { return nil, false } val, ok := list[i].(List) return val, ok } func (list List) GetInt8(i int) (Int8, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(Int8) return val, ok } func (list List) GetInt16(i int) (Int16, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(Int16) return val, ok } func (list List) GetInt32(i int) (Int32, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(Int32) return val, ok } func (list List) GetInt64(i int) (Int64, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(Int64) return val, ok } func (list List) GetUInt8(i int) (UInt8, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(UInt8) return val, ok } func (list List) GetUInt16(i int) (UInt16, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(UInt16) return val, ok } func (list List) GetUInt32(i int) (UInt32, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(UInt32) return val, ok } func (list List) GetUInt64(i int) (UInt64, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(UInt64) return val, ok } func (list List) GetFloat32(i int) (Float32, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(Float32) return val, ok } func (list List) GetFloat64(i int) (Float64, bool) { if len(list) <= i { return 0, false } val, ok := list[i].(Float64) return val, ok } func (list List) GetBool(i int) (Bool, bool) { if len(list) <= i { return false, false } val, ok := list[i].(Bool) return val, ok } func (list List) IsNil(i int) bool { if len(list) <= i { return true } return list[i] == nil } func (dict Dict) GetString(key string) (String, bool) { val, ok := dict.Copy()[key] if !ok { return "", false } if v, ok := val.(String); ok { return v, true } return "", false } func (dict Dict) GetDict(key string) (Dict, bool) { val, ok := dict.Copy()[key] if !ok { return nil, false } if v, ok := val.(Dict); ok { return v, true } return nil, false } func (dict Dict) GetList(key string) (List, bool) { val, ok := dict.Copy()[key] if !ok { return nil, false } if v, ok := val.(List); ok { return v, true } return nil, false } func (dict Dict) GetInt8(key string) (Int8, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(Int8); ok { return v, true } return 0, false } func (dict Dict) GetInt16(key string) (Int16, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(Int16); ok { return v, true } return 0, false } func (dict Dict) GetInt32(key string) (Int32, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(Int32); ok { return v, true } return 0, false } func (dict Dict) GetInt64(key string) (Int64, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(Int64); ok { return v, true } return 0, false } func (dict Dict) GetUInt8(key string) (UInt8, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(UInt8); ok { return v, true } return 0, false } func (dict Dict) GetUInt16(key string) (UInt16, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(UInt16); ok { return v, true } return 0, false } func (dict Dict) GetUInt32(key string) (UInt32, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(UInt32); ok { return v, true } return 0, false } func (dict Dict) GetUInt64(key string) (UInt64, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(UInt64); ok { return v, true } return 0, false } func (dict Dict) GetFloat32(key string) (Float32, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(Float32); ok { return v, true } return 0, false } func (dict Dict) GetFloat64(key string) (Float64, bool) { val, ok := dict.Copy()[key] if !ok { return 0, false } if v, ok := val.(Float64); ok { return v, true } return 0, false } func (dict Dict) GetBool(key string) (Bool, bool) { val, ok := dict.Copy()[key] if !ok { return false, false } if v, ok := val.(Bool); ok { return v, true } return false, false } func (dict Dict) IsNil(key string) bool { val, ok := dict.Copy()[key] if !ok { return true } if val == nil { return true } return false } func copyDict(m Dict) Dict { cp := make(Dict) for k, v := range m { if dict, ok := v.(Dict); ok { cp[k] = copyDict(dict) } else { if list, ok := v.(List); ok { cp[k] = copyList(list) } else { cp[k] = v } } } return cp } func copyList(m List) List { cp := make(List, len(m)) for k, v := range m { if dict, ok := v.(Dict); ok { cp[k] = copyDict(dict) } else { if list, ok := v.(List); ok { cp[k] = copyList(list) } else { cp[k] = v } } } return cp } func NewDict() Dict { return make(Dict) } func (this Dict) Copy() Dict { return convert(copyDict(this)).(Dict) } func convert(item Item) Item { switch i := item.(type) { case map[string]interface{}: ret := NewDict() for k, v := range i { ret[k] = convert(v) } return ret case []interface{}: ret := NewList() for _, v := range i { ret = ret.Append(convert(v)) } return ret case Dict: ret := NewDict() for k, v := range i { ret[k] = convert(v) } return ret case List: ret := NewList() for _, v := range i { ret = ret.Append(convert(v)) } return ret case float64: return Float64(i) case string: return String(i) case bool: return Bool(i) default: return item } } func NewDictFromJson(data Buffer) Dict { ret := make(Dict) json.Unmarshal([]byte(data), &ret) return convert(ret).(Dict) } func MarshalDict(src interface{}) (Dict, error) { ret, err := json.Marshal(src) if err != nil { return nil, err } return NewDictFromJson(Buffer(ret)), nil } func (this Dict) ToJson() Buffer { buf := &bytes.Buffer{} encoder := json.NewEncoder(buf) encoder.SetEscapeHTML(false) err := encoder.Encode(this) if err != nil { return Buffer{} } strip := strings.Trim(string(buf.Bytes()), " \n\t") return Buffer(strip) } func (this Dict) Keys() List { ret := NewList() for i := range this { ret = ret.Append(String(i)) } return ret } func (this Dict) ContainsKey(key String) bool { v, exist := this[string(key)] if exist && v == nil { return false } return exist } func (this Dict) ContainsKeys(keys List) bool { for _, i := range keys.Copy() { switch v := i.(type) { case String: if !this.ContainsKey(v) { return false } default: return false } } return true } func (this Dict) Unmarshal(src interface{}) error { return json.Unmarshal([]byte(this.ToJson()), &src) } func (this Dict) String() string { buf := &bytes.Buffer{} encoder := json.NewEncoder(buf) encoder.SetEscapeHTML(false) encoder.SetIndent("", " ") err := encoder.Encode(this) if err != nil { return "" } strip := strings.Trim(string(buf.Bytes()), " \n\t") return strip } func (this Dict) Equal(other Dict) bool { return bool(this.ToJson().Equal(other.ToJson())) } func (this Dict) ToColoredJson() String { return ColoredJSON(this.ToJson()) } func NewList() List { return List{} } func (this List) Copy() List { return convert(copyList(this)).(List) } func MakeList(count int) List { return make(List, count) } func NewListFromJson(data Buffer) List { ret := List{} json.Unmarshal([]byte(data), &ret) return convert(ret).(List) } func MarshalList(src interface{}) (List, error) { ret, err := json.Marshal(src) if err != nil { return nil, err } return NewListFromJson(Buffer(ret)), nil } func (this List) ToJson() Buffer { buf := &bytes.Buffer{} encoder := json.NewEncoder(buf) encoder.SetEscapeHTML(false) err := encoder.Encode(this) if err != nil { return Buffer{} } strip := strings.Trim(string(buf.Bytes()), " \n\t") return Buffer(strip) } func (this List) ToColoredJson() String { return ColoredJSON(this.ToJson()) } func (this List) Append(item ...Item) List { return append(this, item...) } func (this List) Unmarshal(src interface{}) error { return json.Unmarshal([]byte(this.ToJson()), &src) } func (this List) String() string { buf := &bytes.Buffer{} encoder := json.NewEncoder(buf) encoder.SetEscapeHTML(false) encoder.SetIndent("", " ") err := encoder.Encode(this) if err != nil { return "" } strip := strings.Trim(string(buf.Bytes()), " \n\t") return strip } func (this List) Equal(other List) bool { return bool(this.ToJson().Equal(other.ToJson())) } func ColoredJSON(data Buffer) String { var obj Item json.Unmarshal([]byte(data), &obj) f := colorjson.NewFormatter() f.Indent = 4 s, err := f.Marshal(obj) if err != nil { panic(err) } return Buffer(s).ToString() }