use std::collections::HashMap;
use super::components_model::SurfaceComponentsModel;
use super::data_context::DataContext;
use super::data_model::DataModel;
use crate::catalog::function_api::FunctionImplementation;
pub struct ComponentContext<'a> {
pub component_id: String,
pub surface_id: String,
pub data_context: DataContext<'a>,
pub components: &'a SurfaceComponentsModel,
pub focused_id: Option<String>,
pub template_index: Option<usize>,
}
impl<'a> ComponentContext<'a> {
pub fn new(
component_id: String,
surface_id: String,
data_model: &'a DataModel,
components: &'a SurfaceComponentsModel,
functions: &'a HashMap<String, Box<dyn FunctionImplementation>>,
base_path: &str,
focused_id: Option<String>,
) -> Self {
let data_context = if base_path.is_empty() {
DataContext::new(data_model, functions)
} else {
DataContext::new(data_model, functions).nested(base_path.trim_start_matches('/'))
};
let template_index = index_from_base_path(base_path);
let data_context = data_context.with_template_index(template_index);
Self {
component_id,
surface_id,
data_context,
components,
focused_id,
template_index,
}
}
pub fn with_template_index(mut self, index: Option<usize>) -> Self {
self.template_index = index;
self.data_context.set_template_index(index);
self
}
pub fn set_template_index(&mut self, index: Option<usize>) {
self.template_index = index;
self.data_context.set_template_index(index);
}
}
fn index_from_base_path(path: &str) -> Option<usize> {
path.rsplit('/').next()?.parse::<usize>().ok()
}
#[cfg(test)]
mod path_tests {
use super::index_from_base_path;
#[test]
fn absolute_template_path() {
assert_eq!(index_from_base_path("/items/0"), Some(0));
assert_eq!(index_from_base_path("/items/42"), Some(42));
}
#[test]
fn relative_template_path() {
assert_eq!(index_from_base_path("items/7"), Some(7));
}
#[test]
fn non_template_paths_yield_none() {
assert_eq!(index_from_base_path(""), None);
assert_eq!(index_from_base_path("/"), None);
assert_eq!(index_from_base_path("/user"), None);
assert_eq!(index_from_base_path("/items/3/name"), None);
}
}