-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtodo_server.ex
More file actions
78 lines (62 loc) · 1.8 KB
/
todo_server.ex
File metadata and controls
78 lines (62 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
defmodule TodoServer do
# Client side
def start do
spawn(fn -> loop(TodoList.new()) end)
end
def add_entry(todo_server, new_entry) do
send(todo_server, {:add_entry, new_entry})
end
def delete_entry(todo_server, entry_id) do
send(todo_server, {:delete_entry, entry_id})
end
def entries(todo_server, date) do
send(todo_server, {:entries, self(), date})
receive do
{:todo_entries, entries} -> entries
after
5000 -> {:error, :timeout}
end
end
# Server side
defp loop(todo_list) do
new_todo_list =
receive do
message -> process_message(todo_list, message)
end
loop(new_todo_list)
end
defp process_message(todo_list, {:add_entry, new_entry}) do
TodoList.add_entry(todo_list, new_entry)
end
defp process_message(todo_list, {:delete_entry, entry_id}) do
TodoList.delete_entry(todo_list, entry_id)
end
defp process_message(todo_list, {:entries, caller, date}) do
send(caller, {:todo_entries, TodoList.entries(todo_list, date)})
todo_list
end
defp process_message(todo_list, _), do: todo_list
end
defmodule TodoList do
defstruct auto_id: 1, entries: %{}
def new(entries \\ []) do
Enum.reduce(
entries,
%TodoList{},
&add_entry(&2, &1)
)
end
def add_entry(todo_list, entry) do
entry = Map.put(entry, :id, todo_list.auto_id)
new_entries = Map.put(todo_list.entries, todo_list.auto_id, entry)
%TodoList{todo_list | entries: new_entries, auto_id: todo_list.auto_id + 1}
end
def entries(todo_list, date) do
todo_list.entries
|> Stream.filter(fn {x, entry} -> entry.date == date end)
|> Enum.map(fn {_, entry} -> entry end)
end
def delete_entry(todo_list, entry_id) do
%TodoList{todo_list | entries: Map.delete(todo_list.entries, entry_id)}
end
end