diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..510521a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +.zig-cache/ +todo-db.txt \ No newline at end of file diff --git a/Zig.iml b/Zig.iml new file mode 100644 index 0000000..dc55325 --- /dev/null +++ b/Zig.iml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/interaction.zig b/src/interaction.zig index 744a5e1..989c9c4 100644 --- a/src/interaction.zig +++ b/src/interaction.zig @@ -15,15 +15,24 @@ pub fn userInteraction(allocator: std.mem.Allocator, tasks: *std.ArrayList([]con failure += 1; continue; }; - try stdout.print("Please enter your choice [add/remove/edit/quit]: ", .{}); + + // todo make available commads be listed from enum itself + const Case = enum { add, edit, remove, move, quit }; + + var fields = std.ArrayList([]const u8).init(allocator); + defer fields.deinit(); + + inline for (@typeInfo(Case).Enum.fields) |f| { + fields.append(f.name); + } + try stdout.print("Please enter your choice [add/remove/edit/move/quit]: ", .{}); const input = getInput(allocator) catch |err| { std.debug.print("Error acquiring input:\n{}\n", .{err}); continue; }; defer allocator.free(input); - // todo add option to manipulate tasks via numbers (and add numbers to tasks) - const Case = enum { add, edit, remove, quit }; + const case = std.meta.stringToEnum(Case, input) orelse continue; var task_name: []const u8 = undefined; @@ -70,11 +79,56 @@ pub fn userInteraction(allocator: std.mem.Allocator, tasks: *std.ArrayList([]con allocator.free(tasks.items[id]); _ = tasks.orderedRemove(id); }, + .move => { + try stdout.print("Please enter task name or number: ", .{}); + _ = getTaskIndex(tasks, task_name) catch { + std.debug.print("Invalid task name...", .{}); + continue; + }; + + const new_input = getInput(allocator) catch |err| { + std.debug.print("Failed to get new input:\n{}\n", .{err}); + continue; + }; + defer allocator.free(new_input); + + _ = std.fmt.parseInt(usize, new_input, 10) catch |err| { + std.debug.print("Failed to convert the input into ID:\n{}\n", .{err}); + continue; + }; + + // todo restructure arraylist + }, .quit => break, } } } +fn get_fields_str(allocator: std.mem.Allocator, arr: std.ArrayList([]const u8)) ![]const u8 { + // get len + var len = 0; + for (arr.items) |value| { + len += value.len; + } + len += arr.capacity - 1; + + // todo free mem + var result = try allocator.alloc(u8, len); + defer allocator.free(result); + + var cur_len = 0; + for (arr.items) |value| { + @memcpy(result[0..], value); + cur_len += value.len; + + if (value == arr.items[arr.capacity-1]) continue; + @memcpy(result[cur_len..], "/"); + cur_len += 1; + } + + return result; +} + fn getInput(allocator: std.mem.Allocator) ![]const u8 { const stdin = std.io.getStdIn().reader(); const bare_line = try stdin.readUntilDelimiterAlloc(allocator, '\n', 8192); @@ -84,11 +138,19 @@ fn getInput(allocator: std.mem.Allocator) ![]const u8 { } fn getTaskIndex(tasks: *std.ArrayList([]const u8), task_name: []const u8) !usize { - for (tasks.items, 0..) |value, i| { - if (std.mem.eql(u8, task_name, value)) { - return i; + if (tasks.items.len == 0) return InteractionError.TaskNotFound; + const task_id = std.fmt.parseInt(usize, task_name, 10) catch { + for (tasks.items, 0..) |value, i| { + if (std.mem.eql(u8, task_name, value)) { + return i; + } } - } + + return InteractionError.TaskNotFound; + }; + + const act_val = task_id - 1; + if (act_val >= 0 and act_val < tasks.items.len) return act_val; return InteractionError.TaskNotFound; } @@ -100,8 +162,8 @@ fn printItems(tasks: *std.ArrayList([]const u8)) !void { } try stdout.print("Items:\n------\n", .{}); - for (tasks.items) |value| { - try stdout.print("{s}\n", .{value}); + for (tasks.items, 1..) |value, i| { + try stdout.print("{d}. {s}\n", .{i, value}); } try stdout.print("\n", .{}); }