Change the prototype of from_str to allow &mut str in order to allow for simd-json

No performance numbers yet or anything else substantial, but this does at least
pass the unit tests.

Unfortunately there _is_ an `unsafe` call in this simd_json helper code which
does an unsafe &str.as_bytes_mut().
This commit is contained in:
R Tyler Croy 2020-09-07 09:48:49 -07:00
parent 5c42097621
commit 03abb26b3d
2 changed files with 31 additions and 18 deletions

View File

@ -99,8 +99,11 @@ impl Connection {
}
/*
* Now that we've logged the error, let's unpack and bubble the error anyways
*
* Note: msg needs to be mutable so we can fish the `msg` out within it during a
* simd_json parse
*/
let msg = parsed.unwrap();
let mut msg = parsed.unwrap();
self.stats.send((Stats::LineReceived, 1)).await;
let mut continue_rules = true;
debug!("parsed as: {}", msg.msg);
@ -215,9 +218,11 @@ impl Connection {
Action::Merge { json, json_str: _ } => {
debug!("merging JSON content: {}", json);
if let Ok(buffer) =
perform_merge(&msg.msg, &template_id_for(&rule, index), &rule_state)
{
if let Ok(buffer) = perform_merge(
&mut msg.msg,
&template_id_for(&rule, index),
&rule_state,
) {
output = buffer;
} else {
continue_rules = false;
@ -316,10 +321,14 @@ fn precompile_jmespath(map: &mut JmesPathExpressions, settings: Arc<Settings>) -
/**
* perform_merge will generate the buffer resulting of the JSON merge
*/
fn perform_merge(buffer: &str, template_id: &str, state: &RuleState) -> Result<String, String> {
if let Ok(mut msg_json) = crate::json::from_str(&buffer) {
if let Ok(rendered) = state.hb.render(template_id, &state.variables) {
let to_merge: serde_json::Value = crate::json::from_str(&rendered)
fn perform_merge(
mut buffer: &mut str,
template_id: &str,
state: &RuleState,
) -> Result<String, String> {
if let Ok(mut msg_json) = crate::json::from_str(&mut buffer) {
if let Ok(mut rendered) = state.hb.render(template_id, &state.variables) {
let to_merge: serde_json::Value = crate::json::from_str(&mut rendered)
.expect("Failed to deserialize our rendered to_merge_str");
/*
@ -374,7 +383,8 @@ mod tests {
let hash = HashMap::<String, String>::new();
let state = rule_state(&hb, &hash);
let output = perform_merge("{}", template_id, &state);
let mut buffer = "{}".to_string();
let output = perform_merge(&mut buffer, template_id, &state);
assert_eq!(output, Ok("{}".to_string()));
}
@ -390,7 +400,8 @@ mod tests {
let hash = HashMap::<String, String>::new();
let state = rule_state(&hb, &hash);
let output = perform_merge("{}", template_id, &state)?;
let mut buffer = "{}".to_string();
let output = perform_merge(&mut buffer, template_id, &state)?;
assert_eq!(output, "{}".to_string());
Ok(())
}
@ -407,7 +418,8 @@ mod tests {
let hash = HashMap::<String, String>::new();
let state = rule_state(&hb, &hash);
let output = perform_merge("invalid", template_id, &state);
let mut buffer = "invalid".to_string();
let output = perform_merge(&mut buffer, template_id, &state);
let expected = Err("Not JSON".to_string());
assert_eq!(output, expected);
}
@ -424,7 +436,8 @@ mod tests {
let hash = HashMap::<String, String>::new();
let state = rule_state(&hb, &hash);
let output = perform_merge("{}", template_id, &state);
let mut buffer = "{}".to_string();
let output = perform_merge(&mut buffer, template_id, &state);
assert_eq!(output, Ok("{\"hello\":1}".to_string()));
}
@ -441,7 +454,8 @@ mod tests {
hash.insert("name".to_string(), "world".to_string());
let state = rule_state(&hb, &hash);
let output = perform_merge("{}", template_id, &state);
let mut buffer = "{}".to_string();
let output = perform_merge(&mut buffer, template_id, &state);
assert_eq!(output, Ok("{\"hello\":\"world\"}".to_string()));
}

View File

@ -2,22 +2,21 @@
* This module acts as a shim between serde_json and simd-json to allow for higher performance JSON
* parsing on SIMD-capable architectures
*/
use serde;
use serde_json;
#[cfg(feature = "simd")]
use simd_json;
pub fn from_str<'a, S: serde::Deserialize<'a>>(buffer: &'a str) -> Result<S, serde_json::error::Error> {
pub fn from_str<'a, S: serde::Deserialize<'a>>(buffer: &'a mut str) -> Result<S, std::io::Error> {
#[cfg(feature = "simd")]
{
simd_json::serde::from_str::<S>(buffer)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
}
#[cfg(not(feature="simd"))]
#[cfg(not(feature = "simd"))]
{
serde_json::from_str::<S>(buffer)
serde_json::from_str::<S>(buffer).map_err(|e| e.into())
}
}