github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/actions/lua/encoding/json/json.go (about) 1 package json 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "reflect" 7 8 "github.com/Shopify/go-lua" 9 "github.com/treeverse/lakefs/pkg/actions/lua/util" 10 ) 11 12 func Open(l *lua.State) { 13 jsonOpen := func(l *lua.State) int { 14 lua.NewLibrary(l, jsonLibrary) 15 return 1 16 } 17 lua.Require(l, "encoding/json", jsonOpen, false) 18 l.Pop(1) 19 } 20 21 var jsonLibrary = []lua.RegistryFunction{ 22 {Name: "marshal", Function: jsonMarshal}, 23 {Name: "unmarshal", Function: jsonUnmarshal}, 24 } 25 26 func check(l *lua.State, err error) { 27 if err != nil { 28 lua.Errorf(l, "%s", err.Error()) 29 panic("unreachable") 30 } 31 } 32 33 func jsonMarshal(l *lua.State) int { 34 var t interface{} 35 var ot interface{} 36 var err error 37 if !l.IsNil(1) { 38 t, err = util.PullTable(l, 1) 39 check(l, err) 40 } 41 if !l.IsNoneOrNil(2) { // Options table 42 ot, err = util.PullTable(l, 2) 43 check(l, err) 44 } 45 var buf bytes.Buffer 46 e := json.NewEncoder(&buf) 47 var rot map[string]any 48 if ot != nil { 49 vot := reflect.ValueOf(ot) 50 rot = vot.Interface().(map[string]any) 51 } 52 if rot != nil { 53 pre, ind := fetchIndentProps(rot) 54 e.SetIndent(pre, ind) 55 } 56 err = e.Encode(t) 57 check(l, err) 58 l.PushString(buf.String()) 59 return 1 60 } 61 62 func fetchIndentProps(rot map[string]any) (string, string) { 63 prefix := "" 64 indent := "" 65 if p, ok := rot["prefix"]; ok { 66 prefix = p.(string) 67 } 68 if i, ok := rot["indent"]; ok { 69 indent = i.(string) 70 } 71 return prefix, indent 72 } 73 74 func jsonUnmarshal(l *lua.State) int { 75 payload := lua.CheckString(l, 1) 76 var output interface{} 77 check(l, json.Unmarshal([]byte(payload), &output)) 78 return util.DeepPush(l, output) 79 }