-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from NatLabs/dev
Merge dev branch
- Loading branch information
Showing
9 changed files
with
285 additions
and
187 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,15 @@ | ||
[package] | ||
name = "serde" | ||
version = "2.0.1" | ||
version = "2.0.4" | ||
description = "A serialisation and deserialisation library for Motoko." | ||
repository = "https://github.com/NatLabs/serde" | ||
keywords = [ "json", "candid", "parser", "urlencoded", "serialization" ] | ||
|
||
[dependencies] | ||
base = "0.7.4" | ||
base = "0.10.0" | ||
itertools = "0.1.2" | ||
candid = "1.0.2" | ||
xtended-numbers = "0.2.1" | ||
json = "https://github.com/aviate-labs/json.mo#v0.2.0" | ||
parser-combinators = "https://github.com/aviate-labs/parser-combinators.mo#v0.1.2" | ||
parser-combinators = "https://github.com/aviate-labs/parser-combinators.mo#v0.1.2" | ||
map = "9.0.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,165 @@ | ||
# serde | ||
# `serde` for Motoko | ||
|
||
A serialisation and deserialisation library for Motoko. | ||
An efficient serialization and deserialization library for Motoko. | ||
|
||
[Motoko Playground Demo](https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/?tag=3196250840) | ||
<!-- 👉 [Demo on Motoko Playground](https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/?tag=3196250840) --> | ||
|
||
## Installation | ||
- Install [mops](https://j4mwm-bqaaa-aaaam-qajbq-cai.ic0.app/#/docs/install) | ||
- Run `mops install serde`, in your project directory | ||
## Getting Started | ||
|
||
## Usage | ||
#### Import statement | ||
### Installation | ||
|
||
1. Install [`mops`](https://j4mwm-bqaaa-aaaam-qajbq-cai.ic0.app/#/docs/install). | ||
2. Inside your project directory, run: | ||
```bash | ||
mops install serde | ||
``` | ||
|
||
### Usage | ||
|
||
To start, import the necessary modules: | ||
```motoko | ||
import { JSON; Candid; UrlEncoded } "mo:serde"; | ||
import { JSON; Candid; UrlEncoded } from "mo:serde"; | ||
``` | ||
|
||
#### JSON | ||
> The API for all serde module is the same, so the following code can be used for converting data between the other modules (Candid and URL-Encoded Pairs). | ||
**Example: JSON to Motoko** | ||
|
||
1. **Defining Data Type**: This critical step informs the conversion functions (`from_candid`` and `to_candid`) about how to handle the data. | ||
|
||
Consider the following JSON data: | ||
```json | ||
[ | ||
{ | ||
"name": "John", | ||
"id": 123 | ||
}, | ||
{ | ||
"name": "Jane", | ||
"id": 456, | ||
"email": "jane@gmail.com" | ||
} | ||
] | ||
``` | ||
|
||
- Converting a specific data type, for example `User`: | ||
```motoko | ||
type User = { | ||
name: Text; | ||
id: Nat; | ||
email: ?Text; | ||
}; | ||
``` | ||
|
||
- JSON to Motoko | ||
```motoko | ||
let blob = JSON.fromText("{\"name\": \"bar\", \"id\": 112}", null); | ||
let user : ?User = from_candid(blob); | ||
The optional `email` field translates to: | ||
|
||
```motoko | ||
type User = { | ||
name: Text; | ||
id: Nat; | ||
email: ?Text; | ||
}; | ||
``` | ||
|
||
assert user == ?{ name = "bar"; id = 112; email = null }; | ||
``` | ||
2. **Conversion**: | ||
a. Parse JSON text into a candid blob using `JSON.fromText`. | ||
b. Convert the blob to a Motoko data type with `from_candid`. | ||
|
||
```motoko | ||
let jsonText = "[{\"name\": \"John\", \"id\": 123}, {\"name\": \"Jane\", \"id\": 456, \"email\": \"jane@gmail.com\"}]"; | ||
let #ok(blob) = JSON.fromText(jsonText, null); // you probably want to handle the error case here :) | ||
let users : ?[User] = from_candid(blob); | ||
assert users == ?[ | ||
{ | ||
name = "John"; | ||
id = 123; | ||
email = null; | ||
}, | ||
{ | ||
name = "Jane"; | ||
id = 456; | ||
email = ?"jane@gmail.com"; | ||
}, | ||
]; | ||
``` | ||
|
||
- Motoko to JSON | ||
```motoko | ||
let UserKeys = ["name", "id", "email"]; | ||
**Example: Motoko to JSON** | ||
|
||
let user : User = { name = "bar"; id = 112; email = null }; | ||
let blob = to_candid(user); | ||
let json = JSON.toText(blob, UserKeys, null); | ||
1. **Record Keys**: Collect all unique record keys from your data type into an array. This helps the module convert the record keys correctly instead of returning its hash. | ||
|
||
```motoko | ||
let UserKeys = ["name", "id", "email"]; | ||
``` | ||
|
||
assert json == "{\"name\": \"bar\", \"id\": 112, \"email\": null}"; | ||
2. **Conversion**: | ||
|
||
```motoko | ||
let users: [User] = [ | ||
{ | ||
name = "John"; | ||
id = 123; | ||
email = null; | ||
}, | ||
{ | ||
name = "Jane"; | ||
id = 456; | ||
email = ?"jane@gmail.com"; | ||
}, | ||
]; | ||
let blob = to_candid(users); | ||
let json_result = JSON.toText(blob, UserKeys, null); | ||
assert json_result == #ok( | ||
"[{\"name\": \"John\",\"id\": 123},{\"name\": \"Jane\",\"id\":456,\"email\":\"jane@gmail.com\"}]" | ||
); | ||
``` | ||
|
||
- Renaming field keys (Useful for fields with reserved keywords in Motoko ) | ||
**Example: Renaming Fields** | ||
|
||
- Useful way to rename fields with reserved keywords in Motoko. | ||
|
||
```motoko | ||
import Serde "mo:serde"; | ||
import Serde from "mo:serde"; | ||
// type JsonItemSchemaWithReservedKeys = { | ||
// type JsonSchemaWithReservedKeys = { | ||
// type: Text; // reserved | ||
// label: Text; // reserved | ||
// id: Nat; | ||
// }; | ||
type Item = { | ||
item_type: Text; | ||
item_label: Text; | ||
id: Nat | ||
}; | ||
type Item = { | ||
item_type: Text; | ||
item_label: Text; | ||
id: Nat | ||
}; | ||
let jsonText = "{\"type\": \"bar\", \"label\": \"foo\", \"id\": 112}"; | ||
let options : Serde.Options = { | ||
renameKeys = [("type", "item_type"), ("label", "item_label")] | ||
}; | ||
let jsonText = "{\"type\": \"bar\", \"label\": \"foo\", \"id\": 112}"; | ||
let options: Serde.Options = { | ||
renameKeys = [("type", "item_type"), ("label", "item_label")] | ||
}; | ||
let blob = Serde.JSON.fromText(jsonText, ?options); | ||
let renamedKeys : ?Item = from_candid(blob); | ||
let #ok(blob) = Serde.JSON.fromText(jsonText, ?options); | ||
let renamedKeys: ?Item = from_candid(blob); | ||
assert renamedKeys == ?{ item_type = "bar"; item_label = "foo"; id = 112 }; | ||
assert renamedKeys == ?{ item_type = "bar"; item_label = "foo"; id = 112 }; | ||
``` | ||
For more usage examples see [usage.md](https://github.com/NatLabs/serde/blob/main/usage.md): | ||
|
||
Checkout the [usage guide](https://github.com/NatLabs/serde/blob/main/usage.md) for additional examples: | ||
- [Candid Text](https://github.com/NatLabs/serde/blob/main/usage.md#candid-text) | ||
- [URL-Encoded Pairs](https://github.com/NatLabs/serde/blob/main/usage.md#url-encoded-pairs) | ||
|
||
## Limitations | ||
- Requires that the user provides a list of record keys and variant names when converting from Motoko. This is because the candid format used for serializing Motoko stores record keys as their hash, making it impossible to retrieve the original key names. | ||
- Does not have specific syntax to support the conversion between `Blob`, `Principal`, and Bounded `Nat`/`Int` types. | ||
|
||
- Users must provide a list of record keys and variant names during conversions from Motoko to other data formats due to constraints in the candid format. | ||
- Lack of specific syntax for conversion between `Blob`, `Principal`, and bounded `Nat`/`Int` types. | ||
|
||
## Running Tests | ||
|
||
1. Install dependencies: | ||
- [mops](https://j4mwm-bqaaa-aaaam-qajbq-cai.ic0.app/#/docs/install) | ||
- [mocv](https://github.com/ZenVoich/mocv) | ||
- [wasmtime](https://github.com/bytecodealliance/wasmtime/blob/main/README.md#wasmtime) | ||
|
||
2. Inside the project directory, run: | ||
```bash | ||
mops test | ||
``` | ||
|
||
## Tests | ||
- Install [mops](https://j4mwm-bqaaa-aaaam-qajbq-cai.ic0.app/#/docs/install) | ||
- Install [mocv](https://github.com/ZenVoich/mocv) | ||
- Install [wasmtime](https://github.com/bytecodealliance/wasmtime/blob/main/README.md#wasmtime) | ||
--- | ||
|
||
- Run `mops test` in the project directory | ||
Happy coding with `serde`! 🚀 |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.