Skip to main content

Crate aoc_api

Crate aoc_api 

Source
Expand description

A typed client for Advent of Code.

It downloads puzzle inputs and samples, reads how many stars an account has earned, and submits answers. The site has no API, so every reply is a page meant for a browser; recognising them is parse’s job and nothing else’s.

use aoc_api::{Part, Puzzle, Session, Verdict};

let session = Session::new("53616c7465645f5f...", "github.com/my-username/my-repo by me@example.com")?;
let puzzle = Puzzle::at(2024, 7)?;

let input = session.input_text(puzzle).await?;

match session.submit(puzzle, Part::One, "3749").await? {
    Verdict::Correct => println!("gold star"),
    verdict => println!("{verdict}"),
}

§Shape

  • Session holds the cookie and the one HTTP client built from it. Which puzzle a call is about is an argument, so one session serves a whole event.
  • Every endpoint is also a free function over a http::Transport - session::input_text, session::submit and the rest - for a caller that already keeps a transport in a type of its own and does not want a second wrapper around it. Session’s methods are those functions with the transport filled in.
  • Puzzle, Year, Day and Part are validated newtypes, so an out-of-range coordinate cannot become a request.
  • http::Transport is the seam everything external sits behind. http::fake::FakeTransport replays canned replies, which is how this crate’s own tests run without a network or a cookie - and how a tool built on it can do the same.
  • Error is the union of the typed errors each module owns.

§Runtime

The API is asynchronous and brings no runtime of its own: it runs on whichever executor the caller already has, including a current-thread tokio runtime driven to completion, which is how a synchronous program should use it.

§Automation etiquette

This crate follows the Advent of Code automation guidelines. Two of them are settled here, and two are deliberately left to you:

  • Identification. Every request carries a User-Agent with the identification you provide when the HTTP client is built, whether that is Session::new or http::ReqwestTransport::new. It is baked into the client’s default headers, so no request can go out without it.
  • No hidden traffic. A request happens when you call an endpoint, and never otherwise. Nothing polls, retries or prefetches.
  • Throttling is yours. This crate does not sleep between requests, because a library cannot know how a program is being driven and a hidden delay in someone else’s process is a poor surprise. Space out your calls; aoc-runtime is one example of doing it, with a persisted minimum gap.
  • Caching is yours. Inputs are personal, permanent and unchanging, so download one once and keep it. This crate returns the body and forgets it.

Re-exports§

pub use error::Error;
pub use parse::Hint;
pub use puzzle::Day;
pub use puzzle::Part;
pub use puzzle::Puzzle;
pub use puzzle::PuzzleError;
pub use puzzle::Year;
pub use session::Session;
pub use session::Verdict;

Modules§

error
The error every fallible call in this crate returns.
http
The HTTP transport, and the identification every request carries.
parse
Reading Advent of Code’s HTML replies.
puzzle
Validated puzzle coordinates.
session
The endpoints.