From 86d477136f105f04bfd0dd7c0e939593d81fc581 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Tue, 14 Mar 2023 15:31:45 +0200 Subject: [PATCH] Add support for optional sequences and arrays --- toml_serialization/private/array_reader.nim | 11 ++++++----- toml_serialization/reader.nim | 4 ++++ toml_serialization/types.nim | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/toml_serialization/private/array_reader.nim b/toml_serialization/private/array_reader.nim index 4969200..c49c549 100644 --- a/toml_serialization/private/array_reader.nim +++ b/toml_serialization/private/array_reader.nim @@ -25,8 +25,9 @@ const proc totalArrayFieldsImpl(T: type): int = mixin enumAllSerializedFields + enumAllSerializedFields(T): - when FieldType is (seq or array): + when isArrayLike(FieldType): inc result template totalArrayFields*(T: type): int = @@ -36,9 +37,9 @@ proc makeArrayReadersTable(RecordType, Reader: distinct type, L: static[int]): array[L, ArrayReader[RecordType, Reader]] = var fieldPos = 0 enumAllSerializedFields(RecordType): - when FieldType is (seq or array): - proc readArray(obj: var RecordType, reader: var Reader, idx: int) - {.gcsafe, nimcall, raises: [SerializationError, Defect].} = + when isArrayLike(FieldType): + proc readArrayFieldImpl(obj: var RecordType, reader: var Reader, idx: int) + {.gcsafe, nimcall, raises: [SerializationError, Defect].} = mixin readValue when RecordType is tuple: @@ -59,7 +60,7 @@ proc makeArrayReadersTable(RecordType, Reader: distinct type, L: static[int]): when RecordType is tuple: obj[i] else: field(obj, realFieldName), err) - result[fieldPos] = (0, fieldName, readArray) + result[fieldPos] = (0, fieldName, readArrayFieldImpl) inc fieldPos template arrayReadersTable*(RecordType, Reader: distinct type): auto = diff --git a/toml_serialization/reader.nim b/toml_serialization/reader.nim index 319655a..d096144 100644 --- a/toml_serialization/reader.nim +++ b/toml_serialization/reader.nim @@ -242,6 +242,10 @@ proc readValue*[T](r: var TomlReader, value: var T, numRead: int) readValue(r, value[numRead]) elif T is array: readValue(r, value[numRead]) + elif isOptionalInToml(T): + if value.isNone: + value = some default(typeof(value.get)) + readValue(r, value.get, numRead) else: const typeName = typetraits.name(T) {.error: "Failed to convert from TOML an unsupported type: " & typeName.} diff --git a/toml_serialization/types.nim b/toml_serialization/types.nim index c24c2ca..c615e68 100644 --- a/toml_serialization/types.nim +++ b/toml_serialization/types.nim @@ -116,6 +116,21 @@ type of TomlKind.Table, TomlKind.InlineTable: tableVal*: TomlTableRef +template isOptionalInToml*(T: type): bool = false +template isOptionalInToml*[X](T: type Option[X]): bool = true + +template BaseType*[X](T: type Option[X]): type = X + +template isArrayLike*(T: type): bool = + mixin isOptionalInToml, BaseType + + when T is seq|array: + true + elif isOptionalInToml(T): + BaseType(T) is seq|array + else: + false + when tomlOrderedTable: template withValue*(x: TomlTable, key: string, value, body1, body2: untyped) =