...

Source file src/gitlab.hexacode.org/go-libs/hctypes/JSON.go

Documentation: gitlab.hexacode.org/go-libs/hctypes

     1  /*
     2   * Hexacode Types
     3   * Package: gitlab.hexacode.org/go-libs/hctypes
     4   * Maintainer: Azzis Arswendo <azzis@hexacode.org>
     5   *
     6   * Copyright (C) 2023 Hexacode Teknologi Indonesia
     7   * All Rights Reserved
     8   */
     9  
    10  package hctypes
    11  
    12  import (
    13  	"bytes"
    14  	"encoding/json"
    15  	"strings"
    16  
    17  	"github.com/TylerBrock/colorjson"
    18  )
    19  
    20  type Item interface{}
    21  type List []Item
    22  type Dict map[string]Item
    23  
    24  func (list List) GetString(i int) (String, bool) {
    25  	if len(list) <= i {
    26  		return "", false
    27  	}
    28  
    29  	val, ok := list[i].(String)
    30  	return val, ok
    31  }
    32  
    33  func (list List) GetDict(i int) (Dict, bool) {
    34  	if len(list) <= i {
    35  		return nil, false
    36  	}
    37  
    38  	val, ok := list[i].(Dict)
    39  	return val, ok
    40  }
    41  
    42  func (list List) GetList(i int) (List, bool) {
    43  	if len(list) <= i {
    44  		return nil, false
    45  	}
    46  
    47  	val, ok := list[i].(List)
    48  	return val, ok
    49  }
    50  
    51  func (list List) GetInt8(i int) (Int8, bool) {
    52  	if len(list) <= i {
    53  		return 0, false
    54  	}
    55  
    56  	val, ok := list[i].(Int8)
    57  	return val, ok
    58  }
    59  
    60  func (list List) GetInt16(i int) (Int16, bool) {
    61  	if len(list) <= i {
    62  		return 0, false
    63  	}
    64  
    65  	val, ok := list[i].(Int16)
    66  	return val, ok
    67  }
    68  
    69  func (list List) GetInt32(i int) (Int32, bool) {
    70  	if len(list) <= i {
    71  		return 0, false
    72  	}
    73  
    74  	val, ok := list[i].(Int32)
    75  	return val, ok
    76  }
    77  
    78  func (list List) GetInt64(i int) (Int64, bool) {
    79  	if len(list) <= i {
    80  		return 0, false
    81  	}
    82  
    83  	val, ok := list[i].(Int64)
    84  	return val, ok
    85  }
    86  
    87  func (list List) GetUInt8(i int) (UInt8, bool) {
    88  	if len(list) <= i {
    89  		return 0, false
    90  	}
    91  
    92  	val, ok := list[i].(UInt8)
    93  	return val, ok
    94  }
    95  
    96  func (list List) GetUInt16(i int) (UInt16, bool) {
    97  	if len(list) <= i {
    98  		return 0, false
    99  	}
   100  
   101  	val, ok := list[i].(UInt16)
   102  	return val, ok
   103  }
   104  
   105  func (list List) GetUInt32(i int) (UInt32, bool) {
   106  	if len(list) <= i {
   107  		return 0, false
   108  	}
   109  
   110  	val, ok := list[i].(UInt32)
   111  	return val, ok
   112  }
   113  
   114  func (list List) GetUInt64(i int) (UInt64, bool) {
   115  	if len(list) <= i {
   116  		return 0, false
   117  	}
   118  
   119  	val, ok := list[i].(UInt64)
   120  	return val, ok
   121  }
   122  
   123  func (list List) GetFloat32(i int) (Float32, bool) {
   124  	if len(list) <= i {
   125  		return 0, false
   126  	}
   127  
   128  	val, ok := list[i].(Float32)
   129  	return val, ok
   130  }
   131  
   132  func (list List) GetFloat64(i int) (Float64, bool) {
   133  	if len(list) <= i {
   134  		return 0, false
   135  	}
   136  
   137  	val, ok := list[i].(Float64)
   138  	return val, ok
   139  }
   140  
   141  func (list List) GetBool(i int) (Bool, bool) {
   142  	if len(list) <= i {
   143  		return false, false
   144  	}
   145  
   146  	val, ok := list[i].(Bool)
   147  	return val, ok
   148  }
   149  
   150  func (list List) IsNil(i int) bool {
   151  	if len(list) <= i {
   152  		return true
   153  	}
   154  
   155  	return list[i] == nil
   156  }
   157  
   158  func (dict Dict) GetString(key string) (String, bool) {
   159  	val, ok := dict.Copy()[key]
   160  	if !ok {
   161  		return "", false
   162  	}
   163  
   164  	if v, ok := val.(String); ok {
   165  		return v, true
   166  	}
   167  
   168  	return "", false
   169  }
   170  
   171  func (dict Dict) GetDict(key string) (Dict, bool) {
   172  	val, ok := dict.Copy()[key]
   173  	if !ok {
   174  		return nil, false
   175  	}
   176  
   177  	if v, ok := val.(Dict); ok {
   178  		return v, true
   179  	}
   180  
   181  	return nil, false
   182  }
   183  
   184  func (dict Dict) GetList(key string) (List, bool) {
   185  	val, ok := dict.Copy()[key]
   186  	if !ok {
   187  		return nil, false
   188  	}
   189  
   190  	if v, ok := val.(List); ok {
   191  		return v, true
   192  	}
   193  
   194  	return nil, false
   195  }
   196  
   197  func (dict Dict) GetInt8(key string) (Int8, bool) {
   198  	val, ok := dict.Copy()[key]
   199  	if !ok {
   200  		return 0, false
   201  	}
   202  
   203  	if v, ok := val.(Int8); ok {
   204  		return v, true
   205  	}
   206  
   207  	return 0, false
   208  }
   209  
   210  func (dict Dict) GetInt16(key string) (Int16, bool) {
   211  	val, ok := dict.Copy()[key]
   212  	if !ok {
   213  		return 0, false
   214  	}
   215  
   216  	if v, ok := val.(Int16); ok {
   217  		return v, true
   218  	}
   219  
   220  	return 0, false
   221  }
   222  
   223  func (dict Dict) GetInt32(key string) (Int32, bool) {
   224  	val, ok := dict.Copy()[key]
   225  	if !ok {
   226  		return 0, false
   227  	}
   228  
   229  	if v, ok := val.(Int32); ok {
   230  		return v, true
   231  	}
   232  
   233  	return 0, false
   234  }
   235  
   236  func (dict Dict) GetInt64(key string) (Int64, bool) {
   237  	val, ok := dict.Copy()[key]
   238  	if !ok {
   239  		return 0, false
   240  	}
   241  
   242  	if v, ok := val.(Int64); ok {
   243  		return v, true
   244  	}
   245  
   246  	return 0, false
   247  }
   248  
   249  func (dict Dict) GetUInt8(key string) (UInt8, bool) {
   250  	val, ok := dict.Copy()[key]
   251  	if !ok {
   252  		return 0, false
   253  	}
   254  
   255  	if v, ok := val.(UInt8); ok {
   256  		return v, true
   257  	}
   258  
   259  	return 0, false
   260  }
   261  
   262  func (dict Dict) GetUInt16(key string) (UInt16, bool) {
   263  	val, ok := dict.Copy()[key]
   264  	if !ok {
   265  		return 0, false
   266  	}
   267  
   268  	if v, ok := val.(UInt16); ok {
   269  		return v, true
   270  	}
   271  
   272  	return 0, false
   273  }
   274  
   275  func (dict Dict) GetUInt32(key string) (UInt32, bool) {
   276  	val, ok := dict.Copy()[key]
   277  	if !ok {
   278  		return 0, false
   279  	}
   280  
   281  	if v, ok := val.(UInt32); ok {
   282  		return v, true
   283  	}
   284  
   285  	return 0, false
   286  }
   287  
   288  func (dict Dict) GetUInt64(key string) (UInt64, bool) {
   289  	val, ok := dict.Copy()[key]
   290  	if !ok {
   291  		return 0, false
   292  	}
   293  
   294  	if v, ok := val.(UInt64); ok {
   295  		return v, true
   296  	}
   297  
   298  	return 0, false
   299  }
   300  
   301  func (dict Dict) GetFloat32(key string) (Float32, bool) {
   302  	val, ok := dict.Copy()[key]
   303  	if !ok {
   304  		return 0, false
   305  	}
   306  
   307  	if v, ok := val.(Float32); ok {
   308  		return v, true
   309  	}
   310  
   311  	return 0, false
   312  }
   313  
   314  func (dict Dict) GetFloat64(key string) (Float64, bool) {
   315  	val, ok := dict.Copy()[key]
   316  	if !ok {
   317  		return 0, false
   318  	}
   319  
   320  	if v, ok := val.(Float64); ok {
   321  		return v, true
   322  	}
   323  
   324  	return 0, false
   325  }
   326  
   327  func (dict Dict) GetBool(key string) (Bool, bool) {
   328  	val, ok := dict.Copy()[key]
   329  	if !ok {
   330  		return false, false
   331  	}
   332  
   333  	if v, ok := val.(Bool); ok {
   334  		return v, true
   335  	}
   336  
   337  	return false, false
   338  }
   339  
   340  func (dict Dict) IsNil(key string) bool {
   341  	val, ok := dict.Copy()[key]
   342  	if !ok {
   343  		return true
   344  	}
   345  
   346  	if val == nil {
   347  		return true
   348  	}
   349  
   350  	return false
   351  }
   352  
   353  func copyDict(m Dict) Dict {
   354  	cp := make(Dict)
   355  	for k, v := range m {
   356  		if dict, ok := v.(Dict); ok {
   357  			cp[k] = copyDict(dict)
   358  		} else {
   359  			if list, ok := v.(List); ok {
   360  				cp[k] = copyList(list)
   361  			} else {
   362  				cp[k] = v
   363  			}
   364  		}
   365  	}
   366  
   367  	return cp
   368  }
   369  
   370  func copyList(m List) List {
   371  	cp := make(List, len(m))
   372  	for k, v := range m {
   373  		if dict, ok := v.(Dict); ok {
   374  			cp[k] = copyDict(dict)
   375  		} else {
   376  			if list, ok := v.(List); ok {
   377  				cp[k] = copyList(list)
   378  			} else {
   379  				cp[k] = v
   380  			}
   381  		}
   382  	}
   383  
   384  	return cp
   385  }
   386  
   387  func NewDict() Dict {
   388  	return make(Dict)
   389  }
   390  
   391  func (this Dict) Copy() Dict {
   392  	return convert(copyDict(this)).(Dict)
   393  }
   394  
   395  func convert(item Item) Item {
   396  	switch i := item.(type) {
   397  	case map[string]interface{}:
   398  		ret := NewDict()
   399  		for k, v := range i {
   400  			ret[k] = convert(v)
   401  		}
   402  		return ret
   403  	case []interface{}:
   404  		ret := NewList()
   405  		for _, v := range i {
   406  			ret = ret.Append(convert(v))
   407  		}
   408  		return ret
   409  	case Dict:
   410  		ret := NewDict()
   411  		for k, v := range i {
   412  			ret[k] = convert(v)
   413  		}
   414  		return ret
   415  	case List:
   416  		ret := NewList()
   417  		for _, v := range i {
   418  			ret = ret.Append(convert(v))
   419  		}
   420  		return ret
   421  	case float64:
   422  		return Float64(i)
   423  	case string:
   424  		return String(i)
   425  	case bool:
   426  		return Bool(i)
   427  	default:
   428  		return item
   429  	}
   430  }
   431  
   432  func NewDictFromJson(data Buffer) Dict {
   433  	ret := make(Dict)
   434  	json.Unmarshal([]byte(data), &ret)
   435  	return convert(ret).(Dict)
   436  }
   437  
   438  func MarshalDict(src interface{}) (Dict, error) {
   439  	ret, err := json.Marshal(src)
   440  	if err != nil {
   441  		return nil, err
   442  	}
   443  
   444  	return NewDictFromJson(Buffer(ret)), nil
   445  }
   446  
   447  func (this Dict) ToJson() Buffer {
   448  	buf := &bytes.Buffer{}
   449  	encoder := json.NewEncoder(buf)
   450  	encoder.SetEscapeHTML(false)
   451  	err := encoder.Encode(this)
   452  	if err != nil {
   453  		return Buffer{}
   454  	}
   455  
   456  	strip := strings.Trim(string(buf.Bytes()), " \n\t")
   457  
   458  	return Buffer(strip)
   459  }
   460  
   461  func (this Dict) Keys() List {
   462  	ret := NewList()
   463  	for i := range this {
   464  		ret = ret.Append(String(i))
   465  	}
   466  
   467  	return ret
   468  }
   469  
   470  func (this Dict) ContainsKey(key String) bool {
   471  	v, exist := this[string(key)]
   472  	if exist && v == nil {
   473  		return false
   474  	}
   475  
   476  	return exist
   477  }
   478  
   479  func (this Dict) ContainsKeys(keys List) bool {
   480  	for _, i := range keys.Copy() {
   481  		switch v := i.(type) {
   482  		case String:
   483  			if !this.ContainsKey(v) {
   484  				return false
   485  			}
   486  
   487  		default:
   488  			return false
   489  		}
   490  	}
   491  
   492  	return true
   493  }
   494  
   495  func (this Dict) Unmarshal(src interface{}) error {
   496  	return json.Unmarshal([]byte(this.ToJson()), &src)
   497  }
   498  
   499  func (this Dict) String() string {
   500  	buf := &bytes.Buffer{}
   501  	encoder := json.NewEncoder(buf)
   502  	encoder.SetEscapeHTML(false)
   503  	encoder.SetIndent("", "  ")
   504  	err := encoder.Encode(this)
   505  	if err != nil {
   506  		return ""
   507  	}
   508  
   509  	strip := strings.Trim(string(buf.Bytes()), " \n\t")
   510  	return strip
   511  }
   512  
   513  func (this Dict) Equal(other Dict) bool {
   514  	return bool(this.ToJson().Equal(other.ToJson()))
   515  }
   516  
   517  func (this Dict) ToColoredJson() String {
   518  	return ColoredJSON(this.ToJson())
   519  }
   520  
   521  func NewList() List {
   522  	return List{}
   523  }
   524  
   525  func (this List) Copy() List {
   526  	return convert(copyList(this)).(List)
   527  }
   528  
   529  func MakeList(count int) List {
   530  	return make(List, count)
   531  }
   532  
   533  func NewListFromJson(data Buffer) List {
   534  	ret := List{}
   535  	json.Unmarshal([]byte(data), &ret)
   536  	return convert(ret).(List)
   537  }
   538  
   539  func MarshalList(src interface{}) (List, error) {
   540  	ret, err := json.Marshal(src)
   541  	if err != nil {
   542  		return nil, err
   543  	}
   544  
   545  	return NewListFromJson(Buffer(ret)), nil
   546  }
   547  
   548  func (this List) ToJson() Buffer {
   549  	buf := &bytes.Buffer{}
   550  	encoder := json.NewEncoder(buf)
   551  	encoder.SetEscapeHTML(false)
   552  	err := encoder.Encode(this)
   553  	if err != nil {
   554  		return Buffer{}
   555  	}
   556  
   557  	strip := strings.Trim(string(buf.Bytes()), " \n\t")
   558  
   559  	return Buffer(strip)
   560  }
   561  
   562  func (this List) ToColoredJson() String {
   563  	return ColoredJSON(this.ToJson())
   564  }
   565  
   566  func (this List) Append(item ...Item) List {
   567  	return append(this, item...)
   568  }
   569  
   570  func (this List) Unmarshal(src interface{}) error {
   571  	return json.Unmarshal([]byte(this.ToJson()), &src)
   572  }
   573  
   574  func (this List) String() string {
   575  	buf := &bytes.Buffer{}
   576  	encoder := json.NewEncoder(buf)
   577  	encoder.SetEscapeHTML(false)
   578  	encoder.SetIndent("", "  ")
   579  	err := encoder.Encode(this)
   580  	if err != nil {
   581  		return ""
   582  	}
   583  
   584  	strip := strings.Trim(string(buf.Bytes()), " \n\t")
   585  	return strip
   586  }
   587  
   588  func (this List) Equal(other List) bool {
   589  	return bool(this.ToJson().Equal(other.ToJson()))
   590  }
   591  
   592  func ColoredJSON(data Buffer) String {
   593  	var obj Item
   594  	json.Unmarshal([]byte(data), &obj)
   595  	f := colorjson.NewFormatter()
   596  	f.Indent = 4
   597  	s, err := f.Marshal(obj)
   598  	if err != nil {
   599  		panic(err)
   600  	}
   601  	return Buffer(s).ToString()
   602  }
   603  

View as plain text