Skip to content

Commit

Permalink
Use derive(ToJson) where possible
Browse files Browse the repository at this point in the history
Signed-off-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com>
  • Loading branch information
gmlewis committed Aug 22, 2024
1 parent ea80d82 commit 75338aa
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 65 deletions.
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,7 @@ pub fn Add::parse(s : String) -> Add!ParseError {

struct Sum {
sum : Int
}

pub fn to_json(self : Sum) -> Json {
{ "sum": self.sum.to_json() }
}
} derive(ToJson)

pub fn add() -> Int {
let input = @host.input_string()
Expand Down
16 changes: 11 additions & 5 deletions examples/add/add.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,7 @@ pub fn Add::parse(s : String) -> Add!ParseError {

struct Sum {
sum : Int
}

pub fn to_json(self : Sum) -> Json {
{ "sum": self.sum.to_json() }
}
} derive(ToJson)

pub fn add() -> Int {
let input = @host.input_string()
Expand All @@ -61,3 +57,13 @@ pub fn add() -> Int {
@host.output_json_value(json_value)
0 // success
}

test "Sum::to_json works as expected" {
let sum = { sum: 42 }
let got = sum.to_json().stringify()
// See: https://github.com/moonbitlang/core/issues/878
// for trailing ".0" on the integers.
let want =
#|{"sum":42.0}
assert_eq!(got, want)
}
25 changes: 11 additions & 14 deletions examples/arrays/all-three.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,7 @@ pub struct AllThree {
ints : Array[Int]
floats : Array[Double]
strings : Array[String]
} derive(Eq, Show)

fn array_to_json[T](arr : Array[T], ~f : (T) -> Json) -> Json {
Array(arr.map(f))
}

fn to_json(self : AllThree) -> Json {
let { ints, floats, strings } = self
{
"ints": ints |> array_to_json(f=fn { x => Number(x.to_double()) }),
"floats": floats |> array_to_json(f=fn { x => Number(x) }),
"strings": strings |> array_to_json(f=fn { x => String(x) }),
}
}
} derive(Eq, Show, ToJson)

/// `process_all_three` processes all three array types.
pub fn process_all_three(all3 : AllThree) -> AllThree {
Expand All @@ -26,3 +13,13 @@ pub fn process_all_three(all3 : AllThree) -> AllThree {
strings: process_strings(all3.strings),
}
}

test "AllThree::to_json works as expected" {
let all3 = { ints: [1, 2, 3], floats: [1, 2, 3], strings: ["1", "2", "3"] }
let got = all3.to_json().stringify()
// See: https://github.com/moonbitlang/core/issues/878
// for trailing ".0" on the integers.
let want =
#|{"ints":[1.0,2.0,3.0],"floats":[1.0,2.0,3.0],"strings":["1","2","3"]}
assert_eq!(got, want)
}
30 changes: 13 additions & 17 deletions examples/count-vowels/count-vowels.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,18 @@ pub struct VowelReport {
count : Int
total : Int
vowels : String
} derive(Show, Eq)

pub fn to_json(self : VowelReport) -> Json {
{
"count": self.count.to_json(),
"total": self.total.to_json(),
"vowels": self.vowels.to_json(),
}
}
} derive(Show, Eq, ToJson)

fn get_total() -> Int {
match @var.get_int("total") {
Some(total) => total
None => 0
}
@var.get_int("total").or_default()
}

fn store_total(total : Int) -> Unit {
@var.set_int("total", total)
}

fn get_vowels() -> String {
match @config.get("vowels") {
Some(s) => s
None => default_vowels
}
@config.get("vowels").or(default_vowels)
}

/// `count_vowels` reads the input string from the host, reads the "vowels"
Expand All @@ -54,3 +40,13 @@ pub fn count_vowels() -> Int {
{ count, total, vowels }.to_json() |> @host.output_json_value()
0 // success
}

