From 4a76f13d58820809e01cd53ed0dcc7d95de78d29 Mon Sep 17 00:00:00 2001 From: Brent Schroeter Date: Sun, 11 Jan 2026 20:39:21 +0000 Subject: [PATCH] improve documentation --- ferrtable/README.md | 62 ++++++++++++++++++++++++++++++++++--- ferrtable/src/errors.rs | 1 + ferrtable/src/pagination.rs | 17 +++++++--- 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/ferrtable/README.md b/ferrtable/README.md index a3a0bfb..53def24 100644 --- a/ferrtable/README.md +++ b/ferrtable/README.md @@ -7,16 +7,16 @@ that implement the `Clone`, `serde::Deserialize`, and `serde::Serialize` traits. This crate follows in the footsteps of the [airtable-api](https://crates.io/crates/airtable-api) crate from Oxide Computer -Company, which appears to have been archived and unmaintained since 2022. -By comparison, Ferrtable aims to provide a more flexible and expressive client +Company, which appears to have been archived and unmaintained since 2022. By +comparison, Ferrtable aims to provide a more flexible and expressive client interface as well as greater control over paginated responses with the help of async [streams](https://doc.rust-lang.org/book/ch17-04-streams.html). ## Status: Work in Progress Only a limited set of operations (e.g., creating and listing records) are -currently supported. The goal is to implement coverage for at least the full -set of non-enterprise API endpoints, but my initial emphasis is on getting a +currently supported. The goal is to implement coverage for at least the full set +of non-enterprise API endpoints, but my initial emphasis is on getting a relatively small subset built and tested well. ## Usage @@ -89,3 +89,57 @@ async fn main() -> Result<(), Box> { Ok(()) } ``` + +## Crate Release Process + +Maintainers: Eventually the release process should be automated, but until CI +runners are available for the repo, follow this checklist. + +1. Lint: + +```sh +cd ferrtable +cargo fmt --check +cargo clippy + +cd ../ferrtable-test +cargo fmt --check +cargo clippy +``` + +2. Run integration tests: + +```sh +cd ferrtable-test +cat < ferrtable-test.config.toml +cargo run +``` + +3. Run unit tests: + +```sh +cd ferrtable +# At the time of this writing, nextest doesn't actually have anything to run, +# but it may in the future as tests are added outside of doc comments. +cargo nextest run --all-features --no-tests=warn +cargo test --doc +``` + +4. Bump `version` in `Cargo.toml`. +5. Update main package version in `ferrtable-test` lockfile: + +```sh +cd ferrtable-test +cargo build +``` + +6. Commit and push changes. +7. Publish: + +```sh +cargo publish +``` diff --git a/ferrtable/src/errors.rs b/ferrtable/src/errors.rs index aa98f8a..e1f0779 100644 --- a/ferrtable/src/errors.rs +++ b/ferrtable/src/errors.rs @@ -1,5 +1,6 @@ use thiserror::Error; +/// Errors that may occur when making an Airtable API request. #[derive(Debug, Error)] pub enum ExecutionError { #[error("error making http request to airtable api: {0}")] diff --git a/ferrtable/src/pagination.rs b/ferrtable/src/pagination.rs index 264c075..ab55679 100644 --- a/ferrtable/src/pagination.rs +++ b/ferrtable/src/pagination.rs @@ -35,8 +35,17 @@ where Q: Clone, T: Clone, { + /// Records remaining from the most recently fetched page but not yet + /// yielded to the stream consumer. Subsequent page should not be fetched + /// until this collection has been fully consumed. buffered: VecDeque, + + /// Owned copy of the paginated query. query: Q, + + /// When `query.offset` is `None`, this flag indicates whether that is + /// because the first page still needs to be fetched (`started` = `false`) + /// or because there are no pages remaining (`started` = `true`). started: bool, } @@ -61,9 +70,9 @@ macro_rules! handle_stream_err { }; } -// This could be brought into PaginatedQuery as a default implementation, but -// that forces that the traits in this module be exposed outside of the crate -// and additionally results in worse client ergonomics overall. +// This could be folded into the `PaginatedQuery` trait as a default +// implementation, but that forces that the traits in this module be exposed +// outside of the crate and results in worse caller ergonomics overall. pub(crate) fn execute_paginated( query: impl PaginatedQuery, ) -> Pin>>> @@ -72,7 +81,7 @@ where R: PaginatedResponse, { // Stream has to be pinned to the heap so that the closure inside - // doesn't need to implement Unpin (which I don't think it can). + // doesn't need to implement Unpin. Box::pin(futures::stream::unfold( StreamState { buffered: VecDeque::new(),