use std::collections::HashSet;
use std::sync::Arc;
use serde_json::{Map, Value};
use crate::series::SeriesArgs;
use crate::source::{file_source, Source};
use crate::treemap::TreemapArgs;
use crate::{FrameDataset, Result, TreeNode};
pub trait Backend: Send + Sync {
fn columns(&self) -> Result<HashSet<String>>;
fn schema(&self) -> Result<Vec<(String, String)>>;
fn treemap(&self, ds: &FrameDataset, args: &TreemapArgs) -> Result<TreeNode>;
fn branch_set(
&self,
ds: &FrameDataset,
args: &TreemapArgs,
) -> Result<crate::treemap::BranchSet>;
fn series(&self, ds: &FrameDataset, args: &SeriesArgs) -> Result<Value>;
fn entity_series(
&self,
ds: &FrameDataset,
id: &str,
metric: &str,
window_days: Option<i64>,
resolution: &str,
) -> Result<Value>;
fn scatter(
&self,
ds: &FrameDataset,
x: &str,
y: &str,
filters: &Map<String, Value>,
color: Option<&str>,
limit: Option<u32>,
) -> Result<Value>;
fn geo(
&self,
ds: &FrameDataset,
key_column: &str,
metric: &str,
filters: &Map<String, Value>,
) -> Result<Value>;
fn detail(&self, ds: &FrameDataset, eid: &str) -> Result<Option<Value>>;
fn search(&self, ds: &FrameDataset, q: &str, axis: Option<&str>, limit: u32) -> Result<Value>;
fn filter_options(
&self,
ds: &FrameDataset,
facet: &str,
q: Option<&str>,
limit: u32,
) -> Result<Vec<Value>>;
}
pub struct FrameBackend {
source: Arc<dyn Source>,
}
impl FrameBackend {
pub fn new(source: Arc<dyn Source>) -> Self {
Self { source }
}
}
impl Backend for FrameBackend {
fn columns(&self) -> Result<HashSet<String>> {
self.source.columns()
}
fn schema(&self) -> Result<Vec<(String, String)>> {
self.source.schema()
}
fn treemap(&self, ds: &FrameDataset, args: &TreemapArgs) -> Result<TreeNode> {
crate::treemap::treemap(ds, &*self.source, args)
}
fn branch_set(
&self,
ds: &FrameDataset,
args: &TreemapArgs,
) -> Result<crate::treemap::BranchSet> {
crate::treemap::branch_set(ds, &*self.source, args)
}
fn series(&self, ds: &FrameDataset, args: &SeriesArgs) -> Result<Value> {
crate::series::series(ds, &*self.source, args)
}
fn entity_series(
&self,
ds: &FrameDataset,
id: &str,
metric: &str,
window_days: Option<i64>,
resolution: &str,
) -> Result<Value> {
crate::series::entity_series(ds, &*self.source, id, metric, window_days, resolution)
}
fn scatter(
&self,
ds: &FrameDataset,
x: &str,
y: &str,
filters: &Map<String, Value>,
color: Option<&str>,
limit: Option<u32>,
) -> Result<Value> {
crate::query::scatter(ds, &*self.source, x, y, filters, color, limit)
}
fn geo(
&self,
ds: &FrameDataset,
key_column: &str,
metric: &str,
filters: &Map<String, Value>,
) -> Result<Value> {
crate::query::geo(ds, &*self.source, key_column, metric, filters)
}
fn detail(&self, ds: &FrameDataset, eid: &str) -> Result<Option<Value>> {
crate::query::detail(ds, &*self.source, eid)
}
fn search(&self, ds: &FrameDataset, q: &str, axis: Option<&str>, limit: u32) -> Result<Value> {
crate::query::search(ds, &*self.source, q, axis, limit)
}
fn filter_options(
&self,
ds: &FrameDataset,
facet: &str,
q: Option<&str>,
limit: u32,
) -> Result<Vec<Value>> {
crate::query::filter_options(ds, &*self.source, facet, q, limit)
}
}
pub fn file_backend(path: &str) -> Box<dyn Backend> {
Box::new(FrameBackend::new(Arc::from(file_source(path))))
}