#[cfg(any(feature = "failable", docs))]
pub mod failable;
#[cfg(feature = "test")]
pub mod request;
#[cfg(not(feature = "test"))]
mod request;
use anyhow::Error;
use serde::Serialize;
use serde_json::Value;
use std::fmt::{self, Debug};
use std::time::Duration;
pub use self::request::{RawView, RequestChildren, SyncRequest, TypedIter, TypedView};
#[derive(Deserialize, Serialize, Clone, PartialEq)]
pub struct SyncResponse {
pub status: Value,
pub children: Vec<Value>,
pub resync: Option<Duration>,
}
impl Debug for SyncResponse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let as_string = if f.alternate() {
serde_json::to_string_pretty(self)
} else {
serde_json::to_string(self)
}
.map_err(|_| fmt::Error)?;
write!(f, "SyncResponse: {}", as_string)
}
}
impl SyncResponse {
pub fn new(status: Value) -> SyncResponse {
SyncResponse {
status,
children: Vec::new(),
resync: None,
}
}
pub fn from_status<S: Serialize>(status: S) -> Result<SyncResponse, serde_json::Error> {
serde_json::to_value(status).map(SyncResponse::new)
}
pub fn add_child<C: Serialize>(&mut self, child: C) -> Result<(), serde_json::Error> {
serde_json::to_value(child).map(|c| {
self.children.push(c);
})
}
pub fn resync_after(&mut self, duration: Duration) {
self.resync = Some(duration);
}
}
#[derive(Deserialize, Serialize, Clone, PartialEq)]
pub struct FinalizeResponse {
pub status: Value,
pub retry: Option<Duration>,
}
impl Debug for FinalizeResponse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let as_string = if f.alternate() {
serde_json::to_string_pretty(self)
} else {
serde_json::to_string(self)
}
.map_err(|_| fmt::Error)?;
write!(f, "FinalizeResponse: {}", as_string)
}
}
pub trait Handler: Send + Sync + 'static {
fn sync(&self, request: &SyncRequest) -> Result<SyncResponse, Error>;
fn finalize(&self, request: &SyncRequest) -> Result<FinalizeResponse, Error> {
Ok(FinalizeResponse {
status: request.parent.status().cloned().unwrap_or(Value::Null),
retry: None,
})
}
}
impl<F> Handler for F
where
F: Fn(&SyncRequest) -> Result<SyncResponse, Error> + Send + Sync + 'static,
{
fn sync(&self, req: &SyncRequest) -> Result<SyncResponse, Error> {
self(req)
}
}
impl<SyncFn, ErrorFn> Handler for (SyncFn, ErrorFn)
where
SyncFn: Fn(&SyncRequest) -> Result<SyncResponse, Error> + Send + Sync + 'static,
ErrorFn: Fn(&SyncRequest, Error) -> (Value, Option<Duration>) + Send + Sync + 'static,
{
fn sync(&self, req: &SyncRequest) -> Result<SyncResponse, Error> {
let (sync_fun, handle_error) = self;
sync_fun(req).or_else(|err| {
let (status, resync) = handle_error(req, err);
Ok(SyncResponse {
status,
resync,
children: Vec::new(),
})
})
}
}