use crate::client::ObservationUploadResult;
use crate::error::Result;
use crate::Error;
use napi_derive::napi;
use observation_tools_shared::models::ExecutionId;
use observation_tools_shared::ObservationId;
#[napi]
pub struct SendObservation {
pub(crate) handle: ObservationHandle,
pub(crate) uploaded_rx: Option<tokio::sync::watch::Receiver<ObservationUploadResult>>,
pub(crate) creation_error: Option<Error>,
}
impl SendObservation {
pub(crate) fn new(
handle: ObservationHandle,
uploaded_rx: tokio::sync::watch::Receiver<ObservationUploadResult>,
) -> Self {
Self {
handle,
uploaded_rx: Some(uploaded_rx),
creation_error: None,
}
}
pub(crate) fn stub(error: Error) -> Self {
Self {
handle: ObservationHandle::placeholder(),
uploaded_rx: None,
creation_error: Some(error),
}
}
pub async fn wait_for_upload(&mut self) -> Result<ObservationHandle> {
if let Some(_err) = &self.creation_error {
return Err(Error::CreationError);
}
let rx = self.uploaded_rx.as_mut().ok_or(Error::ChannelClosed)?;
loop {
{
let value = rx.borrow_and_update();
match &*value {
Some(Ok(handle)) => return Ok(handle.clone()),
Some(Err(error_msg)) => return Err(Error::UploadFailed(error_msg.clone())),
None => {}
}
}
rx.changed().await.map_err(|_| Error::ChannelClosed)?;
}
}
pub fn handle(&self) -> &ObservationHandle {
&self.handle
}
pub fn into_handle(self) -> ObservationHandle {
self.handle
}
}
#[napi]
impl SendObservation {
#[napi(js_name = "handle")]
pub fn handle_napi(&self) -> ObservationHandle {
self.handle.clone()
}
}
#[napi]
#[derive(Clone, Debug)]
pub struct ObservationHandle {
pub(crate) base_url: String,
pub(crate) observation_id: ObservationId,
pub(crate) execution_id: ExecutionId,
}
impl ObservationHandle {
pub fn id(&self) -> &ObservationId {
&self.observation_id
}
pub(crate) fn placeholder() -> Self {
Self {
base_url: String::new(),
observation_id: ObservationId::nil(),
execution_id: ExecutionId::nil(),
}
}
}
#[napi]
impl ObservationHandle {
#[napi(getter)]
pub fn url(&self) -> String {
format!(
"{}/exe/{}/obs/{}",
self.base_url, self.execution_id, self.observation_id
)
}
#[napi(getter, js_name = "id")]
pub fn id_napi(&self) -> String {
self.observation_id.to_string()
}
}
impl From<SendObservation> for ObservationHandle {
fn from(send: SendObservation) -> ObservationHandle {
send.into_handle()
}
}