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())
}
}
}
}
}