patterns: add Literal[T] type for literal capture
This commit is contained in:
parent
3a04fc195b
commit
4a6e95bbce
|
@ -289,6 +289,43 @@ proc grabDictionary*(bindings: sink openArray[(string, Pattern)]): Pattern =
|
||||||
for (key, val) in bindings.items:
|
for (key, val) in bindings.items:
|
||||||
result.dcompound.dict.entries[key.toSymbol(Cap)] = val
|
result.dcompound.dict.entries[key.toSymbol(Cap)] = val
|
||||||
|
|
||||||
|
func depattern(comp: DCompound): Preserve[Cap]
|
||||||
|
|
||||||
|
func depattern(pat: Pattern): Preserve[Cap] =
|
||||||
|
case pat.orKind
|
||||||
|
of PatternKind.DDiscard, PatternKind.DBind:
|
||||||
|
discard
|
||||||
|
of PatternKind.DLit:
|
||||||
|
result = pat.dlit.value.toPreserve(Cap)
|
||||||
|
of PatternKind.DCompound:
|
||||||
|
result = depattern(pat.dcompound)
|
||||||
|
|
||||||
|
func depattern(comp: DCompound): Preserve[Cap] =
|
||||||
|
case comp.orKind
|
||||||
|
of DCompoundKind.rec:
|
||||||
|
result = initRecord(comp.rec.label, comp.rec.fields.len)
|
||||||
|
for i, f in comp.rec.fields:
|
||||||
|
result[i] = depattern(f)
|
||||||
|
of DCompoundKind.arr:
|
||||||
|
result = initSequence(comp.arr.items.len, Cap)
|
||||||
|
for i, e in comp.arr.items:
|
||||||
|
result[i] = depattern(e)
|
||||||
|
of DCompoundKind.dict:
|
||||||
|
result = initDictionary(Cap)
|
||||||
|
for key, val in comp.dict.entries:
|
||||||
|
result[key] = depattern(val)
|
||||||
|
|
||||||
|
type Literal*[T] = object
|
||||||
|
## A wrapper type to deserialize patterns to native values.
|
||||||
|
value*: T
|
||||||
|
|
||||||
|
proc fromPreserveHook*[T, E](lit: var Literal[T]; pr: Preserve[E]): bool =
|
||||||
|
var pat: Pattern
|
||||||
|
pat.fromPreserve(pr) and lit.value.fromPreserve(depattern pat)
|
||||||
|
|
||||||
|
proc toPreserveHook*[T](lit: Literal[T]; E: typedesc): Preserve[E] =
|
||||||
|
lit.grab.toPreserve(E)
|
||||||
|
|
||||||
type
|
type
|
||||||
Path* = seq[Value]
|
Path* = seq[Value]
|
||||||
Paths* = seq[Path]
|
Paths* = seq[Path]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "20231013"
|
version = "20231014"
|
||||||
author = "Emery Hemingway"
|
author = "Emery Hemingway"
|
||||||
description = "Syndicated actors for conversational concurrency"
|
description = "Syndicated actors for conversational concurrency"
|
||||||
license = "Unlicense"
|
license = "Unlicense"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/unittest
|
import std/[tables, unittest]
|
||||||
|
|
||||||
import preserves, syndicate
|
import preserves, syndicate
|
||||||
from syndicate/protocols/dataspace import Observe
|
from syndicate/protocols/dataspace import Observe
|
||||||
|
@ -34,3 +34,25 @@ test "dictionaries":
|
||||||
|
|
||||||
let values = capture(pat, source)
|
let values = capture(pat, source)
|
||||||
check $values == "@[1, 2, 3]"
|
check $values == "@[1, 2, 3]"
|
||||||
|
|
||||||
|
type
|
||||||
|
File {.preservesDictionary.} = object
|
||||||
|
name: string
|
||||||
|
path: string
|
||||||
|
size: BiggestInt
|
||||||
|
`type`: string
|
||||||
|
Files = Table[Symbol, File]
|
||||||
|
Fields = Table[Symbol, string]
|
||||||
|
|
||||||
|
Request {.preservesRecord: "request".} = object
|
||||||
|
seq: BiggestInt
|
||||||
|
fields: Fields
|
||||||
|
files: Files
|
||||||
|
|
||||||
|
test "literals":
|
||||||
|
const txt = """<rec request [<lit 3> <dict {artists: <lit "kyyyyym"> date: <lit "2023-10-14"> notes: <lit "Lots of stuff"> title: <lit "Domes show">}> <dict {front-cover: <dict {name: <lit "ADULT_TIME_Glielmi.jpg"> path: <lit "/tmp/652adad1b3d2b666dcc8d857.jpg"> size: <lit 255614> type: <lit "image/jpeg">}>}>]>"""
|
||||||
|
var pr = parsePreserves(txt, Cap)
|
||||||
|
|
||||||
|
var capture: Literal[Request]
|
||||||
|
check capture.fromPreserve(pr)
|
||||||
|
echo capture.value
|
||||||
|
|
Loading…
Reference in New Issue