ferrtable 0.0.2

Ferris the crab's favorite Airtable library
Documentation
use std::fmt::Debug;

use derive_builder::Builder;
use percent_encoding::{NON_ALPHANUMERIC, utf8_percent_encode};
use serde::{Serialize, de::DeserializeOwned};

use crate::{client::Client, errors::ExecutionError, types::AirtableRecord};

#[derive(Builder, Clone, Debug, Serialize)]
#[builder(pattern = "owned", setter(prefix = "with"))]
pub struct GetRecordQuery {
    #[serde(skip)]
    base_id: String,

    #[serde(skip)]
    #[builder(vis = "pub(crate)")]
    client: Client,

    #[serde(skip)]
    record_id: String,

    #[serde(skip)]
    table_id: String,
}

impl GetRecordQuery {
    pub async fn fetch_optional<T>(self) -> Result<Option<AirtableRecord<T>>, ExecutionError>
    where
        T: Clone + Debug + DeserializeOwned,
    {
        let base_id = utf8_percent_encode(&self.base_id, NON_ALPHANUMERIC).to_string();
        let table_id = utf8_percent_encode(&self.table_id, NON_ALPHANUMERIC).to_string();
        let record_id = utf8_percent_encode(&self.record_id, NON_ALPHANUMERIC).to_string();
        let http_resp = self
            .client
            .get_path(&format!("v0/{base_id}/{table_id}/{record_id}"))
            .send()
            .await?;
        match http_resp.error_for_status() {
            Ok(http_resp) => Ok(http_resp.json().await?),
            Err(err) => {
                if err.status() == Some(reqwest::StatusCode::NOT_FOUND) {
                    Ok(None)
                } else {
                    Err(err.into())
                }
            }
        }
    }
}