diff --git a/serde/cbor/README.md b/serde/cbor/README.md index f546c4d..1478de1 100644 --- a/serde/cbor/README.md +++ b/serde/cbor/README.md @@ -1,15 +1,18 @@ # nim-serde CBOR -This README details the usage of CBOR serialization and deserialization features offered by nim-serde, in compliance with [RFC 8949](https://datatracker.ietf.org/doc/html/rfc8949). +The CBOR module in nim-serde provides serialization and deserialization for Nim values following [RFC 8949](https://www.rfc-editor.org/rfc/rfc8949.html). Unlike the JSON implementation, CBOR offers a stream-based API that enables direct binary serialization without intermediate representations. + +> Note: While the JSON implementation supports serde modes via pragmas, the current CBOR implementation does not support the `serialize` and `deserialize` pragmas. The library will raise an assertion error if you try to use these pragmas with CBOR serialization. + ## Table of Contents - [nim-serde CBOR](#nim-serde-cbor) - [Table of Contents](#table-of-contents) - [Serialization API](#serialization-api) - - [Basic Serialization with Stream API](#basic-serialization-with-stream-api) - - [Object Serialization](#object-serialization) - - [Custom Type Serialization](#custom-type-serialization) - - [Converting to CBOR with `toCbor`](#converting-to-cbor-with-tocbor) + - [Stream API: Primitive Type and Sequence Serialization](#stream-api-primitive-type-and-sequence-serialization) + - [Stream API: Object Serialization](#stream-api-object-serialization) + - [Stream API: Custom Type Serialization](#stream-api-custom-type-serialization) + - [Serialization without Stream API: `toCbor`](#serialization-without-stream-api-tocbor) - [Working with CborNode](#working-with-cbornode) - [Convenience Functions for CborNode](#convenience-functions-for-cbornode) - [Deserialization API](#deserialization-api) @@ -24,7 +27,7 @@ This README details the usage of CBOR serialization and deserialization features The nim-serde CBOR serialization API provides several ways to convert Nim values to CBOR. -### Basic Serialization with Stream API +### Stream API: Primitive Type and Sequence Serialization The `writeCbor` function writes Nim values to a stream in CBOR format: @@ -50,7 +53,7 @@ discard stream.writeCbor(@[1, 2, 3]) # Sequence let cborData = stream.data ``` -### Object Serialization +### Stream API: Object Serialization Objects can be serialized to CBOR format using the stream API: @@ -78,7 +81,7 @@ discard stream.writeCbor(person) let cborData = stream.data ``` -### Custom Type Serialization +### Stream API: Custom Type Serialization You can extend nim-serde to support custom types by defining your own `writeCbor` procs: @@ -114,7 +117,7 @@ discard userStream.writeCbor(user) let userCborData = userStream.data ``` -### Converting to CBOR with `toCbor` +### Serialization without Stream API: `toCbor` The `toCbor` function can be used to directly convert a Nim value to CBOR binary data: @@ -363,7 +366,7 @@ For deserialization, the library parses CBOR data into a `CborNode` representati ### Current Limitations -While the JSON implementation supports serde modes via pragmas, the current CBOR implementation does not support the `serialize` and `deserialize` pragmas. The library will raise an assertion error if you try to use these pragmas with CBOR serialization. +This implementation does not support the `serialize` and `deserialize` pragmas. The library will raise an assertion error if you try to use these pragmas with CBOR serialization. ```nim import pkg/serde/cbor diff --git a/serde/cbor/helpers.nim b/serde/cbor/helpers.nim index dc26430..5dc6176 100644 --- a/serde/cbor/helpers.nim +++ b/serde/cbor/helpers.nim @@ -36,10 +36,6 @@ template assertNoPragma*(value, pragma, msg) = when value.hasCustomPragma(pragma): raiseAssert(msg) -macro dot*(obj: object, fld: string): untyped = - ## Turn ``obj.dot("fld")`` into ``obj.fld``. - newDotExpr(obj, newIdentNode(fld.strVal)) - func floatSingle*(half: uint16): float32 = ## Convert a 16-bit float to 32-bits. func ldexp( diff --git a/serde/json/README.md b/serde/json/README.md index 9aa0af9..cdc036c 100644 --- a/serde/json/README.md +++ b/serde/json/README.md @@ -1,17 +1,22 @@ # nim-serde JSON -Explore JSON serialization and deserialization using nim-serde, an improved alternative to `std/json`. +The JSON module in nim-serde provides serialization and deserialization for Nim values, offering an improved alternative to the standard `std/json` library. Unlike the standard library, nim-serde JSON implements a flexible system of serialization/deserialization modes that give developers precise control over how Nim objects are converted to and from JSON. ## Table of Contents - [nim-serde JSON](#nim-serde-json) - [Table of Contents](#table-of-contents) + - [Serde Modes](#serde-modes) + - [Modes Overview](#modes-overview) + - [Default Modes](#default-modes) + - [Field Options](#field-options) - [Serialization API](#serialization-api) - [Basic Serialization with `%` operator](#basic-serialization-with--operator) - [Object Serialization](#object-serialization) - - [Serialization with `%*`](#serialization-with-) + - [Inlining JSON Directly in Code with `%*`](#inlining-json-directly-in-code-with-) - [Converting to JSON String with `toJson`](#converting-to-json-string-with-tojson) - [Serialization Modes](#serialization-modes) - [Field Customization for Serialization](#field-customization-for-serialization) + - [Custom Type Serialization](#custom-type-serialization) - [Deserialization API](#deserialization-api) - [Basic Deserialization with `fromJson`](#basic-deserialization-with-fromjson) - [Error Handling](#error-handling) @@ -19,9 +24,111 @@ Explore JSON serialization and deserialization using nim-serde, an improved alte - [Deserialization Modes](#deserialization-modes) - [Field Customization for Deserialization](#field-customization-for-deserialization) - [Using as a Drop-in Replacement for std/json](#using-as-a-drop-in-replacement-for-stdjson) - - [Custom Type Serialization](#custom-type-serialization) - [Implementation Details](#implementation-details) + +## Serde Modes +This implementation supports three different modes to control de/serialization: + +```nim +OptIn +OptOut +Strict +``` + +Modes can be set in the `{.serialize.}` and/or `{.deserialize.}` pragmas on type +definitions. Each mode has a different meaning depending on if the type is being +serialized or deserialized. Modes can be set by setting `mode` in the `serialize` or +`deserialize` pragma annotation, eg: + +```nim +type MyType {.serialize(mode=Strict).} = object + field1: bool + field2: bool +``` + +### Modes Overview + +| Mode | Serialize | Deserialize | +|:-----|:----------|:------------| +| `OptOut` | All object fields will be serialized, except fields marked with `{.serialize(ignore=true).}`. | All JSON keys will be deserialized, except fields marked with `{.deserialize(ignore=true).}`. No error if extra JSON fields exist. | +| `OptIn` | Only fields marked with `{.serialize.}` will be serialized. Fields marked with `{.serialize(ignore=true).}` will not be serialized. | Only fields marked with `{.deserialize.}` will be deserialized. Fields marked with `{.deserialize(ignore=true).}` will not be deserialized. A `SerdeError` is raised if the field is missing in JSON. | +| `Strict` | All object fields will be serialized, regardless if the field is marked with `{.serialize(ignore=true).}`. | Object fields and JSON fields must match exactly, otherwise a `SerdeError` is raised. | + +### Default Modes + +Types can be serialized and deserialized even without explicit annotations, using default modes. Without any pragmas, types are serialized in OptIn mode and deserialized in OptOut mode. When types have pragmas but no specific mode is set, OptOut mode is used for both serialization and deserialization. + + +| Context | Serialize | Deserialize | +|:--------|:----------|:------------| +| Default (no pragma) | `OptIn` | `OptOut` | +| Default (pragma, but no mode) | `OptOut` | `OptOut` | + +```nim +# Type is not annotated +# A default mode of OptIn (for serialize) and OptOut (for deserialize) is assumed. +type MyObj1 = object + field1: bool + field2: bool + +# Type is annotated, but mode not specified +# A default mode of OptOut is assumed for both serialize and deserialize. +type MyObj2 {.serialize, deserialize.} = object + field1: bool + field2: bool +``` + +### Field Options + +Individual fields can be customized using the `{.serialize.}` and `{.deserialize.}` pragmas with additional options that control how each field is processed during serialization and deserialization + + +| | serialize | deserialize | +|:---------|:-----------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------| +| `key` | aliases the field name in json | deserializes the field if json contains `key` | +| `ignore` |