Skip to content

Commit

Permalink
fix: proper option fromjson (#1027)
Browse files Browse the repository at this point in the history
* fix: proper option fromjson

* fix(json): use Array[val] and null for `to_json` and `from_json`
  • Loading branch information
qazxcdswe123 authored Sep 23, 2024
1 parent ce4547d commit 620d17e
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 3 deletions.
2 changes: 1 addition & 1 deletion builtin/json.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub fn Map::to_json[K : Show, V : ToJson](self : Map[K, V]) -> Json {
pub fn Option::to_json[T : ToJson](self : T?) -> Json {
match self {
None => Null
Some(value) => value.to_json()
Some(value) => [value.to_json()]
}
}

Expand Down
3 changes: 2 additions & 1 deletion json/from_json.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ pub impl[V : FromJson] FromJson for Map[String, V] with from_json(json, path) {
pub impl[T : FromJson] FromJson for T? with from_json(json, path) {
match json {
Null => None
_ => Some(FromJson::from_json!(json, path))
Array([value]) => Some(FromJson::from_json!(value, path.add_index(0)))
_ => decode_error!(path, "Option::from_json: expected array or null")
}
}

Expand Down
6 changes: 6 additions & 0 deletions json/from_json_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,12 @@ test "Option" {
let u = Some(1).to_json()
let v : Int? = @json.from_json!(u)
inspect!(v, content="Some(1)")
let nested : Json = (Some(None) : Unit??).to_json()
let v : Unit?? = @json.from_json!(nested)
inspect!(v, content="Some(None)")
let nested : Json = (Some(Some(None)) : Unit???).to_json()
let v : Unit??? = @json.from_json!(nested)
inspect!(v, content="Some(Some(None))")
}

test "Result" {
Expand Down
33 changes: 32 additions & 1 deletion json/to_json_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,40 @@ test "Map::to_json" {
)
}

struct Opt {
x : Int?
t : Int??
} derive(ToJson)

test "Option::to_json" {
inspect!((Some(42) : Int?).to_json(), content="Number(42)")
inspect!((Some(42) : Int?).to_json(), content="Array([Number(42)])")
inspect!((None : Int?).to_json(), content="Null")
inspect!((Some(None) : Unit??).to_json(), content="Array([Null])")
inspect!(
(Some(Some(None)) : Unit???).to_json(),
content="Array([Array([Null])])",
)
let opt = { x: Some(42), t: Some(Some(42)) }
inspect!(
opt.to_json(),
content=
#|Object({"x": Array([Number(42)]), "t": Array([Array([Number(42)])])})
,
)
let opt = { x: None, t: None }
inspect!(
opt.to_json(),
content=
#|Object({"x": Null, "t": Null})
,
)
let opt = { x: None, t: Some(None) }
inspect!(
opt.to_json(),
content=
#|Object({"x": Null, "t": Array([Null])})
,
)
}

test "Tuple::to_json" {
Expand Down

0 comments on commit 620d17e

Please sign in to comment.