use crate::http_client::HttpClient;
use crate::record::{from_system_time, Labels};
use reqwest::header::CONTENT_LENGTH;
use reqwest::Method;
use reduct_base::error::{ErrorCode, ReductError};
use std::sync::Arc;
use std::time::SystemTime;
pub struct UpdateRecordBuilder {
bucket: String,
entry: String,
timestamp: Option<u64>,
labels: Labels,
client: Arc<HttpClient>,
}
impl UpdateRecordBuilder {
pub(crate) fn new(bucket: String, entry: String, client: Arc<HttpClient>) -> Self {
Self {
timestamp: None,
labels: Labels::new(),
bucket,
entry,
client,
}
}
pub fn timestamp(mut self, timestamp: SystemTime) -> Self {
self.timestamp = Some(from_system_time(timestamp));
self
}
pub fn timestamp_us(mut self, timestamp: u64) -> Self {
self.timestamp = Some(timestamp);
self
}
pub fn labels(mut self, labels: Labels) -> Self {
self.labels = labels;
self
}
pub fn update_label<Str>(mut self, key: Str, value: Str) -> Self
where
Str: Into<String>,
{
self.labels.insert(key.into(), value.into());
self
}
pub fn remove_label(mut self, key: &str) -> Self {
self.labels.insert(key.to_string(), "".to_string());
self
}
pub async fn send(self) -> Result<(), ReductError> {
let timestamp = match self.timestamp {
Some(ts) => ts,
None => {
return Err(ReductError::new(
ErrorCode::UnprocessableEntity,
"timestamp is required",
));
}
};
let mut request = self.client.request(
Method::PATCH,
&format!("/b/{}/{}?ts={}", self.bucket, self.entry, timestamp),
);
for (key, value) in self.labels {
request = request.header(&format!("x-reduct-label-{}", key), value);
}
request = request.header(CONTENT_LENGTH, 0);
self.client.send_request(request).await?;
Ok(())
}
}