Skip to content

Instantly share code, notes, and snippets.

@Freezerburn
Last active December 28, 2015 11:39
Show Gist options
  • Save Freezerburn/7494922 to your computer and use it in GitHub Desktop.
Save Freezerburn/7494922 to your computer and use it in GitHub Desktop.
Porting bacon.js
type
TBaconRet* = enum
BaconMore,
BaconEnd
TBaconEventType* = enum
BaconEventNext,
BaconEventEnd,
BaconEventError,
BaconEventInitial
TBaconEvent*[T] = object
case kind: tbaconeventtype
of BaconEventNext, BaconEventInitial:
value: T
of BaconEventEnd:
nil
of BaconEventError:
error: string
TValueProc*[T] = proc(value: T): TBaconRet {.nimcall.}
TEventProc*[T] = proc(value: TBaconEvent[T]): TBaconRet {.nimcall.}
TBaconPusher[T] = object
pushTo: seq[TValueProc[T]]
subs: seq[TEventProc[T]]
TEventStream*[T] = object
pusher: TBaconPusher[T]
values: seq[T]
proc initialEvent*[T](value: T): TBaconEvent[T] =
return TBaconEvent[T](kind: BaconEventInitial, value: value)
proc nextEvent*[T](value: T): TBaconEvent[T] =
return TBaconEvent[T](kind: BaconEventNext, value: value)
proc endEvent*[T](): TBaconEvent[T] =
return TBaconEvent[T](kind: BaconEventEnd)
proc errorEvent*[T](error: string): TBaconEvent[T] =
return TBaconEvent[T](kind: BaconEventError, error: error)
proc isNext*(e: TBaconEvent): bool =
result = e.kind == BaconEventNext
proc isInitial*(e: TBaconEvent): bool =
result = e.kind == BaconEventInitial
proc isError*(e: TBaconEvent): bool =
result = e.kind == BaconEventError
proc isEnd*(e: TBaconEvent): bool =
result = e.kind == BaconEventEnd
proc push[T](pusher: TBaconPusher, value: T) =
for f in pusher.pushTo:
discard f(value)
for f in pusher.subs:
discard f(nextEvent[T](value))
proc drain[T](stream: var TEventStream[T]) =
for v in stream.values:
#stream.pusher.push(v)
push(stream.pusher, v)
stream.values = @[]
proc fromSeq*[T](values: seq[T]): TEventStream[T] =
TEventStream[T](pusher: TBaconPusher[T](pushTo: @[], subs: @[]), values: values)
proc onValue*[T](stream: var TEventStream[T], f: TValueProc[T]) =
stream.pusher.pushTo.add(f)
stream.drain()
when isMainModule:
let nextTest = nextEvent[int](10)
echo($nextTest)
if not nextTest.isNext:
echo("nextTest: does not detect next correctly")
elif nextTest.value != 10:
echo("nextTest: did not store value correctly")
else:
echo("nextTest: ran correctly")
let endTest = endEvent[int]()
echo($endTest)
let fromSeqTest = fromSeq[int](@[1, 2, 3])
#fromSeqTest.onValue(proc(val: int): TBaconEvent =
onValue[int](fromSeqTest, proc(val: int): TBaconEvent =
echo("onValue: ", $val)
return BaconMore)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment