json.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package stdlib
  2. import (
  3. "bytes"
  4. gojson "encoding/json"
  5. "github.com/d5/tengo/v2"
  6. "github.com/d5/tengo/v2/stdlib/json"
  7. )
  8. var jsonModule = map[string]tengo.Object{
  9. "decode": &tengo.UserFunction{
  10. Name: "decode",
  11. Value: jsonDecode,
  12. },
  13. "encode": &tengo.UserFunction{
  14. Name: "encode",
  15. Value: jsonEncode,
  16. },
  17. "indent": &tengo.UserFunction{
  18. Name: "encode",
  19. Value: jsonIndent,
  20. },
  21. "html_escape": &tengo.UserFunction{
  22. Name: "html_escape",
  23. Value: jsonHTMLEscape,
  24. },
  25. }
  26. func jsonDecode(args ...tengo.Object) (ret tengo.Object, err error) {
  27. if len(args) != 1 {
  28. return nil, tengo.ErrWrongNumArguments
  29. }
  30. switch o := args[0].(type) {
  31. case *tengo.Bytes:
  32. v, err := json.Decode(o.Value)
  33. if err != nil {
  34. return &tengo.Error{
  35. Value: &tengo.String{Value: err.Error()},
  36. }, nil
  37. }
  38. return v, nil
  39. case *tengo.String:
  40. v, err := json.Decode([]byte(o.Value))
  41. if err != nil {
  42. return &tengo.Error{
  43. Value: &tengo.String{Value: err.Error()},
  44. }, nil
  45. }
  46. return v, nil
  47. default:
  48. return nil, tengo.ErrInvalidArgumentType{
  49. Name: "first",
  50. Expected: "bytes/string",
  51. Found: args[0].TypeName(),
  52. }
  53. }
  54. }
  55. func jsonEncode(args ...tengo.Object) (ret tengo.Object, err error) {
  56. if len(args) != 1 {
  57. return nil, tengo.ErrWrongNumArguments
  58. }
  59. b, err := json.Encode(args[0])
  60. if err != nil {
  61. return &tengo.Error{Value: &tengo.String{Value: err.Error()}}, nil
  62. }
  63. return &tengo.Bytes{Value: b}, nil
  64. }
  65. func jsonIndent(args ...tengo.Object) (ret tengo.Object, err error) {
  66. if len(args) != 3 {
  67. return nil, tengo.ErrWrongNumArguments
  68. }
  69. prefix, ok := tengo.ToString(args[1])
  70. if !ok {
  71. return nil, tengo.ErrInvalidArgumentType{
  72. Name: "prefix",
  73. Expected: "string(compatible)",
  74. Found: args[1].TypeName(),
  75. }
  76. }
  77. indent, ok := tengo.ToString(args[2])
  78. if !ok {
  79. return nil, tengo.ErrInvalidArgumentType{
  80. Name: "indent",
  81. Expected: "string(compatible)",
  82. Found: args[2].TypeName(),
  83. }
  84. }
  85. switch o := args[0].(type) {
  86. case *tengo.Bytes:
  87. var dst bytes.Buffer
  88. err := gojson.Indent(&dst, o.Value, prefix, indent)
  89. if err != nil {
  90. return &tengo.Error{
  91. Value: &tengo.String{Value: err.Error()},
  92. }, nil
  93. }
  94. return &tengo.Bytes{Value: dst.Bytes()}, nil
  95. case *tengo.String:
  96. var dst bytes.Buffer
  97. err := gojson.Indent(&dst, []byte(o.Value), prefix, indent)
  98. if err != nil {
  99. return &tengo.Error{
  100. Value: &tengo.String{Value: err.Error()},
  101. }, nil
  102. }
  103. return &tengo.Bytes{Value: dst.Bytes()}, nil
  104. default:
  105. return nil, tengo.ErrInvalidArgumentType{
  106. Name: "first",
  107. Expected: "bytes/string",
  108. Found: args[0].TypeName(),
  109. }
  110. }
  111. }
  112. func jsonHTMLEscape(args ...tengo.Object) (ret tengo.Object, err error) {
  113. if len(args) != 1 {
  114. return nil, tengo.ErrWrongNumArguments
  115. }
  116. switch o := args[0].(type) {
  117. case *tengo.Bytes:
  118. var dst bytes.Buffer
  119. gojson.HTMLEscape(&dst, o.Value)
  120. return &tengo.Bytes{Value: dst.Bytes()}, nil
  121. case *tengo.String:
  122. var dst bytes.Buffer
  123. gojson.HTMLEscape(&dst, []byte(o.Value))
  124. return &tengo.Bytes{Value: dst.Bytes()}, nil
  125. default:
  126. return nil, tengo.ErrInvalidArgumentType{
  127. Name: "first",
  128. Expected: "bytes/string",
  129. Found: args[0].TypeName(),
  130. }
  131. }
  132. }