update cli to allow download user input
This commit is contained in:
parent
92662ddb7f
commit
77ff15f997
59
src/cli.zig
59
src/cli.zig
@ -2,13 +2,18 @@ const std = @import("std");
|
|||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
|
const Action = enum { Run, GetInput };
|
||||||
|
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
|
|
||||||
|
action: Action,
|
||||||
day: u32,
|
day: u32,
|
||||||
part: u32,
|
part: u32,
|
||||||
input_file: []u8,
|
input_file: []u8,
|
||||||
|
|
||||||
fn print_usage(program: []const u8) void {
|
fn print_usage(program: []const u8) void {
|
||||||
std.debug.print("Usage: {s} <day> <part> [input.txt]\n", .{program});
|
std.debug.print("Usage: {s} <day> <part> [input.txt] Run solution\n", .{program});
|
||||||
|
std.debug.print(" {s} get-input <day> [input.txt] Get input. AOC_SESSSION environment variable needs to be defined\n", .{program});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(allocator: Allocator) !Self {
|
pub fn init(allocator: Allocator) !Self {
|
||||||
@ -17,6 +22,7 @@ pub fn init(allocator: Allocator) !Self {
|
|||||||
const program = try allocator.dupe(u8, args.next().?);
|
const program = try allocator.dupe(u8, args.next().?);
|
||||||
defer allocator.free(program);
|
defer allocator.free(program);
|
||||||
|
|
||||||
|
var action = Action.Run;
|
||||||
var day: u32 = 0;
|
var day: u32 = 0;
|
||||||
var part: u32 = 0;
|
var part: u32 = 0;
|
||||||
var input_file = try allocator.dupe(u8, "input.txt");
|
var input_file = try allocator.dupe(u8, "input.txt");
|
||||||
@ -24,29 +30,47 @@ pub fn init(allocator: Allocator) !Self {
|
|||||||
|
|
||||||
var i: u32 = 0;
|
var i: u32 = 0;
|
||||||
while (args.next()) |arg| {
|
while (args.next()) |arg| {
|
||||||
if (i == 0) {
|
if (i == 0 and std.mem.eql(u8, arg[0..], "get-input")) {
|
||||||
day = std.fmt.parseInt(u32, arg, 10) catch {
|
action = .GetInput;
|
||||||
std.debug.print("ERROR: Invalid day '{s}'\n", .{arg});
|
}
|
||||||
return error.cli;
|
|
||||||
};
|
|
||||||
} else if (i == 1) {
|
|
||||||
part = std.fmt.parseInt(u32, arg, 10) catch {
|
|
||||||
std.debug.print("ERROR: Invalid part '{s}'\n", .{arg});
|
|
||||||
return error.cli;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!(part == 1 or part == 2)) {
|
if (action == .Run) {
|
||||||
std.debug.print("ERROR: Part can only be 1 or 2\n", .{});
|
if (i == 0) {
|
||||||
return error.cli;
|
day = std.fmt.parseInt(u32, arg, 10) catch {
|
||||||
|
std.debug.print("ERROR: Invalid day '{s}'\n", .{arg});
|
||||||
|
return error.cli;
|
||||||
|
};
|
||||||
|
} else if (i == 1) {
|
||||||
|
part = std.fmt.parseInt(u32, arg, 10) catch {
|
||||||
|
std.debug.print("ERROR: Invalid part '{s}'\n", .{arg});
|
||||||
|
return error.cli;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!(part == 1 or part == 2)) {
|
||||||
|
std.debug.print("ERROR: Part can only be 1 or 2\n", .{});
|
||||||
|
return error.cli;
|
||||||
|
}
|
||||||
|
} else if (i == 2) {
|
||||||
|
allocator.free(input_file);
|
||||||
|
input_file = try allocator.dupe(u8, arg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i == 1) {
|
||||||
|
day = std.fmt.parseInt(u32, arg, 10) catch {
|
||||||
|
std.debug.print("ERROR: Invalid day '{s}'\n", .{arg});
|
||||||
|
return error.cli;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (i == 2) {
|
||||||
|
allocator.free(input_file);
|
||||||
|
input_file = try allocator.dupe(u8, arg);
|
||||||
}
|
}
|
||||||
} else if (i == 2) {
|
|
||||||
allocator.free(input_file);
|
|
||||||
input_file = try allocator.dupe(u8, arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (i < 2) {
|
if (i < 2) {
|
||||||
print_usage(program);
|
print_usage(program);
|
||||||
return error.cli;
|
return error.cli;
|
||||||
@ -54,6 +78,7 @@ pub fn init(allocator: Allocator) !Self {
|
|||||||
|
|
||||||
return Self{
|
return Self{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
.action = action,
|
||||||
.day = day,
|
.day = day,
|
||||||
.part = part,
|
.part = part,
|
||||||
.input_file = input_file
|
.input_file = input_file
|
||||||
|
92
src/main.zig
92
src/main.zig
@ -2,6 +2,7 @@ const std = @import("std");
|
|||||||
const aoc = @import("./aoc.zig");
|
const aoc = @import("./aoc.zig");
|
||||||
const cli = @import("./cli.zig");
|
const cli = @import("./cli.zig");
|
||||||
|
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
const StringArray = std.ArrayList([]const u8);
|
const StringArray = std.ArrayList([]const u8);
|
||||||
const DayHashMap = std.StringHashMap(aoc.Day);
|
const DayHashMap = std.StringHashMap(aoc.Day);
|
||||||
|
|
||||||
@ -27,19 +28,11 @@ const Days = [_]aoc.Day{
|
|||||||
create_day(@import("day5.zig")),
|
create_day(@import("day5.zig")),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn main() !u8 {
|
fn kilobytes(count: u32) u32 {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
return count * 1024;
|
||||||
const allocator = gpa.allocator();
|
}
|
||||||
defer {
|
|
||||||
if (gpa.deinit() == .leak) @panic("Leaked memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
var args = cli.init(allocator) catch |err| switch (err) {
|
|
||||||
error.cli => return 255,
|
|
||||||
else => return err
|
|
||||||
} ;
|
|
||||||
defer args.deinit();
|
|
||||||
|
|
||||||
|
fn run(allocator: Allocator, args: *cli) !u8 {
|
||||||
if (args.day > Days.len) {
|
if (args.day > Days.len) {
|
||||||
std.debug.print("ERROR: Day {} does not exist\n", .{args.day});
|
std.debug.print("ERROR: Day {} does not exist\n", .{args.day});
|
||||||
return 255;
|
return 255;
|
||||||
@ -98,6 +91,81 @@ pub fn main() !u8 {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_input(allocator: Allocator, args: *cli) !u8 {
|
||||||
|
var client = std.http.Client{ .allocator = allocator };
|
||||||
|
defer client.deinit();
|
||||||
|
|
||||||
|
var headers = std.http.Headers{ .allocator = allocator };
|
||||||
|
defer headers.deinit();
|
||||||
|
|
||||||
|
if (!try std.process.hasEnvVar(allocator, "AOC_SESSION")) {
|
||||||
|
std.debug.print("ERROR: Missing environment variable AOC_SESSION\n", .{});
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
var aoc_session = try std.process.getEnvVarOwned(allocator, "AOC_SESSION");
|
||||||
|
defer allocator.free(aoc_session);
|
||||||
|
|
||||||
|
var cookie_header = try std.fmt.allocPrint(allocator, "session={s}", .{aoc_session});
|
||||||
|
defer allocator.free(cookie_header);
|
||||||
|
|
||||||
|
try headers.append("cookie", cookie_header);
|
||||||
|
try headers.append("accept", "*/*");
|
||||||
|
|
||||||
|
var url_str = try std.fmt.allocPrint(allocator, "https://adventofcode.com/2023/day/{}/input", .{args.day});
|
||||||
|
defer allocator.free(url_str);
|
||||||
|
|
||||||
|
const uri = std.Uri.parse(url_str) catch unreachable;
|
||||||
|
|
||||||
|
var request = try client.request(.GET, uri, headers, .{});
|
||||||
|
defer request.deinit();
|
||||||
|
|
||||||
|
try request.start();
|
||||||
|
try request.wait();
|
||||||
|
|
||||||
|
if (request.response.status != .ok) {
|
||||||
|
if (request.response.status == .not_found) {
|
||||||
|
std.debug.print("ERROR: Day not found\n", .{});
|
||||||
|
} else if (request.response.status == .bad_request) {
|
||||||
|
std.debug.print("ERROR: Invalid session token\n", .{});
|
||||||
|
} else {
|
||||||
|
std.debug.print("ERROR: unknown error, status code {}\n", .{request.response.status});
|
||||||
|
}
|
||||||
|
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = try request.reader().readAllAlloc(allocator, kilobytes(8));
|
||||||
|
defer allocator.free(body);
|
||||||
|
|
||||||
|
var file = try std.fs.cwd().createFile(args.input_file, .{ });
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
try file.writeAll(body);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() !u8 {
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
defer {
|
||||||
|
if (gpa.deinit() == .leak) @panic("Leaked memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
var args = cli.init(allocator) catch |err| switch (err) {
|
||||||
|
error.cli => return 255,
|
||||||
|
else => return err
|
||||||
|
} ;
|
||||||
|
defer args.deinit();
|
||||||
|
|
||||||
|
if (args.action == .Run) {
|
||||||
|
return run(allocator, &args);
|
||||||
|
} else {
|
||||||
|
return get_input(allocator, &args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = @import("day1.zig");
|
_ = @import("day1.zig");
|
||||||
_ = @import("day2.zig");
|
_ = @import("day2.zig");
|
||||||
|
Loading…
Reference in New Issue
Block a user