╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1455 │ │1456 pub fn parent(self: RoutablePage) PageKind { │ │1457 return switch (self) { │ │1440 - .home_about, .home_users, .home_new_repo, .home_auth => .home, │ │1441 - .user_repos, .user_forks, .user_new_repo, .user_auth => .user, │ │1442 - .repo_files, .repo_commits, .repo_diff, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_new_repo, .repo_auth => .repo, │ │1443 - .fork_patch, .fork_diff, .fork_files, .fork_commits, .fork_new_repo, .fork_auth => .fork, │ │1458 + .home_about, .home_users, .home_new_repo, .home_new_user, .home_auth => .home, │ │1459 + .user_repos, .user_forks, .user_new_repo, .user_new_user, .user_auth => .user, │ │1460 + .repo_files, .repo_commits, .repo_diff, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_new_repo, .repo_new_user, .repo_auth => .repo,│ │1461 + .fork_patch, .fork_diff, .fork_files, .fork_commits, .fork_new_repo, .fork_new_user, .fork_auth => .fork, │ │1462 .not_found => .not_found, │ │1463 }; │ │1464 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1500 const tab = segments.next() orelse return null; │ │1501 var params = Params{}; │ │1502 if (std.mem.eql(u8, tab, "new-repo")) return if (segments.next() == null) .{ .repo_new_repo = Array(repo_route_max_len).from(pair) orelse return null } else null;│ │1503 + if (std.mem.eql(u8, tab, "new-user")) return if (segments.next() == null) .{ .repo_new_user = Array(repo_route_max_len).from(pair) orelse return null } else null;│ │1504 if (std.mem.eql(u8, tab, "auth")) return if (segments.next() == null) .{ .repo_auth = Array(repo_route_max_len).from(pair) orelse return null } else null; │ │1505 if (std.mem.eql(u8, tab, "refs")) { │ │1506 const word = params.scanTail(&segments) catch return null; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1757 .user_repos => |a_u| std.mem.eql(u8, a_u.name.slice(), b.user_repos.name.slice()) and a_u.start == b.user_repos.start and std.mem.eql(u8, a_u.search.slice(), b.user_repos.search.slice()),│ │1758 .user_forks => |a_u| std.mem.eql(u8, a_u.name.slice(), b.user_forks.name.slice()) and a_u.start == b.user_forks.start, │ │1759 .user_new_repo => |a_name| std.mem.eql(u8, a_name.slice(), b.user_new_repo.slice()), │ │1760 + .user_new_user => |a_name| std.mem.eql(u8, a_name.slice(), b.user_new_user.slice()), │ │1761 .user_auth => |a_name| std.mem.eql(u8, a_name.slice(), b.user_auth.slice()), │ │1762 .repo_files => |a_f| std.mem.eql(u8, a_f.name.slice(), b.repo_files.name.slice()) and │ │1763 a_f.ref_kind == b.repo_files.ref_kind and │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1819 a_e.kind == b.repo_events.kind and │ │1820 std.mem.eql(u8, a_e.selected.slice(), b.repo_events.selected.slice()), │ │1821 .repo_new_repo => |a_name| std.mem.eql(u8, a_name.slice(), b.repo_new_repo.slice()), │ │1822 + .repo_new_user => |a_name| std.mem.eql(u8, a_name.slice(), b.repo_new_user.slice()), │ │1823 .repo_auth => |a_name| std.mem.eql(u8, a_name.slice(), b.repo_auth.slice()), │ │1824 .fork_patch => |a_f| std.mem.eql(u8, a_f.name.slice(), b.fork_patch.name.slice()) and std.mem.eql(u8, a_f.id.slice(), b.fork_patch.id.slice()),│ │1825 .fork_diff => |a_d| std.mem.eql(u8, a_d.fork.name.slice(), b.fork_diff.fork.name.slice()) and │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1842 .message => std.meta.activeTag(b.fork_commits.content) == .message, │ │1843 }, │ │1844 .fork_new_repo => |a_f| std.mem.eql(u8, a_f.name.slice(), b.fork_new_repo.name.slice()) and std.mem.eql(u8, a_f.id.slice(), b.fork_new_repo.id.slice()),│ │1845 + .fork_new_user => |a_f| std.mem.eql(u8, a_f.name.slice(), b.fork_new_user.name.slice()) and std.mem.eql(u8, a_f.id.slice(), b.fork_new_user.id.slice()),│ │1846 .fork_auth => |a_f| std.mem.eql(u8, a_f.name.slice(), b.fork_auth.name.slice()) and std.mem.eql(u8, a_f.id.slice(), b.fork_auth.id.slice()), │ │1847 else => true, │ │1848 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2226 return switch (err) { │ │2227 error.NameEmpty => .required_name, │ │2228 error.NameTooLong, error.InvalidName => .invalid_name, │ │2229 + error.NameTaken => .name_taken, │ │2230 + else => null, │ │2231 + }; │ │2232 + } │ │2233 + }; │ │2234 + │ │2235 + pub const UserFailure = enum { │ │2236 + required_name, │ │2237 + invalid_name, │ │2238 + name_taken, │ │2239 + required_email, │ │2240 + email_taken, │ │2241 + required_password, │ │2242 + password_mismatch, │ │2243 + │ │2244 + pub fn fromError(err: anyerror) ?UserFailure { │ │2245 + return switch (err) { │ │2246 + error.NameEmpty => .required_name, │ │2247 + error.NameTooShort, error.NameTooLong, error.InvalidName => .invalid_name,│ │2248 error.NameTaken => .name_taken, │ │2249 + error.EmailEmpty => .required_email, │ │2250 + error.EmailTaken => .email_taken, │ │2251 + error.PasswordEmpty => .required_password, │ │2252 + error.PasswordMismatch => .password_mismatch, │ │2253 else => null, │ │2254 }; │ │2255 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────╮ │2259 failure: LoginFailure, │ │2260 username: []const u8, │ │2261 }, │ │2262 + user: struct { │ │2263 + failure: UserFailure, │ │2264 + // passwords are never retained│ │2265 + fields: struct { │ │2266 + name: []const u8, │ │2267 + email: []const u8, │ │2268 + }, │ │2269 + }, │ │2270 repo: struct { │ │2271 failure: RepoFailure, │ │2272 fields: struct { │ ╰─────────────────────────────────────────────────╯