Initial commit

This commit is contained in:
Emery Hemingway 2023-08-25 20:12:49 +01:00
commit 2dde9d75ed
8 changed files with 114 additions and 0 deletions

2
.envrc Normal file
View File

@ -0,0 +1,2 @@
source_env ..
use nix

2
Tuprules.tup Normal file
View File

@ -0,0 +1,2 @@
include ../syndicate-nim/depends.tup
NIM_FLAGS += --path:$(TUP_CWD)/../syndicate-nim/src

5
icalendar_actor.nimble Normal file
View File

@ -0,0 +1,5 @@
bin = @["icalendar_actor"]
license = "Unlicense"
requires: "nim", "syndicate"
srcDir = "src"
version = "20230825"

10
icalendar_components.prs Normal file
View File

@ -0,0 +1,10 @@
version 1.
embeddedType EntityRef.Cap .
Component = [@label string @properties [Property ...] @components [Component ...]].
Property = [@label string @parameters Parameters @type string @values any ...].
Parameters = {symbol: string ...:...}.
CalendarDataspace = <calendar @url string @dataspace #!any>.

5
shell.nix Normal file
View File

@ -0,0 +1,5 @@
let
syndicate = builtins.getFlake "syndicate";
pkgs =
import <nixpkgs> { overlays = (builtins.attrValues syndicate.overlays); };
in pkgs.nim2Packages.syndicate_utils

4
src/Tupfile Normal file
View File

@ -0,0 +1,4 @@
include_rules
: foreach ../*.prs |> !preserves_schema_nim |> {schema}
: icalendar_actor.nim | $(SYNDICATE_PROTOCOL) {schema} |> !nim_bin |> {bin}
: {bin} |> !assert_built |>

60
src/icalendar_actor.nim Normal file
View File

@ -0,0 +1,60 @@
# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[json, sequtils, tables, uri]
import preserves, preserves/jsonhooks, syndicate
from syndicate/protocols/dataspace import Observe
import ./icalendar_components
type Observe = dataspace.Observe[Cap]
type BootArgs {.preservesDictionary.} = object
dataspace: Cap
proc importCalendar(location: string): Component =
let uri = parseUri(location)
if uri.scheme != "file":
raiseAssert """only supported calendar schema is "file" ignoring """ & location
else:
var
js = parseFile(uri.path)
pr = jsonhooks.toPreserveHook(js, void)
if not result.fromPreserve(pr):
# TODO: convert directly from JsonNode
raise newException(ValueError, "Preserves was not a valid iCalendar component")
if result.label != "vcalendar":
raise newException(ValueError, "Preserves was not a valid vcalendar @component")
proc toPreserveHook(prop: Property; E: typedesc): Preserve[E] =
initRecord(prop.label,
prop.parameters.toPreserve(E),
prop.`type`.toPreserve(E),
prop.values.toPreserve(E),
)
proc toPreserveHook(comp: Component; E: typedesc): Preserve[E] =
initRecord(comp.label,
comp.properties.toPreserve(E),
comp.components.toPreserve(E),
)
proc serve(turn: var Turn; url: string): Cap =
let ds = newDataspace(turn)
let calendar = importCalendar(url)
run(turn.facet) do (turn: var Turn):
for prop in calendar.properties:
discard publish(turn, ds, prop)
for comp in calendar.components:
discard publish(turn, ds, comp)
ds
runActor("icalendar_actor") do (root: Cap; turn: var Turn):
connectStdio(root, turn)
stderr.writeLine "connected stdio to ", root
during(turn, root, ?BootArgs) do (ds: Cap):
stderr.writeLine "got dataspace at ", ds
during(turn, ds, ?Observe(pattern: !CalendarDataspace) ?? {0: grabLit()}) do (url: string):
let cap = serve(turn, url)
stderr.writeLine "serving ", url, " at ", cap
discard publish(turn, ds, initRecord("calendar", url.toPreserve(Cap), cap.toPreserve(Cap)))

View File

@ -0,0 +1,26 @@
import
preserves, std/tables
type
CalendarDataspace* {.preservesRecord: "calendar".} = object
`url`*: string
`dataspace`* {.preservesEmbedded.}: Preserve[void]
Property* {.preservesTuple.} = object
`label`*: string
`parameters`*: Parameters
`type`*: string
`values`* {.preservesTupleTail.}: seq[Preserve[void]]
Parameters* = Table[Symbol, string]
Component* {.acyclic, preservesTuple.} = ref object
`label`*: string
`properties`*: seq[Property]
`components`*: seq[Component]
proc `$`*(x: CalendarDataspace | Property | Parameters | Component): string =
`$`(toPreserve(x))
proc encode*(x: CalendarDataspace | Property | Parameters | Component): seq[byte] =
encode(toPreserve(x))