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:
|
||||
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
|
||||
Path* = seq[Value]
|
||||
Paths* = seq[Path]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Package
|
||||
|
||||
version = "20231013"
|
||||
version = "20231014"
|
||||
author = "Emery Hemingway"
|
||||
description = "Syndicated actors for conversational concurrency"
|
||||
license = "Unlicense"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
import std/unittest
|
||||
import std/[tables, unittest]
|
||||
|
||||
import preserves, syndicate
|
||||
from syndicate/protocols/dataspace import Observe
|
||||
|
@ -34,3 +34,25 @@ test "dictionaries":
|
|||
|
||||
let values = capture(pat, source)
|
||||
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