Packages
fnord
0.9.35
0.9.40
0.9.39
0.9.38
0.9.37
0.9.36
0.9.35
0.9.34
0.9.33
0.9.32
0.9.31
0.9.30
0.9.29
0.9.28
0.9.27
0.9.26
0.9.25
0.9.24
0.9.23
0.9.22
0.9.21
0.9.20
0.9.19
0.9.18
0.9.17
0.9.16
0.9.15
0.9.14
0.9.13
0.9.12
0.9.11
0.9.10
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.99
0.8.98
0.8.97
0.8.96
0.8.95
0.8.94
0.8.93
0.8.92
0.8.91
0.8.90
0.8.89
0.8.88
0.8.87
0.8.86
0.8.85
0.8.84
0.8.83
0.8.82
0.8.81
0.8.80
0.8.79
0.8.78
0.8.77
0.8.76
0.8.75
0.8.74
0.8.73
0.8.72
0.8.71
0.8.70
0.8.69
0.8.68
0.8.67
0.8.66
0.8.65
0.8.64
0.8.63
0.8.62
0.8.61
0.8.60
0.8.59
0.8.58
0.8.57
0.8.56
0.8.55
0.8.54
0.8.53
0.8.52
0.8.51
0.8.50
0.8.49
0.8.48
0.8.47
0.8.46
0.8.45
0.8.44
0.8.43
0.8.42
0.8.41
0.8.40
0.8.39
0.8.38
0.8.37
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.30
0.8.29
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.1
0.8.0
0.7.24
0.7.23
0.7.22
0.7.21
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.3
0.7.2
0.7.1
0.7.0
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.1
0.6.0
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.44
0.4.43
0.4.42
0.4.41
0.4.40
0.4.39
0.4.38
0.4.37
0.4.36
0.4.35
0.4.34
0.4.33
0.4.32
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.0
0.1.0
AI code archaeology
Current section
Files
Jump to
Current section
Files
lib/services/task/list.ex
defmodule Services.Task.List do
@moduledoc """
Represents a task list with an identifier, optional description, and a list of tasks.
Provides core operations for creating and manipulating task lists.
"""
defstruct id: nil, description: nil, tasks: [], status: "planning"
# "planning" | "in-progress" | "done"
@type status :: String.t()
@type t :: %__MODULE__{
id: binary,
description: binary | nil,
tasks: [map()],
status: status
}
@doc """
Creates a new TaskList with the given `id` and optional `description`.
"""
@spec new(binary, binary | nil) :: t
def new(id, description \\ nil) when is_binary(id) do
%__MODULE__{id: id, description: description, tasks: [], status: "planning"}
end
@doc """
Adds a task to the end of the task list.
"""
@spec add(t, map()) :: t
def add(%__MODULE__{tasks: tasks} = list, task) when is_map(task) do
%__MODULE__{list | tasks: tasks ++ [task]}
end
@doc """
Pushes a task to the front of the task list.
"""
@spec push(t, map()) :: t
def push(%__MODULE__{tasks: tasks} = list, task) when is_map(task) do
%__MODULE__{list | tasks: [task | tasks]}
end
@doc """
Resolves tasks with the given `task_id` by updating their `outcome` and `result`.
Only tasks in todo state are updated.
"""
@spec resolve(t, binary, :done | :failed, any()) ::
{:ok, t} | {:error, :already_resolved | :not_found}
def resolve(%__MODULE__{tasks: tasks} = list, task_id, outcome, result)
when is_binary(task_id) and outcome in [:done, :failed] do
case Enum.find(tasks, fn %{id: id} -> id == task_id end) do
nil ->
{:error, :not_found}
%{outcome: :todo} ->
updated_tasks =
Enum.map(tasks, fn
%{id: ^task_id, outcome: :todo} = task ->
%{task | outcome: outcome, result: result}
other ->
other
end)
{:ok, %__MODULE__{list | tasks: updated_tasks}}
%{outcome: _terminal} ->
{:error, :already_resolved}
end
end
@doc """
Converts the task list to a string, including the header and each task.
If `detail?` is true, includes task results for done/failed tasks.
"""
@spec to_string(t, boolean) :: binary
def to_string(%__MODULE__{id: id, description: desc, tasks: tasks}, detail? \\ false) do
# Always include colon for consistency with Services.Task.as_string/2
header =
case desc do
nil -> "Task List #{id}:"
"" -> "Task List #{id}:"
_ -> "Task List #{id}: #{desc}"
end
body =
tasks
|> Enum.map(&format_task(&1, detail?))
Enum.join([header | body], "\n")
end
defp format_task(%{id: id, outcome: :todo}, _detail?),
do: "[ ] #{id}"
defp format_task(%{id: id, outcome: :done, result: result}, true),
do: "[✓] #{id}: #{result}"
defp format_task(%{id: id, outcome: :done}, false),
do: "[✓] #{id}"
defp format_task(%{id: id, outcome: :failed, result: result}, true),
do: "[✗] #{id}: #{result}"
defp format_task(%{id: id, outcome: :failed}, false),
do: "[✗] #{id}"
end