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

master
Tom Alexander 4 years ago
parent 34c8d24a69
commit 6a9fe9e1be
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

@ -10,5 +10,6 @@
],
"object": {
"foo": "bar"
}
},
"special_characters": "<>&\"'"
}

@ -1,6 +1,15 @@
Object parsed: {string|jp}{~n}
Object parsed and stringified: {string|jp|js}{~n}
Object stringified and parsed: {string|js|jp}{~n}
Special characters: {special_characters}{~n}
Object string parsed: {string|jp}{~n}
Object string parsed and stringified: {string|jp|js}{~n}
Object string stringified and parsed: {string|js|jp}{~n}
Array: {array}{~n}
Array stringified: {array|js}{~n}
Array stringified and parsed: {array|js|jp}{~n}
Object: {object}{~n}
Object html escaped: {object|h}{~n}
Object html escaping disabled: {object|s}{~n}
Object stringified: {object|js}{~n}
Object stringified and parsed: {object|js|jp}{~n}

@ -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())
}
}

Loading…
Cancel
Save