test "VowelReport::to_json works as expected" {
let vowel_report = { count: 1, total: 2, vowels: "some string" }
let got = vowel_report.to_json().stringify()
// See: https://github.com/moonbitlang/core/issues/878
// for trailing ".0" on the integers.
let want =
#|{"count":1.0,"total":2.0,"vowels":"some string"}
assert_eq!(got, want)
}
8 changes: 0 additions & 8 deletions examples/count-vowels/count-vowels_wbtest.mbt
Original file line number Diff line number Diff line change
@@ -1,8 +0,0 @@
test "to_json" {
let got = { count: 1, total: 2, vowels: "some string" }.to_json().stringify()
// See: https://github.com/moonbitlang/core/issues/878
// for trailing ".0" on the integers.
let want =
#|{"count":1.0,"total":2.0,"vowels":"some string"}
assert_eq!(got, want)
}
2 changes: 1 addition & 1 deletion moon.mod.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "extism/moonbit-pdk",
"version": "0.37.0",
"version": "0.38.0",
"deps": {},
"readme": "README.md",
"repository": "https://github.com/extism/moonbit-pdk",
Expand Down
16 changes: 10 additions & 6 deletions pdk/http/header.mbt
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
/// `Header` represents an HTTP Request header.
/// Multiple values for a single key are not deduped.
pub type Header Map[String, String]
pub type Header Map[String, String] derive(Show, Eq, ToJson)

/// `Header::new` returns a new Header.
pub fn Header::new() -> Header {
Header(Map::new())
}

pub fn to_json(self : Header) -> Json {
self.0.to_json()
}

/// `add` adds a value to a named (by `key`) header field.
/// If the header key already exists, the value is appended after a comma.
pub fn add(self : Header, key : String, value : String) -> Unit {
Expand All @@ -25,7 +21,7 @@ pub fn set(self : Header, key : String, value : String) -> Unit {
self.0[key] = value
}

test "add" {
test "Header::add" {
let h = Header::new()
h.add("key1", "one")
h.add("key2", "one")
Expand All @@ -35,3 +31,11 @@ test "add" {
assert_eq!(h.0.get("key1"), Some("one"))
assert_eq!(h.0.get("key2"), Some("one,two,two"))
}

test "Header::to_json works as expected" {
let header : Header = { "key1": "one", "key2": "two" }
let got = header.to_json().stringify()
let want =
#|{"key1":"one","key2":"two"}
assert_eq!(got, want)
}
32 changes: 23 additions & 9 deletions pdk/http/http.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,7 @@ pub struct Request {
method : Method
header : Header
url : String
}

pub fn to_json(self : Request) -> Json {
{
"method": self.method.to_json(),
"header": self.header.to_json(),
"url": self.url.to_json(),
}
}
} derive(ToJson)

/// `Response` represents an HTTP response from the Extism host.
pub struct Response {
Expand Down Expand Up @@ -60,3 +52,25 @@ pub fn send(self : Request, ~body : @host.Memory? = None) -> Response {
pub fn output(self : Response) -> Unit {
@host.output_memory(self.body)
}

test "Request::to_json works as expected" {
let request = {
method: GET,
header: { "key1": "one", "key2": "two" },
url: "https://example.com",
}
let got = request.to_json().stringify()
// See: https://github.com/moonbitlang/core/issues/893
let want =
#|{"method":"GET","header":{"key1":"one","key2":"two"},"url":"https:\/\/example.com"}
assert_eq!(got, want)
}

test "Json::stringify works on strings" {
let url = "https://example.com"
let got = url.to_json().stringify()
// See: https://github.com/moonbitlang/core/issues/893
let want =
#|"https:\/\/example.com"
assert_eq!(got, want)
}
1 change: 1 addition & 0 deletions pdk/http/method.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub enum Method {
PATCH
} derive(Show)

/// `Method::to_json` is required because `derive(ToJson)` generates `{"$tag":"GET"}` here instead of `"GET"`.
pub fn to_json(self : Method) -> Json {
self.to_string().to_json()
}

0 comments on commit 75338aa

Please sign in to comment.