commit 0aed1dcd0e2342a2dbc64e6c15ee27ccbbd129ed Author: Moritz Böhme Date: Thu Aug 1 20:25:13 2024 +0200 feat: add simple todo list module diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0aa57d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +### direnv ### +.direnv +.envrc + +### Elixir ### +/_build +/cover +/deps +/doc +/.fetch +erl_crash.dump +*.ez +*.beam +/config/*.secret.exs +.elixir_ls/ + +### Elixir Patch ### diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..92536e1 --- /dev/null +++ b/flake.lock @@ -0,0 +1,58 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1719994518, + "narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1722185531, + "narHash": "sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "52ec9ac3b12395ad677e8b62106f0b98c1f8569d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1719876945, + "narHash": "sha256-Fm2rDDs86sHy0/1jxTOKB1118Q0O3Uc7EC0iXvXKpbI=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..32783b1 --- /dev/null +++ b/flake.nix @@ -0,0 +1,36 @@ +{ + description = "Description for the project"; + + inputs = { + flake-parts.url = "github:hercules-ci/flake-parts"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + imports = [ + # To import a flake module + # 1. Add foo to inputs + # 2. Add foo as a parameter to the outputs function + # 3. Add here: foo.flakeModule + + ]; + systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ]; + perSystem = { config, self', inputs', pkgs, system, ... }: { + # Per-system attributes can be defined here. The self' and inputs' + # module parameters provide easy access to attributes of the same + # system. + + # Equivalent to inputs'.nixpkgs.legacyPackages.hello; + devShells.default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ elixir-ls elixir_1_17]; + }; + }; + flake = { + # The usual flake attributes can be defined here, including system- + # agnostic ones like nixosModule and system-enumerating ones, although + # those are more easily expressed in perSystem. + + }; + }; +} diff --git a/todo_list.csv b/todo_list.csv new file mode 100644 index 0000000..a9cb816 --- /dev/null +++ b/todo_list.csv @@ -0,0 +1,3 @@ +2024-12-19,Dentist +2024-12-20,Shopping +2024-12-19,Movies diff --git a/todo_list.ex b/todo_list.ex new file mode 100644 index 0000000..47abb7e --- /dev/null +++ b/todo_list.ex @@ -0,0 +1,71 @@ +defmodule TodoList do + defstruct entries: %{}, next_id: 1 + + def new(entries \\ []) do + Enum.reduce(entries, %__MODULE__{}, &add(&2, &1)) + end + + def add( + %__MODULE__{entries: entries, next_id: next_id} = todo_list, + %{date: _, title: _} = entry + ) do + new_entry = Map.put(entry, :id, next_id) + + new_entries = Map.put(entries, next_id, new_entry) + + %__MODULE__{todo_list | entries: new_entries, next_id: next_id + 1} + end + + def entries(%__MODULE__{entries: entries}, date) do + entries + |> Map.filter(fn {_, entry} -> entry.date == date end) + |> Map.values() + end + + def update(%__MODULE__{entries: entries} = todo_list, id, update_fun) + when is_function(update_fun, 1) do + case Map.fetch(entries, id) do + :error -> + todo_list + + {:ok, entry} -> + new_entry = update_fun.(entry) + new_entries = Map.put(entries, id, new_entry) + %__MODULE__{todo_list | entries: new_entries} + end + end + + def delete(%__MODULE__{entries: entries} = todo_list, id) when is_number(id) do + new_entries = Map.delete(entries, id) + + %__MODULE__{todo_list | entries: new_entries} + end +end + +defmodule TodoList.CSVImporter do + def import(path) do + path + |> File.stream!() + |> Stream.map(&parse_line/1) + |> TodoList.new() + end + + defp parse_line(line) do + line + |> String.trim() + |> String.split(",") + |> create_entry() + end + + defp create_entry([date, title]) do + final_date = parse_date(date) + + %{date: final_date, title: title} + end + + defp parse_date(string) do + [year, month, day] = string |> String.split("-") |> Enum.map(&String.to_integer/1) + + Date.new!(year, month, day) + end +end