use crate::ViewSet;
use hyper::Method;
use reinhardt_http::Handler;
use reinhardt_http::Result;
use std::collections::HashMap;
use std::sync::Arc;
pub struct ViewSetBuilder<V: ViewSet> {
viewset: Arc<V>,
actions: HashMap<Method, String>,
name: Option<String>,
suffix: Option<String>,
}
impl<V: ViewSet + 'static> ViewSetBuilder<V> {
pub fn new(viewset: V) -> Self {
Self {
viewset: Arc::new(viewset),
actions: HashMap::new(),
name: None,
suffix: None,
}
}
pub fn with_actions(mut self, actions: HashMap<Method, String>) -> Self {
self.actions = actions;
self
}
pub fn action(mut self, method: Method, action_name: impl Into<String>) -> Self {
self.actions.insert(method, action_name.into());
self
}
pub fn with_name(mut self, name: impl Into<String>) -> Result<Self> {
if self.suffix.is_some() {
return Err(reinhardt_core::exception::Error::Http(format!(
"{}() received both `name` and `suffix`, which are mutually exclusive arguments.",
std::any::type_name::<V>()
)));
}
self.name = Some(name.into());
Ok(self)
}
pub fn with_suffix(mut self, suffix: impl Into<String>) -> Result<Self> {
if self.name.is_some() {
return Err(reinhardt_core::exception::Error::Http(format!(
"{}() received both `name` and `suffix`, which are mutually exclusive arguments.",
std::any::type_name::<V>()
)));
}
self.suffix = Some(suffix.into());
Ok(self)
}
pub fn build(self) -> Result<Arc<dyn Handler>> {
if self.actions.is_empty() {
return Err(reinhardt_core::exception::Error::Http(
"The `actions` argument must be provided when calling `.as_view()` on a ViewSet. \
For example `.as_view({'get': 'list'})`"
.to_string(),
));
}
Ok(Arc::new(crate::viewsets::handler::ViewSetHandler::new(
self.viewset,
self.actions,
self.name,
self.suffix,
)))
}
pub fn register_to<R>(self, router: &mut R, path: &str) -> Result<()>
where
R: RegisterViewSet,
{
let handler = self.build()?;
router.register_handler(path, handler);
Ok(())
}
}
pub trait RegisterViewSet {
fn register_handler(&mut self, path: &str, handler: Arc<dyn Handler>);
}
#[macro_export]
macro_rules! viewset_actions {
($($method:ident => $action:expr),* $(,)?) => {{
let mut actions = std::collections::HashMap::new();
$(
actions.insert(hyper::Method::$method, $action.to_string());
)*
actions
}};
}