mirror of
https://github.com/logos-storage/nim-serde.git
synced 2026-01-05 23:23:12 +00:00
132 lines
3.7 KiB
Markdown
132 lines
3.7 KiB
Markdown
# nim-serde
|
|
|
|
A serialization and deserialization library for Nim supporting multiple formats.
|
|
|
|
## Supported Serialization Formats
|
|
|
|
nim-serde currently supports the following serialization formats:
|
|
|
|
- **JSON**: A text-based data interchange format. [See JSON](serde/json/README.md) for details.
|
|
- **CBOR**: A binary data format following RFC 8949. [See CBOR](serde/cbor/README.md) for details.
|
|
|
|
## Quick Examples
|
|
|
|
### JSON Serialization and Deserialization
|
|
|
|
```nim
|
|
import ./serde/json
|
|
import questionable/results
|
|
|
|
# Define a type
|
|
type Person = object
|
|
name {.serialize.}: string
|
|
age {.serialize.}: int
|
|
address: string # By default, serde will not serialize non-annotated fields (OptIn mode)
|
|
|
|
# Create an instance
|
|
let person = Person(name: "John Doe", age: 30, address: "123 Main St")
|
|
|
|
# Serialization
|
|
echo "JSON Serialization Example"
|
|
let jsonString = person.toJson(pretty = true)
|
|
echo jsonString
|
|
|
|
# Verify serialization output
|
|
let expectedJson = """{
|
|
"name": "John Doe",
|
|
"age": 30
|
|
}"""
|
|
assert jsonString == expectedJson
|
|
|
|
# Deserialization
|
|
echo "\nJSON Deserialization Example"
|
|
let jsonData = """{"name":"Jane Doe","age":28,"address":"456 Oak Ave"}"""
|
|
let result = Person.fromJson(jsonData)
|
|
|
|
# check if deserialization was successful
|
|
assert result.isSuccess
|
|
|
|
# get the deserialized value
|
|
let parsedPerson = !result
|
|
|
|
echo parsedPerson
|
|
#[
|
|
Expected Output:
|
|
Person(
|
|
name: "Jane Doe",
|
|
age: 28,
|
|
address: "456 Oak Ave"
|
|
)
|
|
]#
|
|
|
|
```
|
|
|
|
### CBOR Serialization and Deserialization
|
|
|
|
```nim
|
|
import ./serde/cbor
|
|
import questionable/results
|
|
import std/streams
|
|
|
|
# Define a type
|
|
type Person = object
|
|
name: string # Unlike JSON, CBOR always serializes all fields, and they do not need to be annotated
|
|
age: int
|
|
address: string
|
|
|
|
# Create an instance
|
|
let person = Person(name: "John Doe", age: 30, address: "123 Main St")
|
|
|
|
# Serialization using Stream API
|
|
echo "CBOR Stream API Serialization"
|
|
let stream = newStringStream()
|
|
let writeResult = stream.writeCbor(person)
|
|
assert writeResult.isSuccess
|
|
|
|
# Serialization using toCbor function
|
|
echo "\nCBOR toCbor Function Serialization"
|
|
let cborResult = toCbor(person)
|
|
assert cborResult.isSuccess
|
|
|
|
let serializedCbor = !cborResult
|
|
|
|
# Deserialization
|
|
echo "\nCBOR Deserialization"
|
|
let personResult = Person.fromCbor(serializedCbor)
|
|
|
|
# check if deserialization was successful
|
|
assert personResult.isSuccess
|
|
|
|
# get the deserialized value
|
|
let parsedPerson = !personResult
|
|
echo parsedPerson
|
|
|
|
#[
|
|
Expected Output:
|
|
Person(
|
|
name: "John Doe",
|
|
age: 30,
|
|
address: "123 Main St"
|
|
)
|
|
]#
|
|
|
|
```
|
|
|
|
Refer to the [json](serde/json/README.md) and [cbor](serde/cbor/README.md) files for more comprehensive examples.
|
|
|
|
## Known Issues
|
|
|
|
There is a known issue when using mixins with generic overloaded procs like `fromJson`. At the time of mixin call, only the `fromJson` overloads in scope of the called mixin are available to be dispatched at runtime. There could be other `fromJson` overloads declared in other modules, but are not in scope at the time the mixin was called.
|
|
|
|
Therefore, anytime `fromJson` is called targeting a declared overload, it may or may not be dispatchable. This can be worked around by forcing the `fromJson` overload into scope at compile time. For example, in your application where the `fromJson` overload is defined, at the bottom of the module add:
|
|
|
|
```nim
|
|
static: MyType.fromJson("")
|
|
```
|
|
|
|
This will ensure that the `MyType.fromJson` overload is dispatchable.
|
|
|
|
The basic types that serde supports should already have their overloads forced in scope in [the `deserializer` module](./serde/json/deserializer.nim#L340-L356).
|
|
|
|
For an illustration of the problem, please see this [narrow example](https://github.com/gmega/serialization-bug/tree/main/narrow) by [@gmega](https://github.com/gmega).
|