Beginning of applying filters for json types. Currently only supports html escaping.

This commit is contained in:
Tom Alexander
2020-05-23 17:23:48 -04:00
parent 34c8d24a69
commit 6a9fe9e1be
3 changed files with 69 additions and 5 deletions

View File

@@ -73,11 +73,60 @@ fn read_context_from_stdin() -> serde_json::Value {
serde_json::from_str(&buffer).expect("Failed to parse json")
}
fn html_escape(inp: &str) -> String {
// Adding 10% space from the original to avoid re-allocations by
// leaving room for escaped sequences.
let mut output = String::with_capacity(((inp.len() as f64) * 1.1) as usize);
inp.chars().for_each(|c| match c {
'<' => output.push_str("&lt;"),
'>' => output.push_str("&gt;"),
'"' => output.push_str("&quot;"),
'\'' => output.push_str("&#39;"),
'&' => output.push_str("&amp;"),
_ => output.push(c),
});
output
}
fn apply_filter(
json_value: &serde_json::Value,
filter: &Filter,
) -> Result<serde_json::Value, RenderError> {
match (json_value, filter) {
(serde_json::Value::String(string), Filter::HtmlEncode) => {
Ok(serde_json::Value::String(html_escape(string)))
}
(_, Filter::HtmlEncode) => Ok(serde_json::Value::String(html_escape(
&json_value.render(&Vec::new())?,
))),
_ => panic!("Unimplemented"),
}
}
fn apply_filters(
json_value: &serde_json::Value,
filters: &[Filter],
) -> Result<serde_json::Value, RenderError> {
let mut final_value: serde_json::Value = apply_filter(json_value, &filters[0])?;
for filter in &filters[1..] {
final_value = apply_filter(&final_value, filter)?;
}
Ok(final_value)
}
impl ContextElement for serde_json::Value {}
impl Renderable for serde_json::Value {
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
match self {
let after_apply = if _filters.is_empty() {
Some(apply_filters(self, _filters)?)
} else {
None
};
match after_apply.as_ref().unwrap_or(self) {
serde_json::Value::Null => Ok("".to_owned()),
serde_json::Value::Bool(boolean) => Ok(boolean.to_string()),
serde_json::Value::Number(num) => Ok(num.to_string()),
@@ -395,4 +444,9 @@ mod tests {
Ok::<_, RenderError>("3,5,7,9".to_owned())
);
}
#[test]
fn test_html_escape() {
assert_eq!(html_escape("<>&\"'"), "&lt;&gt;&amp;&quot;&#39;".to_owned())
}
}