Skip to content

Commit

Permalink
Merge pull request #19 from NatLabs/dev
Browse files Browse the repository at this point in the history
Merge dev branch
  • Loading branch information
tomijaga authored Sep 28, 2023
2 parents 56a1ff9 + 965ae20 commit ed3efe3
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 187 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/makefile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
npm --yes -g i mocv
- name: Select mocv version
run: mocv use 0.9.4
run: mocv use 0.10.0

- name: install mops
run: |
Expand Down
7 changes: 4 additions & 3 deletions mops.toml
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"
186 changes: 132 additions & 54 deletions readme.md
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`! 🚀
56 changes: 0 additions & 56 deletions src/Candid/Blob/Common.mo

This file was deleted.

Loading

0 comments on commit ed3efe3

Please sign in to comment.