patterns: add Literal[T] type for literal capture

This commit is contained in:
Emery Hemingway 2023-10-15 12:11:10 +01:00
parent 3a04fc195b
commit 4a6e95bbce
3 changed files with 61 additions and 2 deletions

View File

@ -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]

View File

@ -1,6 +1,6 @@
# Package
version = "20231013"
version = "20231014"
author = "Emery Hemingway"
description = "Syndicated actors for conversational concurrency"
license = "Unlicense"

View File

@ -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