From 840516b54584bbfd091a10cb306eef1c47c2d30e Mon Sep 17 00:00:00 2001
From: Marto <marto@marto.si>
Date: Mon, 10 Feb 2025 00:12:58 +0100
Subject: [PATCH] task add basic implementation

---
 src/file_op.zig     |  5 ++--
 src/interaction.zig | 58 +++++++++++++++++++++++++++++++++++++++++++++
 src/main.zig        | 38 +++++++----------------------
 3 files changed, 68 insertions(+), 33 deletions(-)
 create mode 100644 src/interaction.zig

diff --git a/src/file_op.zig b/src/file_op.zig
index 096783e..339531e 100644
--- a/src/file_op.zig
+++ b/src/file_op.zig
@@ -3,16 +3,15 @@ const fs = std.fs;
 
 const FileRead = struct {
     file: fs.File,
-    tasks: std.ArrayList([]u8),
+    tasks: std.ArrayList([]const u8),
 };
 
 pub fn readTasksFromFile(allocator: std.mem.Allocator, filename: []const u8) !FileRead {
-    var tasks = std.ArrayList([]u8).init(allocator);
+    var tasks = std.ArrayList([]const u8).init(allocator);
 
     var file = fs.cwd().openFile(filename, .{ .mode = .read_write }) catch |err| {
         if (err == error.FileNotFound) {
             std.debug.print("File not found: {s}\n", .{filename});
-            // todo needs to be closed eventually
             const new_file = fs.cwd().createFile(filename, .{}) catch |e| {
                 std.debug.print("Failed to create the file: {}", .{e});
                 return e;
diff --git a/src/interaction.zig b/src/interaction.zig
new file mode 100644
index 0000000..94519f0
--- /dev/null
+++ b/src/interaction.zig
@@ -0,0 +1,58 @@
+const std = @import("std");
+
+const InteractionError = error{
+    TaskNotFound,
+};
+
+pub fn userInteraction(allocator: std.mem.Allocator, tasks: *std.ArrayList([]const u8)) !void {
+    const stdout = std.io.getStdOut().writer();
+
+    while (true) {
+        try stdout.print("Please enter your choice add/remove/edit/quit: ", .{});
+        const input = getInput(allocator) catch |err| {
+            std.debug.print("Error acquiring input:\n{}\n", .{err});
+            continue;
+        };
+        defer allocator.free(input);
+        std.debug.print("You entered: {s}\n", .{input});
+
+        const Case = enum { add, edit, delete, quit };
+        const case = std.meta.stringToEnum(Case, input) orelse return;
+
+        switch (case) {
+            .add => {
+                try stdout.print("Please enter task name: ", .{});
+                const task_name = getInput(allocator) catch |err| {
+                    std.debug.print("Error acquiring input:\n{}\n", .{err});
+                    continue;
+                };
+                defer allocator.free(task_name);
+                const duped = try allocator.dupe(u8, task_name);
+                tasks.append(duped) catch |err| {
+                    std.debug.print("Failed to add the specified task:\n{}\n", .{err});
+                };
+            },
+            .edit => {},
+            .delete => {},
+            .quit => break,
+        }
+    }
+}
+
+fn getInput(allocator: std.mem.Allocator) ![]const u8 {
+    const stdin = std.io.getStdIn().reader();
+    const bare_line = try stdin.readUntilDelimiterAlloc(allocator, '\n', 8192);
+    // defer std.heap.page_allocator.free(bare_line);
+    // windows legacy
+    return std.mem.trim(u8, bare_line, "\r");
+}
+
+fn getTaskIndex(tasks: *std.ArrayList([]u8), task_name: []u8) !usize {
+    for (tasks.items, 0..) |value, i| {
+        if (std.mem.eql(u8, task_name, value)) {
+            return i;
+        }
+    }
+
+    return InteractionError.TaskNotFound;
+}
diff --git a/src/main.zig b/src/main.zig
index 084342c..5f1f58b 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,5 +1,6 @@
 const std = @import("std");
 const file_op = @import("file_op.zig");
+const user_int = @import("interaction.zig");
 
 pub fn main() !void {
     const filename = "todo-db.txt";
@@ -8,7 +9,7 @@ pub fn main() !void {
     const allocator = gpa.allocator();
 
     var file_res = file_op.readTasksFromFile(allocator, filename) catch |err| {
-        std.debug.print("Failed read or create file, exiting ...", .{});
+        std.debug.print("Failed read or create file:\n{}\n", .{err});
         return err;
     };
 
@@ -25,36 +26,13 @@ pub fn main() !void {
         std.debug.print("{s}\n", .{i});
     }
 
-    try userInteraction();
+    // todo push allocator in
+    user_int.userInteraction(allocator, &file_res.tasks) catch |err| {
+        std.debug.print("User Interaction error:\n{}\n", .{err});
+        return err;
+    };
 
     file_op.writeTasksToFile(file_res) catch |err| {
-        std.debug.print("Error while writing data to file:\n{}", .{err});
+        std.debug.print("Error while writing data to file:\n{}\n", .{err});
     };
 }
-
-fn userInteraction() !void {
-    const stdin = std.io.getStdIn().reader();
-    const stdout = std.io.getStdOut().writer();
-    // var buf: [100]u8 = undefined;
-
-    while (true) {
-        try stdout.print("Please enter your choice add/remove/edit/quit: ", .{});
-        const bare_line = try stdin.readUntilDelimiterAlloc(std.heap.page_allocator, '\n', 8192);
-        defer std.heap.page_allocator.free(bare_line);
-        // windows legacy
-        const line = std.mem.trim(u8, bare_line, "\r");
-        std.debug.print("You entered: {s}\n", .{line});
-
-        const Case = enum { add, edit, delete, quit };
-        const case = std.meta.stringToEnum(Case, line) orelse return;
-
-        switch (case) {
-            .add => {},
-            .edit => {},
-            .delete => {},
-            .quit => break,
-        }
-
-        //break;
-    }
-}