diff --git a/preserves.nimble b/preserves.nimble index cf1676a..68c508f 100644 --- a/preserves.nimble +++ b/preserves.nimble @@ -1,6 +1,6 @@ # Package -version = "20230504" +version = "20230512" author = "Emery Hemingway" description = "data model and serialization format" license = "Unlicense" diff --git a/src/preserves/Tupfile b/src/preserves/Tupfile index aee9354..ba0890c 100644 --- a/src/preserves/Tupfile +++ b/src/preserves/Tupfile @@ -1,3 +1,4 @@ include_rules : foreach preserves_schema_nim.nim schemac.nim |> !nim |> $(BIN_DIR)/%B | $(BIN_DIR)/<%B> +NIM_FLAGS += --path:$(TUP_CWD)/.. : foreach *hooks.nim |> !nim_check |> diff --git a/src/preserves/datehooks.nim b/src/preserves/datehooks.nim new file mode 100644 index 0000000..e9f6f67 --- /dev/null +++ b/src/preserves/datehooks.nim @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: ☭ Emery Hemingway +# SPDX-License-Identifier: Unlicense + +import std/times +import ../preserves + +const + label = "rfc3339" + fullDateFormat = "yyyy-MM-dd" + partialTimeFormat = "HH:mm:ss" + fullTimeFormat = "HH:mm:sszzz" + dateTimeFormat = "yyyy-MM-dd'T'HH:mm:sszzz" + +proc toPreserveHook*(dt: DateTime; E: typedesc): Preserve[E] = + initRecord[E](toSymbol("rfc3339", E), toPreserve($dt, E)) + +proc fromPreserveHook*[E](dt: var DateTime; pr: Preserve[E]): bool = + result = pr.isRecord(label, 1) and pr.record[0].isString + if result: + try: + let + s = pr.record[0].string + n = len(s) + if n == len(fullDateFormat): + dt = parse(s, fullDateFormat) + elif n == len(partialTimeFormat): + dt = parse(s, partialTimeFormat) + elif len(partialTimeFormat) < n and n <= len(fullTimeFormat): + dt = parse(s, fullTimeFormat) + elif len(fullTimeFormat) < n: + dt = parse(s, dateTimeFormat) + else: + result = false + except ValueError: + result = false + +runnableExamples: + import std/[times, unittest] + import preserves + var a, b: DateTime + a = now() + var pr = a.toPreserveHook(void) + check fromPreserveHook(b, pr) + check $a == $b