From cdf3611d91006d1a12b834f5366f0b761c3d0b79 Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Apr 2024 14:32:00 +0800 Subject: [PATCH 01/11] add: utils for json --- json/json.mbt | 187 +++++++++++++++++++++++++++++++++++++++++++++ json/moon.pkg.json | 26 ++++--- 2 files changed, 202 insertions(+), 11 deletions(-) create mode 100644 json/json.mbt diff --git a/json/json.mbt b/json/json.mbt new file mode 100644 index 000000000..2c9085e5b --- /dev/null +++ b/json/json.mbt @@ -0,0 +1,187 @@ +pub fn get_as_null(json : JsonValue) -> Option[Unit] { + match json { + Null => Some(()) + _ => None + } +} + +test "get as null" { + inspect(JsonValue::Null |> get_as_null, content="Some(())")? + inspect(JsonValue::Boolean(false) |> get_as_null, content="None")? + inspect(JsonValue::Number(1.0) |> get_as_null, content="None")? + inspect(JsonValue::String("Hello World") |> get_as_null, content="None")? + inspect( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) + |> get_as_null, + content="None")? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ) + |> get_as_null, + content="None")? +} + +pub fn get_as_bool(json : JsonValue) -> Option[Bool] { + match json { + Boolean(b) => Some(b) + _ => None + } +} + +test "get as bool" { + inspect(JsonValue::Null |> get_as_bool, content="None")? + inspect(JsonValue::Boolean(false) |> get_as_bool, content="Some(false)")? + inspect(JsonValue::Number(1.0) |> get_as_bool, content="None")? + inspect(JsonValue::String("Hello World") |> get_as_bool, content="None")? + inspect( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) + |> get_as_bool, + content="None", + )? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ) + |> get_as_bool, + content="None", + )? +} + +pub fn get_as_number(json : JsonValue) -> Option[Double] { + match json { + Number(n) => Some(n) + _ => None + } +} + +test "get as number" { + inspect(JsonValue::Null |> get_as_number, content="None")? + inspect(JsonValue::Boolean(false) |> get_as_number, content="None")? + inspect(JsonValue::Number(1.0) |> get_as_number, content="Some(1.0)")? + inspect(JsonValue::String("Hello World") |> get_as_number, content="None")? + inspect( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) + |> get_as_number, + content="None", + )? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ) + |> get_as_number, + content="None", + )? +} + +pub fn get_as_string(json : JsonValue) -> Option[String] { + match json { + String(s) => Some(s) + _ => None + } +} + +test "get as string" { + inspect(JsonValue::Null |> get_as_string, content="None")? + inspect(JsonValue::Boolean(false) |> get_as_string, content="None")? + inspect(JsonValue::Number(1.0) |> get_as_string, content="None")? + inspect(JsonValue::String("Hello World") |> get_as_string, content="Some(Hello World)")? + inspect( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) + |> get_as_string, + content="None", + )? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ) + |> get_as_string, + content="None", + )? +} + +pub fn get_as_array(json : JsonValue) -> Option[@vec.Vec[JsonValue]] { + match json { + Array(arr) => Some(arr) + _ => None + } +} + +test "get as array" { + inspect(JsonValue::Null |> get_as_array, content="None")? + inspect(JsonValue::Boolean(false) |> get_as_array, content="None")? + inspect(JsonValue::Number(1.0) |> get_as_array, content="None")? + inspect(JsonValue::String("Hello World") |> get_as_array, content="None")? + inspect( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) + |> get_as_array, + content="Some(Vec::[String(\"Hello World\")])", + )? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ) + |> get_as_array, + content="None", + )? +} + +pub fn get_as_object(json : JsonValue) -> Option[@map.Map[String, JsonValue]] { + match json { + Object(obj) => Some(obj) + _ => None + } +} + +test "get as object" { + inspect( + JsonValue::Null |> get_as_object |> Option::map(@map.Map::to_vec), + content="None", + )? + inspect( + JsonValue::Boolean(false) |> get_as_object |> Option::map(@map.Map::to_vec), + content="None", + )? + inspect( + JsonValue::Number(1.0) |> get_as_object |> Option::map(@map.Map::to_vec), + content="None", + )? + inspect( + JsonValue::String("Hello World") + |> get_as_object + |> Option::map(@map.Map::to_vec), + content="None", + )? + inspect( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) + |> get_as_object + |> Option::map(@map.Map::to_vec), + content="None", + )? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ) + |> get_as_object + |> Option::map(@map.Map::to_vec), + content="Some(Vec::[(key, String(\"key\")), (value, Number(100.0))])", + )? +} diff --git a/json/moon.pkg.json b/json/moon.pkg.json index 1c99cf4f6..4ed5a2da5 100644 --- a/json/moon.pkg.json +++ b/json/moon.pkg.json @@ -1,12 +1,16 @@ { - "import": [ - "moonbitlang/core/builtin", - "moonbitlang/core/double", - "moonbitlang/core/string", - "moonbitlang/core/bool", - "moonbitlang/core/tuple", - "moonbitlang/core/vec", - "moonbitlang/core/map", - "moonbitlang/core/coverage" - ] -} + "import": [ + "moonbitlang/core/builtin", + "moonbitlang/core/double", + "moonbitlang/core/string", + "moonbitlang/core/bool", + "moonbitlang/core/tuple", + "moonbitlang/core/vec", + "moonbitlang/core/map", + "moonbitlang/core/coverage", + "moonbitlang/core/assertion", + "moonbitlang/core/int", + "moonbitlang/core/unit", + "moonbitlang/core/option" + ] +} \ No newline at end of file From 4e3e9b659c7c692272ad44bc7852127d942bebc6 Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Apr 2024 14:38:51 +0800 Subject: [PATCH 02/11] update: change to method --- json/json.mbt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/json/json.mbt b/json/json.mbt index 2c9085e5b..383a7ff6e 100644 --- a/json/json.mbt +++ b/json/json.mbt @@ -1,5 +1,5 @@ -pub fn get_as_null(json : JsonValue) -> Option[Unit] { - match json { +pub fn get_as_null(self : JsonValue) -> Option[Unit] { + match self { Null => Some(()) _ => None } @@ -25,8 +25,8 @@ test "get as null" { content="None")? } -pub fn get_as_bool(json : JsonValue) -> Option[Bool] { - match json { +pub fn get_as_bool(self : JsonValue) -> Option[Bool] { + match self { Boolean(b) => Some(b) _ => None } @@ -54,8 +54,8 @@ test "get as bool" { )? } -pub fn get_as_number(json : JsonValue) -> Option[Double] { - match json { +pub fn get_as_number(self : JsonValue) -> Option[Double] { + match self { Number(n) => Some(n) _ => None } @@ -83,8 +83,8 @@ test "get as number" { )? } -pub fn get_as_string(json : JsonValue) -> Option[String] { - match json { +pub fn get_as_string(self : JsonValue) -> Option[String] { + match self { String(s) => Some(s) _ => None } @@ -112,8 +112,8 @@ test "get as string" { )? } -pub fn get_as_array(json : JsonValue) -> Option[@vec.Vec[JsonValue]] { - match json { +pub fn get_as_array(self : JsonValue) -> Option[@vec.Vec[JsonValue]] { + match self { Array(arr) => Some(arr) _ => None } @@ -141,8 +141,8 @@ test "get as array" { )? } -pub fn get_as_object(json : JsonValue) -> Option[@map.Map[String, JsonValue]] { - match json { +pub fn get_as_object(self : JsonValue) -> Option[@map.Map[String, JsonValue]] { + match self { Object(obj) => Some(obj) _ => None } From 002a7e764e212f4bb00b3632c7e774e1c030de1e Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Apr 2024 14:39:56 +0800 Subject: [PATCH 03/11] add: utils function for vector --- vec/vec.mbt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/vec/vec.mbt b/vec/vec.mbt index 011f5ad00..603aa85e5 100644 --- a/vec/vec.mbt +++ b/vec/vec.mbt @@ -120,6 +120,28 @@ pub fn op_get[T](self : Vec[T], index : Int) -> T { self.buf[index] } +/// Retrieves the element at the specified index from the vector, or `None` if index is out of bounds +/// +/// # Example +/// ``` +/// let v = Vec::new() +/// v.push(3) +/// println(v.get(0)) // Some(3) +/// ``` +pub fn get[T](self : Vec[T], index : Int) -> Option[T] { + if index < 0 || index >= self.len { + return None + } + Some(self.buf[index]) +} + +test "get" { + let v = Vec::[3] + inspect(v.get(-1), content="None")? + inspect(v.get(0), content="Some(3)")? + inspect(v.get(1), content="None")? +} + /// Sets the value of the element at the specified index. /// /// # Example From 17affa26e2376610d0570f27664c91fbac7abecf Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Apr 2024 14:46:32 +0800 Subject: [PATCH 04/11] add: more util methods --- json/json.mbt | 122 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 119 insertions(+), 3 deletions(-) diff --git a/json/json.mbt b/json/json.mbt index 383a7ff6e..83de85db1 100644 --- a/json/json.mbt +++ b/json/json.mbt @@ -5,6 +5,14 @@ pub fn get_as_null(self : JsonValue) -> Option[Unit] { } } +pub fn get_item_as_null(self : JsonValue, index : Int) -> Option[Unit] { + self.get_as_array()?.get(index)?.get_as_null() +} + +pub fn get_value_as_null(self : JsonValue, key : String) -> Option[Unit] { + self.get_as_object()?.lookup(key)?.get_as_null() +} + test "get as null" { inspect(JsonValue::Null |> get_as_null, content="Some(())")? inspect(JsonValue::Boolean(false) |> get_as_null, content="None")? @@ -13,7 +21,8 @@ test "get as null" { inspect( JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) |> get_as_null, - content="None")? + content="None", + )? inspect( JsonValue::Object( @map.Map::[ @@ -22,7 +31,8 @@ test "get as null" { ], ) |> get_as_null, - content="None")? + content="None", + )? } pub fn get_as_bool(self : JsonValue) -> Option[Bool] { @@ -32,6 +42,14 @@ pub fn get_as_bool(self : JsonValue) -> Option[Bool] { } } +pub fn get_item_as_bool(self : JsonValue, index : Int) -> Option[Bool] { + self.get_as_array()?.get(index)?.get_as_bool() +} + +pub fn get_value_as_bool(self : JsonValue, key : String) -> Option[Bool] { + self.get_as_object()?.lookup(key)?.get_as_bool() +} + test "get as bool" { inspect(JsonValue::Null |> get_as_bool, content="None")? inspect(JsonValue::Boolean(false) |> get_as_bool, content="Some(false)")? @@ -61,6 +79,14 @@ pub fn get_as_number(self : JsonValue) -> Option[Double] { } } +pub fn get_item_as_number(self : JsonValue, index : Int) -> Option[Double] { + self.get_as_array()?.get(index)?.get_as_number() +} + +pub fn get_value_as_number(self : JsonValue, key : String) -> Option[Double] { + self.get_as_object()?.lookup(key)?.get_as_number() +} + test "get as number" { inspect(JsonValue::Null |> get_as_number, content="None")? inspect(JsonValue::Boolean(false) |> get_as_number, content="None")? @@ -90,11 +116,22 @@ pub fn get_as_string(self : JsonValue) -> Option[String] { } } +pub fn get_item_as_string(self : JsonValue, index : Int) -> Option[String] { + self.get_as_array()?.get(index)?.get_as_string() +} + +pub fn get_value_as_string(self : JsonValue, key : String) -> Option[String] { + self.get_as_object()?.lookup(key)?.get_as_string() +} + test "get as string" { inspect(JsonValue::Null |> get_as_string, content="None")? inspect(JsonValue::Boolean(false) |> get_as_string, content="None")? inspect(JsonValue::Number(1.0) |> get_as_string, content="None")? - inspect(JsonValue::String("Hello World") |> get_as_string, content="Some(Hello World)")? + inspect( + JsonValue::String("Hello World") |> get_as_string, + content="Some(Hello World)", + )? inspect( JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) |> get_as_string, @@ -119,6 +156,20 @@ pub fn get_as_array(self : JsonValue) -> Option[@vec.Vec[JsonValue]] { } } +pub fn get_item_as_array( + self : JsonValue, + index : Int +) -> Option[@vec.Vec[JsonValue]] { + self.get_as_array()?.get(index)?.get_as_array() +} + +pub fn get_value_as_array( + self : JsonValue, + key : String +) -> Option[@vec.Vec[JsonValue]] { + self.get_as_object()?.lookup(key)?.get_as_array() +} + test "get as array" { inspect(JsonValue::Null |> get_as_array, content="None")? inspect(JsonValue::Boolean(false) |> get_as_array, content="None")? @@ -129,6 +180,21 @@ test "get as array" { |> get_as_array, content="Some(Vec::[String(\"Hello World\")])", )? + inspect( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).get_item_as_string( + 0, + ), + ~content="Some(Hello World)")? + inspect( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).get_item_as_string( + 1, + ), + ~content="None")? + inspect( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).get_item_as_number( + 0, + ), + ~content="None")? inspect( JsonValue::Object( @map.Map::[ @@ -148,6 +214,20 @@ pub fn get_as_object(self : JsonValue) -> Option[@map.Map[String, JsonValue]] { } } +pub fn get_item_as_object( + self : JsonValue, + index : Int +) -> Option[@map.Map[String, JsonValue]] { + self.get_as_array()?.get(index)?.get_as_object() +} + +pub fn get_value_as_object( + self : JsonValue, + key : String +) -> Option[@map.Map[String, JsonValue]] { + self.get_as_object()?.lookup(key)?.get_as_object() +} + test "get as object" { inspect( JsonValue::Null |> get_as_object |> Option::map(@map.Map::to_vec), @@ -184,4 +264,40 @@ test "get as object" { |> Option::map(@map.Map::to_vec), content="Some(Vec::[(key, String(\"key\")), (value, Number(100.0))])", )? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ).get_value_as_string("key"), + content="Some(key)", + )? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ).get_value_as_number("value"), + content="Some(100.0)", + )? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ).get_value_as_number("key"), + content="None", + )? + inspect( + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("key")), + ("value", JsonValue::Number(100.0)), + ], + ).get_value_as_number("asdf"), + content="None", + )? } From 276e8db4990e90345d9dd1eda899b6db6faf5f8e Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Apr 2024 14:49:21 +0800 Subject: [PATCH 05/11] fix: license header --- json/json.mbt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/json/json.mbt b/json/json.mbt index 83de85db1..583933e58 100644 --- a/json/json.mbt +++ b/json/json.mbt @@ -1,3 +1,17 @@ +// Copyright 2024 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn get_as_null(self : JsonValue) -> Option[Unit] { match self { Null => Some(()) From 056a8c54326002d8f828e3bacb3e31c11839fd09 Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Apr 2024 14:52:59 +0800 Subject: [PATCH 06/11] fix: update signature --- json/json.mbti | 18 ++++++++++++++++++ vec/vec.mbti | 1 + 2 files changed, 19 insertions(+) diff --git a/json/json.mbti b/json/json.mbti index b78f46b75..9e67b1527 100644 --- a/json/json.mbti +++ b/json/json.mbti @@ -15,6 +15,24 @@ pub enum JsonValue { Object(@map.Map[String, JsonValue]) } fn JsonValue::debug_write(JsonValue, Buffer) -> Unit +fn JsonValue::get_as_array(JsonValue) -> Option[@vec.Vec[JsonValue]] +fn JsonValue::get_as_bool(JsonValue) -> Option[Bool] +fn JsonValue::get_as_null(JsonValue) -> Option[Unit] +fn JsonValue::get_as_number(JsonValue) -> Option[Double] +fn JsonValue::get_as_object(JsonValue) -> Option[@map.Map[String, JsonValue]] +fn JsonValue::get_as_string(JsonValue) -> Option[String] +fn JsonValue::get_item_as_array(JsonValue, Int) -> Option[@vec.Vec[JsonValue]] +fn JsonValue::get_item_as_bool(JsonValue, Int) -> Option[Bool] +fn JsonValue::get_item_as_null(JsonValue, Int) -> Option[Unit] +fn JsonValue::get_item_as_number(JsonValue, Int) -> Option[Double] +fn JsonValue::get_item_as_object(JsonValue, Int) -> Option[@map.Map[String, JsonValue]] +fn JsonValue::get_item_as_string(JsonValue, Int) -> Option[String] +fn JsonValue::get_value_as_array(JsonValue, String) -> Option[@vec.Vec[JsonValue]] +fn JsonValue::get_value_as_bool(JsonValue, String) -> Option[Bool] +fn JsonValue::get_value_as_null(JsonValue, String) -> Option[Unit] +fn JsonValue::get_value_as_number(JsonValue, String) -> Option[Double] +fn JsonValue::get_value_as_object(JsonValue, String) -> Option[@map.Map[String, JsonValue]] +fn JsonValue::get_value_as_string(JsonValue, String) -> Option[String] fn JsonValue::op_equal(JsonValue, JsonValue) -> Bool fn JsonValue::to_string(JsonValue) -> String diff --git a/vec/vec.mbti b/vec/vec.mbti index dbfa4b624..f7050f950 100644 --- a/vec/vec.mbti +++ b/vec/vec.mbti @@ -23,6 +23,7 @@ fn Vec::fold_lefti[T, U](Vec[T], (Int, U, T) -> U, U) -> U fn Vec::fold_right[T, U](Vec[T], (U, T) -> U, U) -> U fn Vec::fold_righti[T, U](Vec[T], (Int, U, T) -> U, U) -> U fn Vec::from_array[T](Array[T]) -> Vec[T] +fn Vec::get[T](Vec[T], Int) -> Option[T] fn Vec::insert[T](Vec[T], Int, T) -> Unit fn Vec::is_empty[T](Vec[T]) -> Bool fn Vec::is_sorted[T : Compare + Eq](Vec[T]) -> Bool From 9ea162215c666dbc372c5a269f0394c5b35102e7 Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Apr 2024 15:09:53 +0800 Subject: [PATCH 07/11] add: more util functions and tests --- json/json.mbt | 78 ++++++++++++++++++++++++++++++++++++++++++++++++-- json/json.mbti | 2 ++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/json/json.mbt b/json/json.mbt index 583933e58..f820fdbf5 100644 --- a/json/json.mbt +++ b/json/json.mbt @@ -184,6 +184,10 @@ pub fn get_value_as_array( self.get_as_object()?.lookup(key)?.get_as_array() } +pub fn get_item(self : JsonValue, index : Int) -> Option[JsonValue] { + self.get_as_array()?.get(index) +} + test "get as array" { inspect(JsonValue::Null |> get_as_array, content="None")? inspect(JsonValue::Boolean(false) |> get_as_array, content="None")? @@ -198,17 +202,20 @@ test "get as array" { JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).get_item_as_string( 0, ), - ~content="Some(Hello World)")? + content="Some(Hello World)", + )? inspect( JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).get_item_as_string( 1, ), - ~content="None")? + content="None", + )? inspect( JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).get_item_as_number( 0, ), - ~content="None")? + content="None", + )? inspect( JsonValue::Object( @map.Map::[ @@ -242,6 +249,10 @@ pub fn get_value_as_object( self.get_as_object()?.lookup(key)?.get_as_object() } +pub fn get_value(self : JsonValue, key : String) -> Option[JsonValue] { + self.get_as_object()?.lookup(key) +} + test "get as object" { inspect( JsonValue::Null |> get_as_object |> Option::map(@map.Map::to_vec), @@ -315,3 +326,64 @@ test "get as object" { content="None", )? } + +test "deep access" { + let json = JsonValue::Object( + @map.Map::[ + ( + "key", + JsonValue::Array( + @vec.Vec::[ + JsonValue::Number(1.0), + JsonValue::Boolean(true), + JsonValue::Null, + JsonValue::Array(@vec.Vec::[]), + JsonValue::Object( + @map.Map::[ + ("key", JsonValue::String("value")), + ("value", JsonValue::Number(100.0)), + ], + ), + ], + ), + ), + ("null", JsonValue::Null), + ("bool", JsonValue::Boolean(false)), + ("obj", JsonValue::Object(@map.Map::[])), + ], + ) + inspect(json.get_value_as_null("null"), content="Some(())")? + inspect( + json.get_value("key").bind(fn { array => array.get_item_as_null(2) }), + content="Some(())", + )? + inspect(json.get_value_as_bool("bool"), content="Some(false)")? + inspect( + json.get_value("key").bind(fn { array => array.get_item_as_bool(1) }), + content="Some(true)", + )? + inspect( + json.get_value_as_array("key"), + content="Some(Vec::[Number(1.0), Boolean(true), Null, Array(Vec::[]), Object(Map::[(\"key\", String(\"value\")), (\"value\", Number(100.0))])])", + )? + inspect( + json.get_value("key").bind(fn { array => array.get_item_as_array(3) }), + content="Some(Vec::[])", + )? + inspect( + json.get_value("key").bind(fn { array => array.get_item_as_object(4) }).map( + @map.Map::to_vec, + ), + content="Some(Vec::[(key, String(\"value\")), (value, Number(100.0))])", + )? + inspect( + json.get_value_as_object("obj").map(@map.Map::to_vec), + content="Some(Vec::[])", + )? + inspect( + json.get_value("key").bind(fn { array => array.get_item(4) }).bind( + fn { obj => obj.get_value_as_number("value") }, + ), + content="Some(100.0)", + )? +} diff --git a/json/json.mbti b/json/json.mbti index 9e67b1527..e637fcc04 100644 --- a/json/json.mbti +++ b/json/json.mbti @@ -21,12 +21,14 @@ fn JsonValue::get_as_null(JsonValue) -> Option[Unit] fn JsonValue::get_as_number(JsonValue) -> Option[Double] fn JsonValue::get_as_object(JsonValue) -> Option[@map.Map[String, JsonValue]] fn JsonValue::get_as_string(JsonValue) -> Option[String] +fn JsonValue::get_item(JsonValue, Int) -> Option[JsonValue] fn JsonValue::get_item_as_array(JsonValue, Int) -> Option[@vec.Vec[JsonValue]] fn JsonValue::get_item_as_bool(JsonValue, Int) -> Option[Bool] fn JsonValue::get_item_as_null(JsonValue, Int) -> Option[Unit] fn JsonValue::get_item_as_number(JsonValue, Int) -> Option[Double] fn JsonValue::get_item_as_object(JsonValue, Int) -> Option[@map.Map[String, JsonValue]] fn JsonValue::get_item_as_string(JsonValue, Int) -> Option[String] +fn JsonValue::get_value(JsonValue, String) -> Option[JsonValue] fn JsonValue::get_value_as_array(JsonValue, String) -> Option[@vec.Vec[JsonValue]] fn JsonValue::get_value_as_bool(JsonValue, String) -> Option[Bool] fn JsonValue::get_value_as_null(JsonValue, String) -> Option[Unit] From 3d0ef5f209fbfb188d538e699a6f3cb6d9d04b21 Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Apr 2024 15:17:12 +0800 Subject: [PATCH 08/11] doc: add comments --- json/json.mbt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/json/json.mbt b/json/json.mbt index f820fdbf5..ebee6fec7 100644 --- a/json/json.mbt +++ b/json/json.mbt @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +/// Try to get this element as a Null pub fn get_as_null(self : JsonValue) -> Option[Unit] { match self { Null => Some(()) @@ -19,10 +20,12 @@ pub fn get_as_null(self : JsonValue) -> Option[Unit] { } } +/// Try to get this element as a Json Array and try to get the element at the `index` as a Null pub fn get_item_as_null(self : JsonValue, index : Int) -> Option[Unit] { self.get_as_array()?.get(index)?.get_as_null() } +/// Try to get this element as a Json Object and try to get the element with the `key` as a Null pub fn get_value_as_null(self : JsonValue, key : String) -> Option[Unit] { self.get_as_object()?.lookup(key)?.get_as_null() } @@ -49,6 +52,7 @@ test "get as null" { )? } +/// Try to get this element as a Boolean pub fn get_as_bool(self : JsonValue) -> Option[Bool] { match self { Boolean(b) => Some(b) @@ -56,10 +60,12 @@ pub fn get_as_bool(self : JsonValue) -> Option[Bool] { } } +/// Try to get this element as a Json Array and try to get the element at the `index` as a Boolean pub fn get_item_as_bool(self : JsonValue, index : Int) -> Option[Bool] { self.get_as_array()?.get(index)?.get_as_bool() } +/// Try to get this element as a Json Object and try to get the element with the `key` as a Boolean pub fn get_value_as_bool(self : JsonValue, key : String) -> Option[Bool] { self.get_as_object()?.lookup(key)?.get_as_bool() } @@ -86,6 +92,7 @@ test "get as bool" { )? } +/// Try to get this element as a Number pub fn get_as_number(self : JsonValue) -> Option[Double] { match self { Number(n) => Some(n) @@ -93,10 +100,12 @@ pub fn get_as_number(self : JsonValue) -> Option[Double] { } } +/// Try to get this element as a Json Array and try to get the element at the `index` as a Number pub fn get_item_as_number(self : JsonValue, index : Int) -> Option[Double] { self.get_as_array()?.get(index)?.get_as_number() } +/// Try to get this element as a Json Object and try to get the element with the `key` as a Number pub fn get_value_as_number(self : JsonValue, key : String) -> Option[Double] { self.get_as_object()?.lookup(key)?.get_as_number() } @@ -123,6 +132,7 @@ test "get as number" { )? } +/// Try to get this element as a String pub fn get_as_string(self : JsonValue) -> Option[String] { match self { String(s) => Some(s) @@ -130,10 +140,12 @@ pub fn get_as_string(self : JsonValue) -> Option[String] { } } +/// Try to get this element as a Json Array and try to get the element at the `index` as a String pub fn get_item_as_string(self : JsonValue, index : Int) -> Option[String] { self.get_as_array()?.get(index)?.get_as_string() } +/// Try to get this element as a Json Object and try to get the element with the `key` as a String pub fn get_value_as_string(self : JsonValue, key : String) -> Option[String] { self.get_as_object()?.lookup(key)?.get_as_string() } @@ -163,6 +175,7 @@ test "get as string" { )? } +/// Try to get this element as an Array pub fn get_as_array(self : JsonValue) -> Option[@vec.Vec[JsonValue]] { match self { Array(arr) => Some(arr) @@ -170,6 +183,7 @@ pub fn get_as_array(self : JsonValue) -> Option[@vec.Vec[JsonValue]] { } } +/// Try to get this element as a Json Array and try to get the element at the `index` as an Array pub fn get_item_as_array( self : JsonValue, index : Int @@ -177,6 +191,7 @@ pub fn get_item_as_array( self.get_as_array()?.get(index)?.get_as_array() } +/// Try to get this element as a Json Object and try to get the element with the `key` as an Array pub fn get_value_as_array( self : JsonValue, key : String @@ -184,6 +199,7 @@ pub fn get_value_as_array( self.get_as_object()?.lookup(key)?.get_as_array() } +/// Try to get this element as a Json Array and get the element at the `index` as a Json Value pub fn get_item(self : JsonValue, index : Int) -> Option[JsonValue] { self.get_as_array()?.get(index) } @@ -228,6 +244,7 @@ test "get as array" { )? } +/// Try to get this element as an Object pub fn get_as_object(self : JsonValue) -> Option[@map.Map[String, JsonValue]] { match self { Object(obj) => Some(obj) @@ -235,6 +252,7 @@ pub fn get_as_object(self : JsonValue) -> Option[@map.Map[String, JsonValue]] { } } +/// Try to get this element as a Json Array and try to get the element at the `index` as an Object pub fn get_item_as_object( self : JsonValue, index : Int @@ -242,6 +260,7 @@ pub fn get_item_as_object( self.get_as_array()?.get(index)?.get_as_object() } +/// Try to get this element as a Json Object and try to get the element with the `key` as an Object pub fn get_value_as_object( self : JsonValue, key : String @@ -249,6 +268,7 @@ pub fn get_value_as_object( self.get_as_object()?.lookup(key)?.get_as_object() } +/// Try to get this element as a Json Object and get the element with the `key` as a Json Value pub fn get_value(self : JsonValue, key : String) -> Option[JsonValue] { self.get_as_object()?.lookup(key) } From a1a1100f0d0b6412343cebbc4d55c3720670af1a Mon Sep 17 00:00:00 2001 From: zihang Date: Tue, 23 Apr 2024 09:45:22 +0800 Subject: [PATCH 09/11] update: shorten name by removing get_ --- json/json.mbt | 203 +++++++++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 93 deletions(-) diff --git a/json/json.mbt b/json/json.mbt index ebee6fec7..c87bceb3b 100644 --- a/json/json.mbt +++ b/json/json.mbt @@ -13,7 +13,7 @@ // limitations under the License. /// Try to get this element as a Null -pub fn get_as_null(self : JsonValue) -> Option[Unit] { +pub fn as_null(self : JsonValue) -> Option[Unit] { match self { Null => Some(()) _ => None @@ -21,23 +21,26 @@ pub fn get_as_null(self : JsonValue) -> Option[Unit] { } /// Try to get this element as a Json Array and try to get the element at the `index` as a Null -pub fn get_item_as_null(self : JsonValue, index : Int) -> Option[Unit] { - self.get_as_array()?.get(index)?.get_as_null() +/// +/// Same as `item(index)?.as_null()` +pub fn item_as_null(self : JsonValue, index : Int) -> Option[Unit] { + self.as_array()?.get(index)?.as_null() } /// Try to get this element as a Json Object and try to get the element with the `key` as a Null -pub fn get_value_as_null(self : JsonValue, key : String) -> Option[Unit] { - self.get_as_object()?.lookup(key)?.get_as_null() +/// +/// Same as `value(key)?.as_null()` +pub fn value_as_null(self : JsonValue, key : String) -> Option[Unit] { + self.as_object()?.lookup(key)?.as_null() } test "get as null" { - inspect(JsonValue::Null |> get_as_null, content="Some(())")? - inspect(JsonValue::Boolean(false) |> get_as_null, content="None")? - inspect(JsonValue::Number(1.0) |> get_as_null, content="None")? - inspect(JsonValue::String("Hello World") |> get_as_null, content="None")? + inspect(JsonValue::Null |> as_null, content="Some(())")? + inspect(JsonValue::Boolean(false) |> as_null, content="None")? + inspect(JsonValue::Number(1.0) |> as_null, content="None")? + inspect(JsonValue::String("Hello World") |> as_null, content="None")? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) - |> get_as_null, + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) |> as_null, content="None", )? inspect( @@ -47,13 +50,13 @@ test "get as null" { ("value", JsonValue::Number(100.0)), ], ) - |> get_as_null, + |> as_null, content="None", )? } /// Try to get this element as a Boolean -pub fn get_as_bool(self : JsonValue) -> Option[Bool] { +pub fn as_bool(self : JsonValue) -> Option[Bool] { match self { Boolean(b) => Some(b) _ => None @@ -61,23 +64,26 @@ pub fn get_as_bool(self : JsonValue) -> Option[Bool] { } /// Try to get this element as a Json Array and try to get the element at the `index` as a Boolean -pub fn get_item_as_bool(self : JsonValue, index : Int) -> Option[Bool] { - self.get_as_array()?.get(index)?.get_as_bool() +/// +/// Same as `item(index)?.as_bool()` +pub fn item_as_bool(self : JsonValue, index : Int) -> Option[Bool] { + self.as_array()?.get(index)?.as_bool() } /// Try to get this element as a Json Object and try to get the element with the `key` as a Boolean -pub fn get_value_as_bool(self : JsonValue, key : String) -> Option[Bool] { - self.get_as_object()?.lookup(key)?.get_as_bool() +/// +/// Same as `value(key)?.as_bool()` +pub fn value_as_bool(self : JsonValue, key : String) -> Option[Bool] { + self.as_object()?.lookup(key)?.as_bool() } test "get as bool" { - inspect(JsonValue::Null |> get_as_bool, content="None")? - inspect(JsonValue::Boolean(false) |> get_as_bool, content="Some(false)")? - inspect(JsonValue::Number(1.0) |> get_as_bool, content="None")? - inspect(JsonValue::String("Hello World") |> get_as_bool, content="None")? + inspect(JsonValue::Null |> as_bool, content="None")? + inspect(JsonValue::Boolean(false) |> as_bool, content="Some(false)")? + inspect(JsonValue::Number(1.0) |> as_bool, content="None")? + inspect(JsonValue::String("Hello World") |> as_bool, content="None")? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) - |> get_as_bool, + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) |> as_bool, content="None", )? inspect( @@ -87,13 +93,13 @@ test "get as bool" { ("value", JsonValue::Number(100.0)), ], ) - |> get_as_bool, + |> as_bool, content="None", )? } /// Try to get this element as a Number -pub fn get_as_number(self : JsonValue) -> Option[Double] { +pub fn as_number(self : JsonValue) -> Option[Double] { match self { Number(n) => Some(n) _ => None @@ -101,23 +107,26 @@ pub fn get_as_number(self : JsonValue) -> Option[Double] { } /// Try to get this element as a Json Array and try to get the element at the `index` as a Number -pub fn get_item_as_number(self : JsonValue, index : Int) -> Option[Double] { - self.get_as_array()?.get(index)?.get_as_number() +/// +/// Same as `item(index)?.as_number()` +pub fn item_as_number(self : JsonValue, index : Int) -> Option[Double] { + self.as_array()?.get(index)?.as_number() } /// Try to get this element as a Json Object and try to get the element with the `key` as a Number -pub fn get_value_as_number(self : JsonValue, key : String) -> Option[Double] { - self.get_as_object()?.lookup(key)?.get_as_number() +/// +/// Same as `value(key)?.as_number()` +pub fn value_as_number(self : JsonValue, key : String) -> Option[Double] { + self.as_object()?.lookup(key)?.as_number() } test "get as number" { - inspect(JsonValue::Null |> get_as_number, content="None")? - inspect(JsonValue::Boolean(false) |> get_as_number, content="None")? - inspect(JsonValue::Number(1.0) |> get_as_number, content="Some(1.0)")? - inspect(JsonValue::String("Hello World") |> get_as_number, content="None")? + inspect(JsonValue::Null |> as_number, content="None")? + inspect(JsonValue::Boolean(false) |> as_number, content="None")? + inspect(JsonValue::Number(1.0) |> as_number, content="Some(1.0)")? + inspect(JsonValue::String("Hello World") |> as_number, content="None")? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) - |> get_as_number, + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) |> as_number, content="None", )? inspect( @@ -127,13 +136,13 @@ test "get as number" { ("value", JsonValue::Number(100.0)), ], ) - |> get_as_number, + |> as_number, content="None", )? } /// Try to get this element as a String -pub fn get_as_string(self : JsonValue) -> Option[String] { +pub fn as_string(self : JsonValue) -> Option[String] { match self { String(s) => Some(s) _ => None @@ -141,26 +150,29 @@ pub fn get_as_string(self : JsonValue) -> Option[String] { } /// Try to get this element as a Json Array and try to get the element at the `index` as a String -pub fn get_item_as_string(self : JsonValue, index : Int) -> Option[String] { - self.get_as_array()?.get(index)?.get_as_string() +/// +/// Same as `item(index)?.as_string()` +pub fn item_as_string(self : JsonValue, index : Int) -> Option[String] { + self.as_array()?.get(index)?.as_string() } /// Try to get this element as a Json Object and try to get the element with the `key` as a String -pub fn get_value_as_string(self : JsonValue, key : String) -> Option[String] { - self.get_as_object()?.lookup(key)?.get_as_string() +/// +/// Same as `value(key)?.as_string()` +pub fn value_as_string(self : JsonValue, key : String) -> Option[String] { + self.as_object()?.lookup(key)?.as_string() } test "get as string" { - inspect(JsonValue::Null |> get_as_string, content="None")? - inspect(JsonValue::Boolean(false) |> get_as_string, content="None")? - inspect(JsonValue::Number(1.0) |> get_as_string, content="None")? + inspect(JsonValue::Null |> as_string, content="None")? + inspect(JsonValue::Boolean(false) |> as_string, content="None")? + inspect(JsonValue::Number(1.0) |> as_string, content="None")? inspect( - JsonValue::String("Hello World") |> get_as_string, + JsonValue::String("Hello World") |> as_string, content="Some(Hello World)", )? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) - |> get_as_string, + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) |> as_string, content="None", )? inspect( @@ -170,13 +182,13 @@ test "get as string" { ("value", JsonValue::Number(100.0)), ], ) - |> get_as_string, + |> as_string, content="None", )? } /// Try to get this element as an Array -pub fn get_as_array(self : JsonValue) -> Option[@vec.Vec[JsonValue]] { +pub fn as_array(self : JsonValue) -> Option[@vec.Vec[JsonValue]] { match self { Array(arr) => Some(arr) _ => None @@ -184,50 +196,53 @@ pub fn get_as_array(self : JsonValue) -> Option[@vec.Vec[JsonValue]] { } /// Try to get this element as a Json Array and try to get the element at the `index` as an Array -pub fn get_item_as_array( +/// +/// Same as `item(index)?.as_array()` +pub fn item_as_array( self : JsonValue, index : Int ) -> Option[@vec.Vec[JsonValue]] { - self.get_as_array()?.get(index)?.get_as_array() + self.as_array()?.get(index)?.as_array() } /// Try to get this element as a Json Object and try to get the element with the `key` as an Array -pub fn get_value_as_array( +/// +/// Same as `value(key)?.as_array()` +pub fn value_as_array( self : JsonValue, key : String ) -> Option[@vec.Vec[JsonValue]] { - self.get_as_object()?.lookup(key)?.get_as_array() + self.as_object()?.lookup(key)?.as_array() } /// Try to get this element as a Json Array and get the element at the `index` as a Json Value -pub fn get_item(self : JsonValue, index : Int) -> Option[JsonValue] { - self.get_as_array()?.get(index) +pub fn item(self : JsonValue, index : Int) -> Option[JsonValue] { + self.as_array()?.get(index) } test "get as array" { - inspect(JsonValue::Null |> get_as_array, content="None")? - inspect(JsonValue::Boolean(false) |> get_as_array, content="None")? - inspect(JsonValue::Number(1.0) |> get_as_array, content="None")? - inspect(JsonValue::String("Hello World") |> get_as_array, content="None")? + inspect(JsonValue::Null |> as_array, content="None")? + inspect(JsonValue::Boolean(false) |> as_array, content="None")? + inspect(JsonValue::Number(1.0) |> as_array, content="None")? + inspect(JsonValue::String("Hello World") |> as_array, content="None")? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) - |> get_as_array, + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) |> as_array, content="Some(Vec::[String(\"Hello World\")])", )? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).get_item_as_string( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).item_as_string( 0, ), content="Some(Hello World)", )? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).get_item_as_string( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).item_as_string( 1, ), content="None", )? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).get_item_as_number( + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).item_as_number( 0, ), content="None", @@ -239,13 +254,13 @@ test "get as array" { ("value", JsonValue::Number(100.0)), ], ) - |> get_as_array, + |> as_array, content="None", )? } /// Try to get this element as an Object -pub fn get_as_object(self : JsonValue) -> Option[@map.Map[String, JsonValue]] { +pub fn as_object(self : JsonValue) -> Option[@map.Map[String, JsonValue]] { match self { Object(obj) => Some(obj) _ => None @@ -253,48 +268,52 @@ pub fn get_as_object(self : JsonValue) -> Option[@map.Map[String, JsonValue]] { } /// Try to get this element as a Json Array and try to get the element at the `index` as an Object -pub fn get_item_as_object( +/// +/// Same as `item(index)?.as_object()` +pub fn item_as_object( self : JsonValue, index : Int ) -> Option[@map.Map[String, JsonValue]] { - self.get_as_array()?.get(index)?.get_as_object() + self.as_array()?.get(index)?.as_object() } /// Try to get this element as a Json Object and try to get the element with the `key` as an Object -pub fn get_value_as_object( +/// +/// Same as `value(key)?.as_object()` +pub fn value_as_object( self : JsonValue, key : String ) -> Option[@map.Map[String, JsonValue]] { - self.get_as_object()?.lookup(key)?.get_as_object() + self.as_object()?.lookup(key)?.as_object() } /// Try to get this element as a Json Object and get the element with the `key` as a Json Value -pub fn get_value(self : JsonValue, key : String) -> Option[JsonValue] { - self.get_as_object()?.lookup(key) +pub fn value(self : JsonValue, key : String) -> Option[JsonValue] { + self.as_object()?.lookup(key) } test "get as object" { inspect( - JsonValue::Null |> get_as_object |> Option::map(@map.Map::to_vec), + JsonValue::Null |> as_object |> Option::map(@map.Map::to_vec), content="None", )? inspect( - JsonValue::Boolean(false) |> get_as_object |> Option::map(@map.Map::to_vec), + JsonValue::Boolean(false) |> as_object |> Option::map(@map.Map::to_vec), content="None", )? inspect( - JsonValue::Number(1.0) |> get_as_object |> Option::map(@map.Map::to_vec), + JsonValue::Number(1.0) |> as_object |> Option::map(@map.Map::to_vec), content="None", )? inspect( JsonValue::String("Hello World") - |> get_as_object + |> as_object |> Option::map(@map.Map::to_vec), content="None", )? inspect( JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]) - |> get_as_object + |> as_object |> Option::map(@map.Map::to_vec), content="None", )? @@ -305,7 +324,7 @@ test "get as object" { ("value", JsonValue::Number(100.0)), ], ) - |> get_as_object + |> as_object |> Option::map(@map.Map::to_vec), content="Some(Vec::[(key, String(\"key\")), (value, Number(100.0))])", )? @@ -315,7 +334,7 @@ test "get as object" { ("key", JsonValue::String("key")), ("value", JsonValue::Number(100.0)), ], - ).get_value_as_string("key"), + ).value_as_string("key"), content="Some(key)", )? inspect( @@ -324,7 +343,7 @@ test "get as object" { ("key", JsonValue::String("key")), ("value", JsonValue::Number(100.0)), ], - ).get_value_as_number("value"), + ).value_as_number("value"), content="Some(100.0)", )? inspect( @@ -333,7 +352,7 @@ test "get as object" { ("key", JsonValue::String("key")), ("value", JsonValue::Number(100.0)), ], - ).get_value_as_number("key"), + ).value_as_number("key"), content="None", )? inspect( @@ -342,7 +361,7 @@ test "get as object" { ("key", JsonValue::String("key")), ("value", JsonValue::Number(100.0)), ], - ).get_value_as_number("asdf"), + ).value_as_number("asdf"), content="None", )? } @@ -372,38 +391,36 @@ test "deep access" { ("obj", JsonValue::Object(@map.Map::[])), ], ) - inspect(json.get_value_as_null("null"), content="Some(())")? + inspect(json.value_as_null("null"), content="Some(())")? inspect( - json.get_value("key").bind(fn { array => array.get_item_as_null(2) }), + json.value("key").bind(fn { array => array.item_as_null(2) }), content="Some(())", )? - inspect(json.get_value_as_bool("bool"), content="Some(false)")? + inspect(json.value_as_bool("bool"), content="Some(false)")? inspect( - json.get_value("key").bind(fn { array => array.get_item_as_bool(1) }), + json.value("key").bind(fn { array => array.item_as_bool(1) }), content="Some(true)", )? inspect( - json.get_value_as_array("key"), + json.value_as_array("key"), content="Some(Vec::[Number(1.0), Boolean(true), Null, Array(Vec::[]), Object(Map::[(\"key\", String(\"value\")), (\"value\", Number(100.0))])])", )? inspect( - json.get_value("key").bind(fn { array => array.get_item_as_array(3) }), + json.value("key").bind(fn { array => array.item_as_array(3) }), content="Some(Vec::[])", )? inspect( - json.get_value("key").bind(fn { array => array.get_item_as_object(4) }).map( + json.value("key").bind(fn { array => array.item_as_object(4) }).map( @map.Map::to_vec, ), content="Some(Vec::[(key, String(\"value\")), (value, Number(100.0))])", )? inspect( - json.get_value_as_object("obj").map(@map.Map::to_vec), + json.value_as_object("obj").map(@map.Map::to_vec), content="Some(Vec::[])", )? inspect( - json.get_value("key").bind(fn { array => array.get_item(4) }).bind( - fn { obj => obj.get_value_as_number("value") }, - ), + (fn() { json.value("key")?.item(4)?.value_as_number("value") })(), content="Some(100.0)", )? } From f63cf1760c3d32a688b66014380e3fc9215537cc Mon Sep 17 00:00:00 2001 From: zihang Date: Tue, 23 Apr 2024 09:50:57 +0800 Subject: [PATCH 10/11] update: mbti --- json/json.mbti | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/json/json.mbti b/json/json.mbti index e637fcc04..18f73af9b 100644 --- a/json/json.mbti +++ b/json/json.mbti @@ -14,29 +14,29 @@ pub enum JsonValue { Array(@vec.Vec[JsonValue]) Object(@map.Map[String, JsonValue]) } +fn JsonValue::as_array(JsonValue) -> Option[@vec.Vec[JsonValue]] +fn JsonValue::as_bool(JsonValue) -> Option[Bool] +fn JsonValue::as_null(JsonValue) -> Option[Unit] +fn JsonValue::as_number(JsonValue) -> Option[Double] +fn JsonValue::as_object(JsonValue) -> Option[@map.Map[String, JsonValue]] +fn JsonValue::as_string(JsonValue) -> Option[String] fn JsonValue::debug_write(JsonValue, Buffer) -> Unit -fn JsonValue::get_as_array(JsonValue) -> Option[@vec.Vec[JsonValue]] -fn JsonValue::get_as_bool(JsonValue) -> Option[Bool] -fn JsonValue::get_as_null(JsonValue) -> Option[Unit] -fn JsonValue::get_as_number(JsonValue) -> Option[Double] -fn JsonValue::get_as_object(JsonValue) -> Option[@map.Map[String, JsonValue]] -fn JsonValue::get_as_string(JsonValue) -> Option[String] -fn JsonValue::get_item(JsonValue, Int) -> Option[JsonValue] -fn JsonValue::get_item_as_array(JsonValue, Int) -> Option[@vec.Vec[JsonValue]] -fn JsonValue::get_item_as_bool(JsonValue, Int) -> Option[Bool] -fn JsonValue::get_item_as_null(JsonValue, Int) -> Option[Unit] -fn JsonValue::get_item_as_number(JsonValue, Int) -> Option[Double] -fn JsonValue::get_item_as_object(JsonValue, Int) -> Option[@map.Map[String, JsonValue]] -fn JsonValue::get_item_as_string(JsonValue, Int) -> Option[String] -fn JsonValue::get_value(JsonValue, String) -> Option[JsonValue] -fn JsonValue::get_value_as_array(JsonValue, String) -> Option[@vec.Vec[JsonValue]] -fn JsonValue::get_value_as_bool(JsonValue, String) -> Option[Bool] -fn JsonValue::get_value_as_null(JsonValue, String) -> Option[Unit] -fn JsonValue::get_value_as_number(JsonValue, String) -> Option[Double] -fn JsonValue::get_value_as_object(JsonValue, String) -> Option[@map.Map[String, JsonValue]] -fn JsonValue::get_value_as_string(JsonValue, String) -> Option[String] +fn JsonValue::item(JsonValue, Int) -> Option[JsonValue] +fn JsonValue::item_as_array(JsonValue, Int) -> Option[@vec.Vec[JsonValue]] +fn JsonValue::item_as_bool(JsonValue, Int) -> Option[Bool] +fn JsonValue::item_as_null(JsonValue, Int) -> Option[Unit] +fn JsonValue::item_as_number(JsonValue, Int) -> Option[Double] +fn JsonValue::item_as_object(JsonValue, Int) -> Option[@map.Map[String, JsonValue]] +fn JsonValue::item_as_string(JsonValue, Int) -> Option[String] fn JsonValue::op_equal(JsonValue, JsonValue) -> Bool fn JsonValue::to_string(JsonValue) -> String +fn JsonValue::value(JsonValue, String) -> Option[JsonValue] +fn JsonValue::value_as_array(JsonValue, String) -> Option[@vec.Vec[JsonValue]] +fn JsonValue::value_as_bool(JsonValue, String) -> Option[Bool] +fn JsonValue::value_as_null(JsonValue, String) -> Option[Unit] +fn JsonValue::value_as_number(JsonValue, String) -> Option[Double] +fn JsonValue::value_as_object(JsonValue, String) -> Option[@map.Map[String, JsonValue]] +fn JsonValue::value_as_string(JsonValue, String) -> Option[String] // Traits From 4bbe287d28e0c53f155cbf7aad57357044e3e1b6 Mon Sep 17 00:00:00 2001 From: zihang Date: Wed, 24 Apr 2024 11:23:39 +0800 Subject: [PATCH 11/11] refactor: simplify api --- json/json.mbt | 134 +++++++------------------------------------------ json/json.mbti | 12 ----- 2 files changed, 19 insertions(+), 127 deletions(-) diff --git a/json/json.mbt b/json/json.mbt index c87bceb3b..aae13b3fd 100644 --- a/json/json.mbt +++ b/json/json.mbt @@ -20,20 +20,6 @@ pub fn as_null(self : JsonValue) -> Option[Unit] { } } -/// Try to get this element as a Json Array and try to get the element at the `index` as a Null -/// -/// Same as `item(index)?.as_null()` -pub fn item_as_null(self : JsonValue, index : Int) -> Option[Unit] { - self.as_array()?.get(index)?.as_null() -} - -/// Try to get this element as a Json Object and try to get the element with the `key` as a Null -/// -/// Same as `value(key)?.as_null()` -pub fn value_as_null(self : JsonValue, key : String) -> Option[Unit] { - self.as_object()?.lookup(key)?.as_null() -} - test "get as null" { inspect(JsonValue::Null |> as_null, content="Some(())")? inspect(JsonValue::Boolean(false) |> as_null, content="None")? @@ -63,20 +49,6 @@ pub fn as_bool(self : JsonValue) -> Option[Bool] { } } -/// Try to get this element as a Json Array and try to get the element at the `index` as a Boolean -/// -/// Same as `item(index)?.as_bool()` -pub fn item_as_bool(self : JsonValue, index : Int) -> Option[Bool] { - self.as_array()?.get(index)?.as_bool() -} - -/// Try to get this element as a Json Object and try to get the element with the `key` as a Boolean -/// -/// Same as `value(key)?.as_bool()` -pub fn value_as_bool(self : JsonValue, key : String) -> Option[Bool] { - self.as_object()?.lookup(key)?.as_bool() -} - test "get as bool" { inspect(JsonValue::Null |> as_bool, content="None")? inspect(JsonValue::Boolean(false) |> as_bool, content="Some(false)")? @@ -106,20 +78,6 @@ pub fn as_number(self : JsonValue) -> Option[Double] { } } -/// Try to get this element as a Json Array and try to get the element at the `index` as a Number -/// -/// Same as `item(index)?.as_number()` -pub fn item_as_number(self : JsonValue, index : Int) -> Option[Double] { - self.as_array()?.get(index)?.as_number() -} - -/// Try to get this element as a Json Object and try to get the element with the `key` as a Number -/// -/// Same as `value(key)?.as_number()` -pub fn value_as_number(self : JsonValue, key : String) -> Option[Double] { - self.as_object()?.lookup(key)?.as_number() -} - test "get as number" { inspect(JsonValue::Null |> as_number, content="None")? inspect(JsonValue::Boolean(false) |> as_number, content="None")? @@ -149,20 +107,6 @@ pub fn as_string(self : JsonValue) -> Option[String] { } } -/// Try to get this element as a Json Array and try to get the element at the `index` as a String -/// -/// Same as `item(index)?.as_string()` -pub fn item_as_string(self : JsonValue, index : Int) -> Option[String] { - self.as_array()?.get(index)?.as_string() -} - -/// Try to get this element as a Json Object and try to get the element with the `key` as a String -/// -/// Same as `value(key)?.as_string()` -pub fn value_as_string(self : JsonValue, key : String) -> Option[String] { - self.as_object()?.lookup(key)?.as_string() -} - test "get as string" { inspect(JsonValue::Null |> as_string, content="None")? inspect(JsonValue::Boolean(false) |> as_string, content="None")? @@ -195,26 +139,6 @@ pub fn as_array(self : JsonValue) -> Option[@vec.Vec[JsonValue]] { } } -/// Try to get this element as a Json Array and try to get the element at the `index` as an Array -/// -/// Same as `item(index)?.as_array()` -pub fn item_as_array( - self : JsonValue, - index : Int -) -> Option[@vec.Vec[JsonValue]] { - self.as_array()?.get(index)?.as_array() -} - -/// Try to get this element as a Json Object and try to get the element with the `key` as an Array -/// -/// Same as `value(key)?.as_array()` -pub fn value_as_array( - self : JsonValue, - key : String -) -> Option[@vec.Vec[JsonValue]] { - self.as_object()?.lookup(key)?.as_array() -} - /// Try to get this element as a Json Array and get the element at the `index` as a Json Value pub fn item(self : JsonValue, index : Int) -> Option[JsonValue] { self.as_array()?.get(index) @@ -230,20 +154,20 @@ test "get as array" { content="Some(Vec::[String(\"Hello World\")])", )? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).item_as_string( - 0, + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).item(0).bind( + as_string, ), content="Some(Hello World)", )? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).item_as_string( - 1, + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).item(1).bind( + as_string, ), content="None", )? inspect( - JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).item_as_number( - 0, + JsonValue::Array(@vec.Vec::[JsonValue::String("Hello World")]).item(0).bind( + as_number, ), content="None", )? @@ -267,26 +191,6 @@ pub fn as_object(self : JsonValue) -> Option[@map.Map[String, JsonValue]] { } } -/// Try to get this element as a Json Array and try to get the element at the `index` as an Object -/// -/// Same as `item(index)?.as_object()` -pub fn item_as_object( - self : JsonValue, - index : Int -) -> Option[@map.Map[String, JsonValue]] { - self.as_array()?.get(index)?.as_object() -} - -/// Try to get this element as a Json Object and try to get the element with the `key` as an Object -/// -/// Same as `value(key)?.as_object()` -pub fn value_as_object( - self : JsonValue, - key : String -) -> Option[@map.Map[String, JsonValue]] { - self.as_object()?.lookup(key)?.as_object() -} - /// Try to get this element as a Json Object and get the element with the `key` as a Json Value pub fn value(self : JsonValue, key : String) -> Option[JsonValue] { self.as_object()?.lookup(key) @@ -334,7 +238,7 @@ test "get as object" { ("key", JsonValue::String("key")), ("value", JsonValue::Number(100.0)), ], - ).value_as_string("key"), + ).value("key").bind(as_string), content="Some(key)", )? inspect( @@ -343,7 +247,7 @@ test "get as object" { ("key", JsonValue::String("key")), ("value", JsonValue::Number(100.0)), ], - ).value_as_number("value"), + ).value("value").bind(as_number), content="Some(100.0)", )? inspect( @@ -352,7 +256,7 @@ test "get as object" { ("key", JsonValue::String("key")), ("value", JsonValue::Number(100.0)), ], - ).value_as_number("key"), + ).value("key").bind(as_number), content="None", )? inspect( @@ -361,7 +265,7 @@ test "get as object" { ("key", JsonValue::String("key")), ("value", JsonValue::Number(100.0)), ], - ).value_as_number("asdf"), + ).value("asdf").bind(as_number), content="None", )? } @@ -391,36 +295,36 @@ test "deep access" { ("obj", JsonValue::Object(@map.Map::[])), ], ) - inspect(json.value_as_null("null"), content="Some(())")? + inspect(json.value("null").bind(as_null), content="Some(())")? inspect( - json.value("key").bind(fn { array => array.item_as_null(2) }), + json.value("key").bind(fn { array => array.item(2) }).bind(as_null), content="Some(())", )? - inspect(json.value_as_bool("bool"), content="Some(false)")? + inspect(json.value("bool").bind(as_bool), content="Some(false)")? inspect( - json.value("key").bind(fn { array => array.item_as_bool(1) }), + json.value("key").bind(fn { array => array.item(1) }).bind(as_bool), content="Some(true)", )? inspect( - json.value_as_array("key"), + json.value("key").bind(as_array), content="Some(Vec::[Number(1.0), Boolean(true), Null, Array(Vec::[]), Object(Map::[(\"key\", String(\"value\")), (\"value\", Number(100.0))])])", )? inspect( - json.value("key").bind(fn { array => array.item_as_array(3) }), + json.value("key").bind(fn { array => array.item(3) }).bind(as_array), content="Some(Vec::[])", )? inspect( - json.value("key").bind(fn { array => array.item_as_object(4) }).map( + json.value("key").bind(fn { array => array.item(4) }).bind(as_object).map( @map.Map::to_vec, ), content="Some(Vec::[(key, String(\"value\")), (value, Number(100.0))])", )? inspect( - json.value_as_object("obj").map(@map.Map::to_vec), + json.value("obj").bind(as_object).map(@map.Map::to_vec), content="Some(Vec::[])", )? inspect( - (fn() { json.value("key")?.item(4)?.value_as_number("value") })(), + (fn() { json.value("key")?.item(4)?.value("value")?.as_number() })(), content="Some(100.0)", )? } diff --git a/json/json.mbti b/json/json.mbti index 18f73af9b..1123d07b2 100644 --- a/json/json.mbti +++ b/json/json.mbti @@ -22,21 +22,9 @@ fn JsonValue::as_object(JsonValue) -> Option[@map.Map[String, JsonValue]] fn JsonValue::as_string(JsonValue) -> Option[String] fn JsonValue::debug_write(JsonValue, Buffer) -> Unit fn JsonValue::item(JsonValue, Int) -> Option[JsonValue] -fn JsonValue::item_as_array(JsonValue, Int) -> Option[@vec.Vec[JsonValue]] -fn JsonValue::item_as_bool(JsonValue, Int) -> Option[Bool] -fn JsonValue::item_as_null(JsonValue, Int) -> Option[Unit] -fn JsonValue::item_as_number(JsonValue, Int) -> Option[Double] -fn JsonValue::item_as_object(JsonValue, Int) -> Option[@map.Map[String, JsonValue]] -fn JsonValue::item_as_string(JsonValue, Int) -> Option[String] fn JsonValue::op_equal(JsonValue, JsonValue) -> Bool fn JsonValue::to_string(JsonValue) -> String fn JsonValue::value(JsonValue, String) -> Option[JsonValue] -fn JsonValue::value_as_array(JsonValue, String) -> Option[@vec.Vec[JsonValue]] -fn JsonValue::value_as_bool(JsonValue, String) -> Option[Bool] -fn JsonValue::value_as_null(JsonValue, String) -> Option[Unit] -fn JsonValue::value_as_number(JsonValue, String) -> Option[Double] -fn JsonValue::value_as_object(JsonValue, String) -> Option[@map.Map[String, JsonValue]] -fn JsonValue::value_as_string(JsonValue, String) -> Option[String] // Traits