use super::DefaultViewLocator;
use crate::binding::interfaces::{IntoViewFor, IViewFor};
use ferroui_splat::{AppLocator, ReadonlyDependencyResolverExt};
use std::fmt;
use std::rc::Rc;
pub struct ViewMappingBuilder<'a> {
locator: &'a DefaultViewLocator,
}
impl fmt::Debug for ViewMappingBuilder<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ViewMappingBuilder").field("locator", self.locator).finish()
}
}
impl<'a> ViewMappingBuilder<'a> {
pub fn new(locator: &'a DefaultViewLocator) -> Self {
Self { locator }
}
pub fn map<VM: 'static, V: IViewFor + Default>(&self, contract: Option<&str>) -> &Self {
self.locator.map::<VM, V>(contract);
self
}
pub fn map_factory<VM: 'static>(&self, factory: impl Fn() -> Rc<dyn IViewFor> + 'static, contract: Option<&str>) -> &Self {
self.locator.map_factory::<VM>(factory, contract);
self
}
pub fn map_from_service_locator<VM: 'static, V: IntoViewFor + ?Sized + 'static>(&self, contract: Option<&str>, service_contract: Option<&str>) -> &Self {
let service_contract: Option<String> = service_contract.map(str::to_owned);
self.locator.map_factory::<VM>(
move || match AppLocator::current().get_service_with_contract::<V>(service_contract.as_deref()) {
Some(view) => view.into_view_for(),
None => match &service_contract {
None => panic!("InvalidOperationException: View {} is not registered in the service locator.", std::any::type_name::<V>()),
Some(service_contract) => panic!(
"InvalidOperationException: View {} is not registered in the service locator under contract '{service_contract}'.",
std::any::type_name::<V>()
),
},
},
contract,
);
self
}
}