Skip to content

Commit

Permalink
Merge pull request #82 from nofun97/json-func
Browse files Browse the repository at this point in the history
JSON to arrai object
  • Loading branch information
nofun97 authored Mar 29, 2020
2 parents 51d98e0 + 20d5e21 commit 53b734c
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 23 deletions.
1 change: 1 addition & 0 deletions syntax/std.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func stdScope() rel.Scope {
stdStr(),
stdEval(),
stdOs(),
stdJSON(),
))
})
return stdScopeVar
Expand Down
26 changes: 26 additions & 0 deletions syntax/std_json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package syntax

import (
"encoding/json"

"github.com/arr-ai/arrai/rel"
"github.com/arr-ai/arrai/translate"
)

func stdJSON() rel.Attr {
return rel.NewTupleAttr(
"json",
rel.NewNativeFunctionAttr("decode", func(v rel.Value) rel.Value {
s := mustAsString(v)
var data interface{}
var err error
if err = json.Unmarshal([]byte(s), &data); err == nil {
var d rel.Value
if d, err = translate.JSONToArrai(data); err == nil {
return d
}
}
panic(err)
}),
)
}
42 changes: 42 additions & 0 deletions syntax/std_json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package syntax

import "testing"

func TestJSONDecode(t *testing.T) {
t.Parallel()
AssertCodePanics(t, `//.json.decode(123)`)
AssertCodesEvalToSameValue(t,
`{
"a": (s: "string"),
"b": 123,
"c": 123.321,
"d": (a: [1, (s: "string again"), (a: []), {}]),
"e": {
"f": {
"g": (s: "321")
},
"h": (a: [])
},
"i": (null: {}),
"j": (a: [(b: {()}), (b: {})]),
"k": (s: {})
}`,
`//.json.decode(
'{
"a": "string",
"b": 123,
"c": 123.321,
"d": [1, "string again", [], {}],
"e": {
"f": {
"g": "321"
},
"h": []
},
"i": null,
"j": [true, false],
"k": ""
}'
)`,
)
}
2 changes: 1 addition & 1 deletion syntax/std_str.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,5 @@ func mustAsString(v rel.Value) string {
if s, ok := rel.AsString(v.(rel.Set)); ok {
return s.String()
}
panic("can not be a string")
panic("value is not a string")
}
18 changes: 13 additions & 5 deletions translate/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@ func JSONToArrai(data interface{}) (rel.Value, error) {
return jsonObjToArrai(v)
case []interface{}:
return jsonArrToArrai(v)
case string: // rel.NewValue cannot produce strings
return rel.NewString([]rune(v)), nil
case string:
return rel.NewTuple(rel.NewAttr("s", rel.NewString([]rune(v)))), nil
case float64:
return rel.NewNumber(v), nil
case bool:
return rel.NewTuple(rel.NewAttr("b", rel.NewBool(v))), nil
case nil:
return rel.None, nil
return rel.NewTuple(rel.NewAttr("null", rel.None)), nil
default:
return rel.NewValue(v)
t, err := rel.NewValue(v)
if err != nil {
return nil, err
}
return rel.NewTuple(rel.NewAttr("v", t)), nil
}
}

Expand Down Expand Up @@ -52,5 +60,5 @@ func jsonArrToArrai(data []interface{}) (rel.Value, error) {
}
elts[i] = elt
}
return rel.NewArray(elts...), nil
return rel.NewTuple(rel.NewAttr("a", rel.NewArray(elts...))), nil
}
34 changes: 17 additions & 17 deletions translate/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,46 +42,46 @@ func TestJSONObjectToArrai(t *testing.T) {
AssertExpectedJSONTranslation(t, `{}`, `{}`)

// different value types
AssertExpectedJSONTranslation(t, `{"key": "val"}`, `{"key":"val"}`)
AssertExpectedJSONTranslation(t, `{"key": 123}`, `{"key":123}`)
AssertExpectedJSONTranslation(t, `{"key": {"foo": "bar"}}`, `{"key":{"foo":"bar"}}`)
AssertExpectedJSONTranslation(t, `{"key": [1, 2, 3]}`, `{"key":[1, 2, 3]}`)
AssertExpectedJSONTranslation(t, `{"key": {}}`, `{"key":null}`)
AssertExpectedJSONTranslation(t, `{"key": 123} `, `{"key":123} `)
AssertExpectedJSONTranslation(t, `{"key": (null: {})} `, `{"key":null} `)
AssertExpectedJSONTranslation(t, `{"key": (s: "val")} `, `{"key":"val"} `)
AssertExpectedJSONTranslation(t, `{"key": (a: [1, 2, 3])}`, `{"key":[1, 2, 3]} `)
AssertExpectedJSONTranslation(t, `{"key": {"foo": (s: "bar")}}`, `{"key":{"foo":"bar"}}`)

// Multiple key-val pairs
AssertExpectedJSONTranslation(t, `{"key": "val", "foo": 123}`, `{"key":"val", "foo":123}`)
AssertExpectedJSONTranslation(t, `{"key": (s: "val"), "foo": 123}`, `{"key":"val", "foo":123}`)
}

func TestJSONArrayToArrai(t *testing.T) {
t.Parallel()

// Empty
AssertExpectedJSONTranslation(t, `[]`, `[]`)
AssertExpectedJSONTranslation(t, `(a: [])`, `[]`)

// Different value types
AssertExpectedJSONTranslation(t, `[1]`, `[1]`)
AssertExpectedJSONTranslation(t, `["hello"]`, `["hello"]`)
AssertExpectedJSONTranslation(t, `[{"foo": "bar"}]`, `[{"foo":"bar"}]`)
AssertExpectedJSONTranslation(t, `[[1, 2, 3]]`, `[[1, 2, 3]]`)
AssertExpectedJSONTranslation(t, `[{}]`, `[null]`)
AssertExpectedJSONTranslation(t, `(a: [1]) `, `[1] `)
AssertExpectedJSONTranslation(t, `(a: [(null: {})]) `, `[null] `)
AssertExpectedJSONTranslation(t, `(a: [(s: "hello")]) `, `["hello"] `)
AssertExpectedJSONTranslation(t, `(a: [(a: [1, 2, 3])]) `, `[[1, 2, 3]] `)
AssertExpectedJSONTranslation(t, `(a: [{"foo": (s: "bar")}])`, `[{"foo":"bar"}]`)

// Multiple values with different types
AssertExpectedJSONTranslation(t, `[1, "Hello", {}]`, `[1, "Hello", null]`)
AssertExpectedJSONTranslation(t, `(a: [1, (s: "Hello"), (null: {})])`, `[1, "Hello", null]`)
}

func TestJSONNullToNone(t *testing.T) {
t.Parallel()
AssertExpectedJSONTranslation(t, `{}`, `null`)
AssertExpectedJSONTranslation(t, `(null: {})`, `null`)
}

func TestJSONStringToArrai(t *testing.T) {
t.Parallel()
AssertExpectedJSONTranslation(t, `""`, `""`)
AssertExpectedJSONTranslation(t, `"Hello World"`, `"Hello World"`)
AssertExpectedJSONTranslation(t, `(s: {}) `, `"" `)
AssertExpectedJSONTranslation(t, `(s: "Hello World")`, `"Hello World"`)
}

func TestJSONNumericToArrai(t *testing.T) {
t.Parallel()
AssertExpectedJSONTranslation(t, `123`, `123`)
AssertExpectedJSONTranslation(t, `123 `, `123 `)
AssertExpectedJSONTranslation(t, `1.23`, `1.23`)
}

0 comments on commit 53b734c

Please sign in to comment.