diff options
Diffstat (limited to 'aoc2017-gleam/src/helpers/set_state.gleam')
-rw-r--r-- | aoc2017-gleam/src/helpers/set_state.gleam | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/aoc2017-gleam/src/helpers/set_state.gleam b/aoc2017-gleam/src/helpers/set_state.gleam new file mode 100644 index 0000000..cbbad81 --- /dev/null +++ b/aoc2017-gleam/src/helpers/set_state.gleam @@ -0,0 +1,55 @@ +import gleam/erlang/process.{type Subject, Normal} +import gleam/option.{None} +import gleam/otp/actor.{type Next, Continue, Stop} +import gleam/set.{type Set} + +const timeout = 1000 + +pub type Message(k) { + Shutdown + Check(key: k, client: Subject(Bool)) + Add(key: k) + Drop(key: k) + Pop(client: Subject(Result(k, Nil))) +} + +fn handle_message(message: Message(k), set: Set(k)) -> Next(Message(k), Set(k)) { + case message { + Shutdown -> Stop(Normal) + Check(key, client) -> { + process.send(client, set.contains(set, key)) + Continue(set, None) + } + Add(key) -> Continue(set.insert(set, key), None) + Drop(key) -> Continue(set.delete(set, key), None) + Pop(client) -> { + case set.to_list(set) { + [next, ..] -> { + process.send(client, Ok(next)) + Continue(set.delete(set, next), None) + } + [] -> { + process.send(client, Error(Nil)) + Stop(Normal) + } + } + } + } +} + +pub fn start_actor(with: Set(a)) { + let assert Ok(actor) = actor.start(with, handle_message) + actor +} + +pub fn pop(actor) { + process.call(actor, Pop, timeout) +} + +pub fn check(actor, value) { + process.call(actor, Check(value, _), timeout) +} + +pub fn drop(actor, value) { + process.send(actor, Drop(value)) +} |