2020-05-09 02:12:35 +00:00
|
|
|
use crate::parser::KVPair;
|
2020-05-09 02:34:58 +00:00
|
|
|
use crate::parser::{Filter, RValue};
|
2020-05-09 02:12:35 +00:00
|
|
|
use crate::renderer::context_element::ContextElement;
|
2020-05-10 23:01:02 +00:00
|
|
|
use crate::renderer::context_element::IntoBoxedContextElement;
|
2020-05-09 18:53:53 +00:00
|
|
|
use crate::renderer::walking::walk_path;
|
2020-05-09 02:34:58 +00:00
|
|
|
use crate::renderer::Loopable;
|
|
|
|
use crate::renderer::RenderError;
|
|
|
|
use crate::renderer::Renderable;
|
2020-05-09 18:10:38 +00:00
|
|
|
use crate::renderer::WalkError;
|
2020-05-09 02:34:58 +00:00
|
|
|
use crate::renderer::Walkable;
|
2020-05-09 02:12:35 +00:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
2020-05-10 22:10:17 +00:00
|
|
|
/// Copy the data from an RValue to an Owned struct
|
|
|
|
///
|
|
|
|
/// In order to get comparisons to work for our `ContextElement` trait
|
|
|
|
/// objects, we need to be able to use `std::any::Any`. Unfortunately,
|
|
|
|
/// `Any` requires that the structs do not have a lifetime (so they
|
|
|
|
/// will have a `'static` lifetime. This means that we cannot have a
|
|
|
|
/// `<'a>` appended to the struct type, so the struct cannot contain
|
|
|
|
/// any borrows. Rather than impose the copy cost in the parser, we
|
|
|
|
/// are imposing the cost of copying the data in the renderer because
|
|
|
|
/// the parser has no reason to not be able to reference data from the
|
|
|
|
/// input string.
|
|
|
|
pub enum OwnedRValue {
|
|
|
|
RVPath(OwnedPath),
|
|
|
|
RVString(String),
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct OwnedPath {
|
|
|
|
pub keys: Vec<String>,
|
|
|
|
}
|
|
|
|
|
2020-05-10 22:19:06 +00:00
|
|
|
impl From<&RValue<'_>> for OwnedRValue {
|
|
|
|
fn from(original: &RValue<'_>) -> Self {
|
2020-05-10 22:10:17 +00:00
|
|
|
match original {
|
|
|
|
RValue::RVString(text) => OwnedRValue::RVString(text.to_owned()),
|
|
|
|
RValue::RVPath(path) => OwnedRValue::RVPath(OwnedPath {
|
|
|
|
keys: path.keys.iter().map(|k| k.to_string()).collect(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct NewParametersContext {
|
|
|
|
params: HashMap<String, OwnedRValue>,
|
2020-05-10 22:19:06 +00:00
|
|
|
breadcrumbs: Vec<Box<dyn ContextElement>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl NewParametersContext {
|
|
|
|
pub fn new(
|
|
|
|
breadcrumbs: &Vec<&dyn ContextElement>,
|
|
|
|
params: &Vec<KVPair>,
|
|
|
|
) -> NewParametersContext {
|
|
|
|
let owned_params: HashMap<String, OwnedRValue> = params
|
|
|
|
.iter()
|
|
|
|
.map(|kvpair| (kvpair.key.to_string(), OwnedRValue::from(&kvpair.value)))
|
|
|
|
.collect();
|
|
|
|
|
2020-05-10 22:35:24 +00:00
|
|
|
let x: String = "foo".to_owned();
|
|
|
|
let y: &dyn ContextElement = &x as _;
|
2020-05-10 23:01:02 +00:00
|
|
|
let z: Box<dyn ContextElement> = y.clone().to_box();
|
2020-05-10 22:45:54 +00:00
|
|
|
// let owned_y: Box<dyn ContextElement> = Box::new(*y.clone());
|
|
|
|
// unsafe {
|
|
|
|
// let ce = &mut *y.clone() as *mut dyn ContextElement;
|
|
|
|
// Box::from_raw(ce);
|
|
|
|
// }
|
2020-05-10 22:35:24 +00:00
|
|
|
|
|
|
|
// let owned_breadcrumbs: Vec<Box<dyn ContextElement>> =
|
|
|
|
// breadcrumbs.iter().map(|ce| Box::new(*ce.clone())).collect();
|
|
|
|
|
2020-05-10 22:19:06 +00:00
|
|
|
NewParametersContext {
|
|
|
|
params: owned_params,
|
|
|
|
breadcrumbs: Vec::new(),
|
|
|
|
}
|
|
|
|
}
|
2020-05-10 22:10:17 +00:00
|
|
|
}
|
|
|
|
|
2020-05-10 23:01:02 +00:00
|
|
|
// #[derive(Clone, Debug)]
|
|
|
|
// pub struct ParametersContext<'a> {
|
|
|
|
// params: HashMap<&'a str, &'a RValue<'a>>,
|
|
|
|
// breadcrumbs: &'a Vec<&'a dyn ContextElement>,
|
|
|
|
// }
|
|
|
|
|
|
|
|
// impl<'a> ParametersContext<'a> {
|
|
|
|
// pub fn new(
|
|
|
|
// breadcrumbs: &'a Vec<&'a dyn ContextElement>,
|
|
|
|
// params: &'a Vec<KVPair<'a>>,
|
|
|
|
// ) -> ParametersContext<'a> {
|
|
|
|
// let param_map = params
|
|
|
|
// .iter()
|
|
|
|
// .map(|pair: &KVPair<'a>| (pair.key, &pair.value))
|
|
|
|
// .collect();
|
|
|
|
// ParametersContext {
|
|
|
|
// params: param_map,
|
|
|
|
// breadcrumbs: breadcrumbs,
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// impl<'a> ContextElement for ParametersContext<'a> {}
|
|
|
|
|
|
|
|
// impl<'a> Renderable for ParametersContext<'a> {
|
|
|
|
// fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
|
|
|
|
// // TODO: Would this even ever be called? Won't matter, but I'd
|
|
|
|
// // like to know. Since it is injected 1 above the current
|
|
|
|
// // context, we wouldn't be able to access it with `{.}`.
|
|
|
|
// Ok("[object Object]".to_owned())
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// impl<'a> Loopable for ParametersContext<'a> {
|
|
|
|
// fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
|
|
|
|
// // TODO: Would this even ever be called? Won't matter, but I'd
|
|
|
|
// // like to know. Since it is injected 1 above the current
|
|
|
|
// // context, we wouldn't be able to access it with `{.}`.
|
|
|
|
// vec![self]
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// impl<'a> Walkable for ParametersContext<'a> {
|
|
|
|
// fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> {
|
|
|
|
// let rval = self.params.get(segment).ok_or(WalkError::CantWalk)?;
|
|
|
|
// match rval {
|
|
|
|
// RValue::RVPath(path) => walk_path(self.breadcrumbs, &path.keys),
|
|
|
|
// RValue::RVString(text) => Ok(text),
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
2020-05-09 18:53:53 +00:00
|
|
|
|
|
|
|
impl ContextElement for String {}
|
|
|
|
|
|
|
|
impl Renderable for String {
|
|
|
|
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
|
|
|
|
Ok(self.clone())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Loopable for String {
|
|
|
|
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
|
|
|
|
if self.is_empty() {
|
|
|
|
Vec::new()
|
|
|
|
} else {
|
|
|
|
vec![self]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Walkable for String {
|
|
|
|
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> {
|
2020-05-09 18:10:38 +00:00
|
|
|
Err(WalkError::CantWalk)
|
2020-05-09 02:34:58 +00:00
|
|
|
}
|
|
|
|
}
|