From aa2558c6793ae45eb04f90b59cc800646b931cda Mon Sep 17 00:00:00 2001 From: Brent Schroeter Date: Tue, 16 Sep 2025 22:49:22 -0700 Subject: [PATCH] move readme --- README.md | 92 +-------------------------------------------- ferrtable/README.md | 91 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 91 deletions(-) mode change 100644 => 120000 README.md create mode 100644 ferrtable/README.md diff --git a/README.md b/README.md deleted file mode 100644 index 24d8d38..0000000 --- a/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# Ferrtable: Ferris the Crab's Favorite Airtable Client - -Ferrtable provides async Rust bindings for a subset of the -[Airtable web API](https://airtable.com/developers/web/api/introduction). -Notably, it allows records to be read from and written to arbitrary Rust types -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 be 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 -relatively small subset built and tested well. - -## Usage - -```rust -use futures::prelude::*; - -// Ferrtable allows us to use any record types that implement Clone, -// Deserialize, and Serialize. -#[derive(Clone, Debug, Deserialize, Serialize)] -struct MyRecord { - #[serde(rename = "Name")] - name: String, - - #[serde(rename = "Notes")] - notes: String, - - #[serde(rename = "Assignee")] - assignee: Option, - - #[serde(rename = "Status")] - status: Status, - - #[serde(rename = "Attachments")] - attachments: Vec, -} - -#[derive(Clone, Debug, Deserialize, Serialize)] -enum Status { - Todo, - - #[serde(rename = "In progress")] - InProgress, - - Done, -} - -#[tokio::main] -async fn main() { - let client = ferrtable::Client::new_from_access_token("******").unwrap(); - - client - .create_records([MyRecord { - name: "Steal Improbability Drive".to_owned(), - notes: "Just for fun, no other reason.".to_owned(), - assignee: None, - status: Status::InProgress, - attachments: vec![], - }]) - .with_base_id("***".to_owned()) - .with_table_id("***".to_owned()) - .build() - .unwrap() - .execute() - .await - .unwrap(); - - let mut rec_stream = client - .list_records() - .with_base_id("***".to_owned()) - .with_table_id("***".to_owned()) - .with_filter("{status} = 'Todo' || {status} = 'In Progress'".to_owned()) - .build() - .unwrap() - .stream_items::(); - - while let Some(result) = rec_stream.next().await { - let rec = result.unwrap(); - dbg!(rec.fields); - } -} -``` diff --git a/README.md b/README.md new file mode 120000 index 0000000..e931cca --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +./ferrtable/README.md \ No newline at end of file diff --git a/ferrtable/README.md b/ferrtable/README.md new file mode 100644 index 0000000..24d8d38 --- /dev/null +++ b/ferrtable/README.md @@ -0,0 +1,91 @@ +# Ferrtable: Ferris the Crab's Favorite Airtable Client + +Ferrtable provides async Rust bindings for a subset of the +[Airtable web API](https://airtable.com/developers/web/api/introduction). +Notably, it allows records to be read from and written to arbitrary Rust types +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 be 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 +relatively small subset built and tested well. + +## Usage + +```rust +use futures::prelude::*; + +// Ferrtable allows us to use any record types that implement Clone, +// Deserialize, and Serialize. +#[derive(Clone, Debug, Deserialize, Serialize)] +struct MyRecord { + #[serde(rename = "Name")] + name: String, + + #[serde(rename = "Notes")] + notes: String, + + #[serde(rename = "Assignee")] + assignee: Option, + + #[serde(rename = "Status")] + status: Status, + + #[serde(rename = "Attachments")] + attachments: Vec, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +enum Status { + Todo, + + #[serde(rename = "In progress")] + InProgress, + + Done, +} + +#[tokio::main] +async fn main() { + let client = ferrtable::Client::new_from_access_token("******").unwrap(); + + client + .create_records([MyRecord { + name: "Steal Improbability Drive".to_owned(), + notes: "Just for fun, no other reason.".to_owned(), + assignee: None, + status: Status::InProgress, + attachments: vec![], + }]) + .with_base_id("***".to_owned()) + .with_table_id("***".to_owned()) + .build() + .unwrap() + .execute() + .await + .unwrap(); + + let mut rec_stream = client + .list_records() + .with_base_id("***".to_owned()) + .with_table_id("***".to_owned()) + .with_filter("{status} = 'Todo' || {status} = 'In Progress'".to_owned()) + .build() + .unwrap() + .stream_items::(); + + while let Some(result) = rec_stream.next().await { + let rec = result.unwrap(); + dbg!(rec.fields); + } +} +```