diff --git a/Cargo.lock b/Cargo.lock index 5128b19..e578471 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", "getrandom", @@ -16,15 +16,21 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bumpalo" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "cfg-if" @@ -50,20 +56,22 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] name = "halfbrown" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f985624e90f861184145c13b736873a0f83cdb998a292dbb0653598ab03aecbf" +checksum = "5681137554ddff44396e5f149892c769d45301dd9aa19c51602a89ee214cb0ec" dependencies = [ "arrayvec", "hashbrown", @@ -72,24 +80,27 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ "ahash", ] [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] -name = "itoa" -version = "1.0.2" +name = "js-sys" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] [[package]] name = "lexical-core" @@ -157,63 +168,69 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.144" +version = "0.2.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" + +[[package]] +name = "log" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" -version = "1.0.125" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", @@ -222,22 +239,23 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ - "itoa 0.4.7", + "itoa", "ryu", "serde", ] [[package]] name = "simd-json" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d0815e7ff0f1f05e09d4b029f86d8a330f0ab15b35b28736f3758325f59e14" +checksum = "474b451aaac1828ed12f6454a80fe58b940ae2998d10389d41533940a6f641bf" dependencies = [ "ahash", + "getrandom", "halfbrown", "lexical-core", "once_cell", @@ -261,20 +279,20 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "1.0.67" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] -name = "unicode-xid" -version = "0.2.1" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "value-trait" @@ -284,7 +302,7 @@ checksum = "09a5b6c8ceb01263b969cac48d4a6705134d490ded13d889e52c0cfc80c6945e" dependencies = [ "float-cmp", "halfbrown", - "itoa 1.0.2", + "itoa", "ryu", ] @@ -299,3 +317,57 @@ name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" diff --git a/Cargo.toml b/Cargo.toml index c7e966e..eb92085 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ description = "Logstash inspired dissect extractor" readme = "README.md" [dependencies] -simd-json = { version = "0.10.3" } +simd-json = { version = "0.11" } [features] default = ["known-key"] diff --git a/src/lib.rs b/src/lib.rs index bae90f9..66cc0ad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,17 +17,16 @@ //! //! ```rust //! use dissect::{Pattern, Error}; -//! use simd_json::{borrowed::{Value, Object}, ObjectInit}; -//! +//! use simd_json::{borrowed::Value, prelude::*}; //! let filter = Pattern::compile("%{a} %{b}")?; //! let input = "John Doe"; //! -//! let output = filter.run(input).unwrap_or_default(); -//! let mut expected = Object::new(); -//! expected.insert("a".into(), Value::from("John")); -//! expected.insert("b".into(), Value::from("Doe")); +//! let output = filter.run(input); +//! let mut expected = Value::object(); +//! expected.try_insert("a", Value::from("John")); +//! expected.try_insert("b", Value::from("Doe")); //! -//! assert_eq!(output, expected); +//! assert_eq!(output.as_ref(), expected.as_object()); //! # Ok::<(), Error>(()) //! ``` //! @@ -40,15 +39,15 @@ //! //! ```rust //! use dissect::{Pattern, Error}; -//! use simd_json::{borrowed::{Value, Object}, ObjectInit}; +//! use simd_json::{borrowed::Value, prelude::*}; //! //! let output = Pattern::compile("%{name}, %{age}")?; -//! let output = output.run("John Doe, 22").unwrap_or_default(); -//! let mut expected = Object::new(); -//! expected.insert("name".into(), Value::from("John Doe")); -//! expected.insert("age".into(), Value::from("22")); +//! let output = output.run("John Doe, 22"); +//! let mut expected = Value::object(); +//! expected.try_insert("name", Value::from("John Doe")); +//! expected.try_insert("age", Value::from("22")); //! -//! assert_eq!(output, expected); +//! assert_eq!(output.as_ref(), expected.as_object()); //! # Ok::<(), Error>(()) //! ``` //! @@ -58,14 +57,15 @@ //! //! ```rust //! use dissect::{Pattern, Error}; -//! use simd_json::{borrowed::{Value, Object}, ObjectInit}; +//! use simd_json::{borrowed::Value, prelude::*}; +//! //! let output = Pattern::compile( "%{+name} %{+name}, %{age}")?; -//! let output = output.run("John Doe, 22").unwrap_or_default(); -//! let mut expected = Object::new(); -//! expected.insert("name".into(), Value::from("John Doe")); -//! expected.insert("age".into(), Value::from("22")); +//! let output = output.run("John Doe, 22"); +//! let mut expected = Value::object(); +//! expected.try_insert("name", Value::from("John Doe")); +//! expected.try_insert("age", Value::from("22")); //! -//! assert_eq!(output, expected); +//! assert_eq!(output.as_ref(), expected.as_object()); //! # Ok::<(), Error>(()) //! ``` //! @@ -86,12 +86,12 @@ //! //! ```rust //! use dissect::{Pattern, Error}; -//! use simd_json::{borrowed::{Value, Object}, ObjectInit}; +//! use simd_json::{borrowed::Value, prelude::*}; //! let output = Pattern::compile("%{?name}, %{&name}")?; -//! let output = output.run( "John Doe, 22").unwrap_or_default(); -//! let mut expected = Object::new(); -//! expected.insert("John Doe".into(), Value::from("22")); -//! assert_eq!(output, expected); +//! let output = output.run( "John Doe, 22"); +//! let mut expected = Value::object(); +//! expected.try_insert("John Doe", Value::from("22")); +//! assert_eq!(output.as_ref(), expected.as_object()); //! # Ok::<(), Error>(()) //! ``` //! @@ -101,14 +101,14 @@ //! //! ```rust //! use dissect::{Pattern, Error}; -//! use simd_json::{borrowed::{Value, Object}, ObjectInit}; +//! use simd_json::{borrowed::Value, prelude::*}; //! //! let output = Pattern::compile("%{name}, %{age}")?; -//! let output = output.run(", 22").unwrap_or_default(); -//! let mut expected = Object::new(); -//! expected.insert("name".into(), Value::from("")); -//! expected.insert("age".into(), Value::from("22")); -//! assert_eq!(output, expected); +//! let output = output.run(", 22"); +//! let mut expected = Value::object(); +//! expected.try_insert("name", Value::from("")); +//! expected.try_insert("age", Value::from("22")); +//! assert_eq!(output.as_ref(), expected.as_object()); //! # Ok::<(), Error>(()) //! ``` //! @@ -118,13 +118,14 @@ //! //! ```rust //! use dissect::{Pattern, Error}; -//! use simd_json::{borrowed::{Value, Object}, ObjectInit}; +//! use simd_json::{borrowed::Value, prelude::*}; +//! //! let output = Pattern::compile("%{?first_name} %{last_name}, %{age}")?; -//! let output = output.run("John Doe, 22").unwrap_or_default(); -//! let mut expected = Object::new(); -//! expected.insert("last_name".into(), Value::from("Doe")); -//! expected.insert("age".into(), Value::from("22")); -//! assert_eq!(output, expected); +//! let output = output.run("John Doe, 22"); +//! let mut expected = Value::object(); +//! expected.try_insert("last_name", "Doe"); +//! expected.try_insert("age", "22"); +//! assert_eq!(output.as_ref(), expected.as_object()); //! # Ok::<(), Error>(()) //! ``` //! @@ -137,13 +138,14 @@ //! ```rust //! //! use dissect::{Pattern, Error}; -//! use simd_json::{borrowed::{Value, Object}, ObjectInit}; +//! use simd_json::{borrowed::Value, prelude::*}; +//! //! let output = Pattern::compile("%{name}, %{age:int}")?; -//! let output = output.run( "John Doe, 22").unwrap_or_default(); -//! let mut expected = Object::new(); -//! expected.insert("name".into(), Value::from("John Doe")); -//! expected.insert("age".into(),Value::from(22)); -//! assert_eq!(output, expected); +//! let output = output.run( "John Doe, 22"); +//! let mut expected = Value::object(); +//! expected.try_insert("name", "John Doe"); +//! expected.try_insert("age",22); +//! assert_eq!(output.as_ref(), expected.as_object()); //! # Ok::<(), Error>(()) //! ``` //! @@ -154,25 +156,27 @@ //! //! ```rust //! use dissect::{Pattern, Error}; -//! use simd_json::{borrowed::{Value, Object}, ObjectInit}; +//! use simd_json::{borrowed::Value, prelude::*}; +//! //! let output = Pattern::compile("%{name}, %{_}%{age}")?; -//! let output = output.run("John Doe, 22").unwrap_or_default(); -//! let mut expected = Object::new(); -//! expected.insert("name".into(), Value::from("John Doe")); -//! expected.insert("age".into(), Value::from("22")); -//! assert_eq!(output, expected); +//! let output = output.run("John Doe, 22"); +//! let mut expected = Value::object(); +//! expected.try_insert("name", "John Doe"); +//! expected.try_insert("age", "22"); +//! assert_eq!(output.as_ref(), expected.as_object()); //! # Ok::<(), Error>(()) //! ``` //! //! ```rust //! use dissect::{Pattern, Error}; -//! use simd_json::{borrowed::{Value, Object}, ObjectInit}; +//! use simd_json::{borrowed::Value, prelude::*}; +//! //! let output = Pattern::compile("%{name}, %{_(-)}%{age}")?; -//! let output = output.run("John Doe, -----------------------22").unwrap_or_default(); -//! let mut expected = Object::new(); -//! expected.insert("name".into(), Value::from("John Doe")); -//! expected.insert("age".into(), Value::from("22")); -//! assert_eq!(output, expected); +//! let output = output.run("John Doe, -----------------------22"); +//! let mut expected = Value::object(); +//! expected.try_insert("name","John Doe"); +//! expected.try_insert("age", "22"); +//! assert_eq!(output.as_ref(), expected.as_object()); //! # Ok::<(), Error>(()) //! ``` @@ -403,10 +407,9 @@ impl Pattern { return Err(Error::PaddingFollowedBySelf(idx)); }; false + } else if was_extract { + return Err(Error::ConnectedExtractors(idx)); } else { - if was_extract { - return Err(Error::ConnectedExtractors(idx)); - }; true }; commands.push(p); @@ -475,12 +478,7 @@ impl Pattern { // No more pattern we're good if no data is left otherwise // we do not match None => { - return if data.is_empty() { - Some(r) - } else { - // We still have data left so it's not a string - None - }; + return data.is_empty().then_some(r); } // We want to skip some text, do so if it's there Some(Command::Delimiter(s)) => { @@ -617,8 +615,7 @@ impl PartialEq> for Pattern { #[cfg(test)] mod test { use super::*; - use simd_json::value::borrowed::Value; - use simd_json::ObjectInit; + use simd_json::{value::borrowed::Value, Builder, Mutable, ValueAccess}; fn cp(pattern: &str) -> Pattern { Pattern::compile(pattern).expect("failed to compile pattern") @@ -964,10 +961,13 @@ mod test { fn do_extract2() { let p = Pattern::compile("this is a %{what} case named %{name}") .expect("failed to compile pattern"); - let mut m = Object::new(); - m.insert("what".into(), Value::from("test")); - m.insert("name".into(), Value::from("cake")); - assert_eq!(p.run("this is a test case named cake"), Some(m)); + let mut m = Value::object(); + m.try_insert("what", "test"); + m.try_insert("name", "cake"); + assert_eq!( + p.run("this is a test case named cake").as_ref(), + m.as_object() + ); } #[test] @@ -996,10 +996,13 @@ mod test { }, ] ); - let mut m = Object::new(); - m.insert("what".into(), Value::from("test")); - m.insert("name".into(), Value::from("cake")); - assert_eq!(p.run("this is a test case named cake"), Some(m)); + let mut m = Value::object(); + m.try_insert("what", "test"); + m.try_insert("name", "cake"); + assert_eq!( + p.run("this is a test case named cake").as_ref(), + m.as_object() + ); } #[test] @@ -1009,8 +1012,8 @@ mod test { p, vec![pad(" "), del("this"), pad(" "), pad("-"), del("works"),] ); - let m = simd_json::borrowed::Object::new(); - assert_eq!(p.run("this -----works"), Some(m)); + let m = Value::object(); + assert_eq!(p.run("this -----works").as_ref(), m.as_object()); } #[test] @@ -1031,40 +1034,40 @@ mod test { del("|"), ] ); - let mut m = Object::new(); - m.insert("n".into(), Value::from("Jim")); - assert_eq!(p.run("|Jim |"), Some(m)); - let mut m = Object::new(); - m.insert("n".into(), Value::from("John")); - assert_eq!(p.run("|John|"), Some(m)); + let mut m = Value::object(); + m.try_insert("n", "Jim"); + assert_eq!(p.run("|Jim |").as_ref(), m.as_object()); + let mut m = Value::object(); + m.try_insert("n", "John"); + assert_eq!(p.run("|John|").as_ref(), m.as_object()); } #[test] fn middle_pads() { let p = cp("%{a}%{_}%{b}"); assert_eq!(p, vec![pat("a"), pad(" "), pat("b"),]); - let mut m = Object::new(); - m.insert("a".into(), Value::from("this")); - m.insert("b".into(), Value::from("works")); - assert_eq!(p.run("this works"), Some(m)); + let mut m = Value::object(); + m.try_insert("a", "this"); + m.try_insert("b", "works"); + assert_eq!(p.run("this works").as_ref(), m.as_object()); } #[test] fn left_pads() { let p = Pattern::compile("%{_}%{b}").expect("failed to compile pattern"); assert_eq!(p, vec![pad(" "), pat("b"),]); - let mut m = Object::new(); - m.insert("b".into(), Value::from("works")); - assert_eq!(p.run(" works"), Some(m)); + let mut m = Value::object(); + m.try_insert("b", "works"); + assert_eq!(p.run(" works").as_ref(), m.as_object()); } #[test] fn right_pads() { let p = Pattern::compile("%{a}%{_}").expect("failed to compile pattern"); assert_eq!(p, vec![pat("a"), pad(" ")]); - let mut m = Object::new(); - m.insert("a".into(), Value::from("this")); - assert_eq!(p.run("this "), Some(m)); + let mut m = Value::object(); + m.try_insert("a", "this"); + assert_eq!(p.run("this ").as_ref(), m.as_object()); } #[test] @@ -1083,9 +1086,9 @@ mod test { pad(" "), ] ); - let mut m = Object::new(); - m.insert("a".into(), Value::from("this")); - assert_eq!(p.run("this"), Some(m)); + let mut m = Value::object(); + m.try_insert("a", "this"); + assert_eq!(p.run("this").as_ref(), m.as_object()); } #[test] @@ -1114,19 +1117,25 @@ mod test { }, ] ); - let mut m = Object::new(); - m.insert("what".into(), Value::from("test")); - m.insert("name".into(), Value::from("cake")); - assert_eq!(p.run("this is a test case named cake"), Some(m)); + let mut m = Value::object(); + m.try_insert("what", "test"); + m.try_insert("name", "cake"); + assert_eq!( + p.run("this is a test case named cake").as_ref(), + m.as_object() + ); } #[test] fn do_extract_ignore() { let p = Pattern::compile("this is a %{?what} case named %{name}") .expect("failed to compile pattern"); - let mut m = Object::new(); - m.insert("name".into(), Value::from("cake")); - assert_eq!(p.run("this is a test case named cake"), Some(m)); + let mut m = Value::object(); + m.try_insert("name", "cake"); + assert_eq!( + p.run("this is a test case named cake").as_ref(), + m.as_object() + ); } #[test] @@ -1143,24 +1152,42 @@ mod test { ("test", "cake") ); assert_pattern!("%{?name}: %{&name:int}", "key: 42", ("key", 42)); + assert_pattern!("%{?name}: %{&name:float}", "key: 42.0", ("key", 42.0)); + assert_pattern!("%{?name}: %{&name:string}", "key: 42.0", ("key", "42.0")); } #[test] fn do_arr() { let p = Pattern::compile("this is a %{+arr} case named %{+arr}") .expect("failed to compile pattern"); - let mut m = Object::new(); - m.insert("arr".into(), Value::from("test cake")); - assert_eq!(p.run("this is a test case named cake"), Some(m)); + let mut m = Value::object(); + m.try_insert("arr", "test cake"); + assert_eq!( + p.run("this is a test case named cake").as_ref(), + m.as_object() + ); } #[test] fn do_arr_upgrade() { let p = Pattern::compile("this is a %{arr} case named %{+arr}") .expect("failed to compile pattern"); - let mut m = Object::new(); - m.insert("arr".into(), Value::from("test cake")); - assert_eq!(p.run("this is a test case named cake"), Some(m)); + let mut m = Value::object(); + m.try_insert("arr", "test cake"); + assert_eq!( + p.run("this is a test case named cake").as_ref(), + m.as_object() + ); + } + #[test] + fn errors() { + assert!(Pattern::compile("%{}%{}").is_err()); + assert!(Pattern::compile("%{arr").is_err()); + assert!(Pattern::compile("%{_(-)}-").is_err()); + assert!(Pattern::compile("%{_-}-").is_err()); + assert!(Pattern::compile("%{a:bad-type}-").is_err()); + assert!(Pattern::compile(r"\x").is_err()); + assert!(Pattern::compile(r"\").is_err()); } #[allow(clippy::too_many_lines)] diff --git a/tests/dissect.rs b/tests/dissect.rs index 15e8ab2..2b770a9 100644 --- a/tests/dissect.rs +++ b/tests/dissect.rs @@ -14,7 +14,6 @@ use dissect::*; use simd_json::value::borrowed::{Object, Value}; -use simd_json::ObjectInit; fn cp(pattern: &str) -> Pattern { Pattern::compile(pattern).expect("failed to compile pattern") @@ -36,13 +35,13 @@ where } macro_rules! assert_pattern { - ($pattern:expr, $input:expr) => { - assert_eq!(run($pattern, $input), None) - }; - ($pattern:expr, $input:expr, $($args:expr),*) => { - assert_eq!(run($pattern, $input), v(&[$($args),*])) - }; -} + ($pattern:expr, $input:expr) => { + assert_eq!(run($pattern, $input), None) + }; + ($pattern:expr, $input:expr, $($args:expr),*) => { + assert_eq!(run($pattern, $input), v(&[$($args),*])) + }; + } #[test] fn dissect_all_edgecases() { @@ -164,1240 +163,10 @@ fn do_extract() { } #[test] fn do_extract2() { - let p = Pattern::compile("this is a %{what} case named %{name}") - .expect("failed to compile pattern"); - let mut m = Object::new(); - m.insert("what".into(), Value::from("test")); - m.insert("name".into(), Value::from("cake")); - assert_eq!(p.run("this is a test case named cake"), Some(m)) -} - -/* Old tests - - -#[cfg(test)] -mod tests { - use super::*; - use simd_json::borrowed::Value as SimdValue; - - fn p(s: &str) -> Token { - Token::Field(s.into()) - } - - fn d(s: &str) -> Token { - (Token::Delimiter(s.to_string())) - } - - fn v<'dissect>(s: &'dissect [(&str, &str)]) -> Dissect<'dissect> { - Dissect( - s.into_iter() - .map(|(x, y)| { - ( - Into::>::into(*x), - SimdValue::String(y.to_string().into()), - ) - }) - .collect(), - ) - } - - fn pad(s: &str) -> Token { - Token::Padding(s.to_string()) - } - - #[test] - fn dissect_multiple_padding() { - let pattern = "%{name}%{_}%{_(|)}"; - let input = "John ||"; - assert_eq!( - Pattern::try_from(pattern) - .expect("") - .extract(input) - .expect(""), - v(&[("name", "John")]) - ); - } - - #[test] - fn dissect_multiple_padding_in_the_middle_1() { - let pattern = "%{name}%{_}%{_(|)}%{age}"; - let input = "John ||22"; - assert_eq!( - Pattern::try_from(pattern) - .expect("") - .extract(input) - .expect(""), - v(&[("name", "John"), ("age", "22")]) - ); - } - - #[test] - fn dissect_multiple_padding_in_the_middle_with_delim_err() { - let pattern = "%{name}%{_}%{_(|)}/ %{age}"; - let input = "John |/ 22"; - let output = Pattern::try_from(pattern).expect(""); - let output = output.extract(input).expect(""); - assert_eq!(output, v(&([("name", "John"), ("age", "22")]))); - } - - #[test] - fn dissect_skipped_fields() { - let pattern = "%{?first_name} %{last_name}"; - let input = "John Doe"; - assert_eq!( - Pattern::try_from(pattern) - .expect("") - .extract(input) - .expect("skipped fields doesn't work"), - v(&[("last_name", "Doe")]) - ); - } - - #[test] - fn question_mark_with_nothing_doesnt_parse() { - let pattern = "%{?} %{something}"; - let output = lex(pattern); - assert_eq!( - output, - Err(DissectError::ParseError(ParseError::InvalidToken( - "?".to_owned(), - 0 - ))) - ); - } - - #[test] - fn dissect_skipped_field_alone() { - let pattern = "%{?foo}"; - let input = "John"; - let output = Pattern::try_from(pattern).expect(""); - let output = output - .extract(input) - .expect("plain skipped field doesnt work"); - assert_eq!(output, Dissect(HashMap::new())); - } - - #[test] - fn dissect_multiple_skipped_fields() { - let pattern = "%{?first_name} %{?middle_name} %{last_name}"; - let input = "John Michael Doe"; - let output = Pattern::try_from(pattern).expect(""); - let output = output - .extract(input) - .expect("multiple skipped fields doesn't work"); - assert_eq!(output, v(&[("last_name", "Doe")])); - } - - #[test] - fn dissect_skipped_field_at_eol() { - let pattern = "%{first_name} %{?last_name}"; - let input = "John Doe"; - let output = Pattern::try_from(pattern).expect(""); - let output = output - .extract(input) - .expect("dissect doesn't skip fields at end of line"); - assert_eq!(output, v(&[("first_name", "John")])); - } - - #[test] - fn dissect_with_integer_type() { - let pattern = "%{name} %{age:int}"; - let input = "John 22"; - let output = Pattern::try_from(pattern).expect(""); - let output = output.extract(input).expect("dissect doesn't do types"); - let mut expected = HashMap::new(); - expected.insert("name".into(), SimdValue::String("John".into())); - expected.insert("age".into(), SimdValue::from(22)); - assert_eq!(output, Dissect(expected)); - } - - #[test] - fn dissect_with_float_type() { - let pattern = "%{name} %{tax:float}"; - let input = "John 414.203"; - let output = Pattern::try_from(pattern).expect(""); - let output = output.extract(input).expect("dissect doesn't float"); - - assert_eq!( - output.0.get("name".into()), - Some(&SimdValue::String("John".into())) - ); - match output.0.get("tax".into()) { - Some(SimdValue::from(f)) => assert!((f - 414.203).abs() < 0.001), - _ => unreachable!(), - }; - } - - #[test] - fn dissect_with_string_is_a_noop() { - let pattern = "%{name:string}"; - let input = "John"; - let output = Pattern::try_from(pattern).expect(""); - let output = output.extract(input).expect( - "dissect doesn't work with string as a type even though it is a string already", - ); - let mut expected = HashMap::new(); - expected.insert("name".into(), SimdValue::String("John".into())); - - assert_eq!(output, Dissect(expected)); - } - - #[test] - fn dissect_with_wrong_type_errors_out() { - let pattern = "%{name} %{age:wakanda}"; - let output = Pattern::try_from(pattern); - assert_eq!( - output, - Err(DissectError::ParseError(ParseError::TypeNotSupported( - "wakanda".to_string() - ))) - ); - } - - #[test] - fn lex_multiple_colons_is_invalid() { - let input = "%{foo:int:float}"; - let output = lex(input); - assert_eq!( - output, - Err(DissectError::ParseError(ParseError::InvalidToken( - "foo:int:float".to_owned(), - 0 - ))) - ); - } - - #[test] - fn dissect_with_no_field_name() { - let pattern = "%{} %{name}"; - let input = "Foo John"; - let output = Pattern::try_from(pattern).expect(""); - let output = output - .extract(input) - .expect("dissect doesn't like empty fields"); - assert_eq!(output, v(&[("name", "John")])); - } - - #[test] - fn dissect_append_field() { - let pattern = "%{+name} %{+name} %{age}"; - let input = "John Doe 22"; - let output = Pattern::try_from(pattern).expect(""); - let output = output.extract(input).expect("dissect doesn't like append"); - assert_eq!(output, v(&[("name", "John Doe"), ("age", "22")])); - } - - #[test] - fn lex_simple_append() { - let input = "%{+name} %{+name}"; - let output = lex(input).expect("doesn't lex appends"); - - assert_eq!( - output, - vec![ - Token::Field(Field { - value: "name".into(), - category: Some(FieldCategory::Append("name".into())) - }), - Token::Delimiter(" ".to_string()), - Token::Field(Field { - value: "name".into(), - category: Some(FieldCategory::Append("name".into())) - }) - ] - ); - } - - #[test] - fn dissect_simple_append() { - let pattern = "%{+name} %{+name}"; - let input = "John Doe"; - let output = Pattern::try_from(pattern).expect(""); - let output = output.extract(input).expect("dissect doesn't append"); - assert_eq!(output, v(&[("name", "John Doe")])); - } - - #[test] - fn dissect_out_of_order_append() { - let pattern = "%{+name} %{age} %{+name}"; - let input = "John 22 Doe"; - let output = Pattern::try_from(pattern).expect(""); - let output = output.extract(input).expect("out of order"); - assert_eq!(output, v(&[("name", "John Doe"), ("age", "22")])); - } - - #[test] - fn dissect_multiple_append() { - let pattern = "%{+name} %{+country}|%{+name} %{+country}"; - let input = "John United|Doe States"; - let output = Pattern::try_from(pattern).expect(""); - - let output = output.extract(input).expect("doesn't work with 2 appends"); - assert_eq!( - output, - v(&[("name", "John Doe"), ("country", "United|States")]) - ) - } - - #[test] - fn lex_fails_for_append_and_types() { - let pattern = "%{+age:int}"; - let output = lex(pattern); - assert_eq!( - output, - Err(DissectError::ParseError( - ParseError::AppendDoesNotSupportTypes("age".into(), 0) - )) - ); - } - - #[test] - fn lex_fails_for_append_with_type_on_append() { - let pattern = "%{age} %{+age:int}"; - let output = Pattern::try_from(pattern); - assert_eq!( - output, - Err(DissectError::ParseError( - ParseError::AppendDoesNotSupportTypes("age".into(), 7) - )) - ) - } - - #[test] - fn lex_fails_for_append_with_type_on_non_append() { - let pattern = "%{age:int} %{+age}"; - - let output = Pattern::try_from(pattern); - assert_eq!( - output, - Err(DissectError::ParseError( - ParseError::AppendDoesNotSupportTypes("age".into(), 11) - )) - ); - } - - - - - - #[test] - fn dissect_empty() { - let output = Pattern::try_from("").expect(""); - let output = output.extract("").expect(""); - assert_eq!(output, Dissect(HashMap::new())); - } - - #[test] - fn multi_pad() { - let pattern = "|%{n}%{_}|"; - let input = "|foo |"; - let pt = Pattern::try_from(pattern).expect("cannot parse pattern"); - - let output = pt.extract(input).expect(""); - let second_op = pt.extract("|foo|").expect(""); - - assert_eq!(output, v(&[("n", "foo")])); - assert_eq!(second_op, v(&[("n", "foo")])); - } - - #[test] - fn extract_with_padding_specific() { - let pattern = "this is a %{what}%{_( case)} named %{name}"; - let input = "this is a test case named cake"; - let output = Pattern::try_from(pattern).expect("cannot parse pattern"); - let output = output.extract(input).expect(""); - - assert_eq!(output, v(&[("what", "test"), ("name", "cake")])); - } - - #[test] - fn do_kv_1() { - let pattern = "this is a %{?name} case named %{&name}"; - let input = "this is a test case named cake"; - let output = Pattern::try_from(pattern).expect("cannot parse pattern"); - let output = output.extract(input).expect(""); - assert_eq!(output, v(&[("test", "cake")])); - } - - #[test] - fn do_repeat_kv_1() { - let pattern = "%{?count}: %{&count:int}, %{?count}: %{&count:int}"; - let input = "tremor: 1, logstash: 0"; - let output = Pattern::try_from(pattern).expect("cannot parse pattern"); - let output = output.extract(input).expect(""); - let mut expected = HashMap::new(); - expected.insert("tremor".into(), SimdValue::from(1)); - expected.insert("logstash".into(), SimdValue::from(0)); - assert_eq!(output, Dissect(expected)); - } - - #[test] - fn parsing_wrong_value_returns_error() { - let pattern = "%{foo:int}"; - let input = "abcdef"; - let p = Pattern::try_from(pattern).expect("cannot parse pattern"); - let output = p.extract(input); - - assert_eq!( - output, - Err(DissectError::RuntimeError( - RuntimeError::CannotParseValueToType("abcdef".to_owned(), SupportedType::Integer), - )), - ); - } - - #[test] - fn consecutive_padding_first_one_optional() { - let pattern = "%{name}%{_}%{_(|)}%{age}"; - let input = "John|22"; - let p = Pattern::try_from(pattern).expect("cannot parse pattern"); - let output = p.extract(input).expect(""); - let mut expected = HashMap::new(); - expected.insert("name".into(), SimdValue::String("John".into())); - expected.insert("age".into(), SimdValue::String("22".into())); - assert_eq!(output, Dissect(expected)); - } - - #[test] - fn empty() { - assert_eq!(lex("").expect("failed to compile pattern"), vec![]); - } - - #[test] - fn parse_errors_happen_at_right_places_with_correct_messages() { - let combinations = [ - ("%{foo", "The { at 0 has no matching }"), - ("%{foo}%{bar}", "No delimiter between tokens at 6"), - ("%{foo}%{_(@}", "Invalid padding (@ at 6"), - ("%{?}", "Invalid token ? at 0"), - ("%{foo:blah}", "Type blah not supported"), - ( - "%{foo}|%{+bar:int}", - "Can't use types with append for field bar", - ), - ]; - - combinations.iter().for_each(|c| match lex(c.0) { - Ok(x) => assert_eq!(x, vec![]), - Err(e) => match e { - DissectError::ParseError(p) => assert_eq!(p.to_string(), c.1), - _ => {} - }, - }); - } - - #[test] - fn runtime_errors_happen_at_right_places_with_correct_messages() { - let combinations = [ - ("%{foo}|", "bar", "Missing delimiter | in the input"), - ("%{&foo}", "John", "named field foo not found"), - ( - "%{foo} ", - "foo bar baz", - "Input not completely parsed starting at 4", - ), - ( - "%{foo} %{bar}", - "foo ", - "Tokens still remaining to be parsed from 2", - ), - ]; - - combinations - .iter() - .for_each(|c| match Pattern::try_from(c.0).expect("").extract(c.1) { - Ok(x) => assert_eq!(x, Dissect(HashMap::new())), - Err(e) => match e { - DissectError::RuntimeError(p) => assert_eq!(p.to_string(), c.2), - _ => {} - }, - }); - } - - #[test] - fn extract() { - let output = lex("%{test}").expect("failed to compile pattern"); - - assert_eq!(output, vec![p("test")]); - } - - #[test] - fn type_float() { - let p = "%{f:float}"; - let mut m = HashMap::new(); - m.insert("f".into(), SimdValue::from(1.0)); - - let pattern = Pattern::try_from(p).expect("can parse token"); - assert_eq!( - pattern, - Pattern { - tokens: vec![Token::Field(Field { - value: "f".into(), - category: Some(FieldCategory::Typed(SupportedType::Float)) - })] - } - ); - - assert_eq!( - Pattern::try_from(p).expect("").extract("1.0"), - Ok(Dissect(m.clone())) - ); - assert_eq!(Pattern::try_from(p).expect("").extract("1"), Ok(Dissect(m))); - assert_eq!( - Pattern::try_from(p).expect("").extract("one"), - Err(DissectError::RuntimeError( - RuntimeError::CannotParseValueToType("one".into(), SupportedType::Float) - )) - ); - } - - #[test] - fn type_int() { - let p = "%{i: int}"; - let mut m = HashMap::new(); - m.insert("i".into(), SimdValue::from(1)); - - let i = lex(p).expect(""); - assert_eq!( - i, - vec![Token::Field(Field { - value: "i".into(), - category: Some(FieldCategory::Typed(SupportedType::Integer)) - })] - ); - - assert_eq!( - Pattern::try_from(p).expect("").extract("1.0"), - Err(DissectError::RuntimeError( - RuntimeError::CannotParseValueToType("1.0".into(), SupportedType::Integer) - )) - ); - assert_eq!(Pattern::try_from(p).expect("").extract("1"), Ok(Dissect(m))); - assert_eq!( - Pattern::try_from(p).expect("").extract("one"), - Err(DissectError::RuntimeError( - RuntimeError::CannotParseValueToType("one".into(), SupportedType::Integer) - )) - ); - } - - #[test] - fn type_bad_type() { - assert_eq!( - lex("ints is not a type %{test:ints}"), - Err(DissectError::ParseError(ParseError::TypeNotSupported( - "ints".into() - ))) - ); - } - #[test] - fn prefix() { - assert_eq!( - lex("this is %{test}").expect("failed to compile pattern"), - vec![d("this is "), p("test")] - ); - } - - #[test] - fn suffix() { - assert_eq!( - lex("%{test} case").expect("failed to compile pattern"), - vec![p("test"), d(" case")] - ); - } - - #[test] - fn encircled() { - assert_eq!( - lex("this is %{test} case").expect("failed to compile pattern"), - vec![d("this is "), p("test"), d(" case")] - ); - } - - #[test] - fn two_patterns() { - assert_eq!( - lex("this is %{test} case named %{name}").expect("failed to compile pattern"), - vec![d("this is "), p("test"), d(" case named "), p("name")] - ); - } - - #[test] - fn two_ignore() { - assert_eq!( - lex("this is %{test} case named %{?name}").expect("failed to compile pattern"), - vec![ - d("this is "), - p("test"), - d(" case named "), - Token::Field(Field { - value: "name".into(), - category: Some(FieldCategory::Skipped) - }) - ] - ); - } - - #[test] - fn open_extract() { - assert_eq!( - lex("%{test"), - Err(DissectError::ParseError(ParseError::MissingClosingBracket( - 0 - ))) - ); - } - - #[test] - fn open_middle() { - assert_eq!( - lex("%{test %{case}"), - Err(DissectError::ParseError(ParseError::MissingClosingBracket( - 0 - ))) - ); - } - - #[test] - fn extract_inside() { - assert_eq!( - lex("this is %{test case"), - Err(DissectError::ParseError(ParseError::MissingClosingBracket( - 8 - ))) - ); - } - - #[test] - fn connected_extract() { - assert_eq!( - lex("%{test}%{pattern}"), - Err(DissectError::ParseError(ParseError::NoDelimiter(7))) - ); - } - - #[test] - fn do_extract1() { - let p = "this is a %{name} case"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("test".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this is a test case") - .expect(""), - Dissect(m) - ); - } - - #[test] - fn do_extract2() { - let p = "this is a %{what} case named %{name}"; - let mut m = HashMap::new(); - m.insert("what".into(), SimdValue::String("test".into())); - m.insert("name".into(), SimdValue::String("cake".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this is a test case named cake") - .expect(""), - Dissect(m) - ); - } - - #[test] - fn do_extract_with_padding() { - let p = "this is a %{what}%{_}case named %{name}"; - let mut m = HashMap::new(); - m.insert("what".into(), SimdValue::String("test".into())); - m.insert("name".into(), SimdValue::String("cake".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this is a test case named cake") - .expect(""), - Dissect(m) - ); - } - - #[test] - fn two_pads() { - let p = "%{_}this%{_}%{_(-)}works"; - let m = HashMap::new(); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this -----works") - .expect(""), - Dissect(m) - ) - } - - #[test] - fn middle_pads_w_delim() { - let p = "|%{n}%{_}|"; - let mut m = HashMap::new(); - m.insert("n".into(), SimdValue::String("Jim".into())); - assert_eq!( - Pattern::try_from(p).expect("").extract("|Jim |").expect(""), - Dissect(m) - ); - let mut m = HashMap::new(); - m.insert("n".into(), SimdValue::String("John".into()).into()); - assert_eq!( - Pattern::try_from(p).expect("").extract("|John|").expect(""), - Dissect(m) - ); - } - - #[test] - fn middle_pads() { - let p = "%{a}%{_}%{b}"; - let mut m = HashMap::new(); - m.insert("a".into(), SimdValue::String("this".into())); - m.insert("b".into(), SimdValue::String("works".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this works") - .expect(""), - Dissect(m) - ) - } - - #[test] - fn left_pads() { - let p = "%{_}%{b}"; - let mut m = HashMap::new(); - m.insert("b".into(), SimdValue::String("works".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract(" works") - .expect(""), - Dissect(m) - ); - } - - #[test] - fn right_pads() { - let p = "%{a}%{_}"; - let mut m = HashMap::new(); - m.insert("a".into(), SimdValue::String("this".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this ") - .expect(""), - Dissect(m) - ); - } - - #[test] - fn right_pads_last_opt() { - let p = "%{a}%{_}"; - let mut m = HashMap::new(); - m.insert("a".into(), SimdValue::String("this".into())); - let m = Dissect(m); - assert_eq!( - &Pattern::try_from(p).expect("").extract("this").expect(""), - &m - ); - assert_eq!( - &Pattern::try_from(p).expect("").extract("this ").expect(""), - &m - ); - assert_eq!( - &Pattern::try_from(p) - .expect("") - .extract("this ") - .expect(""), - &m - ); - } - - #[test] - fn right_pads_last() { - let p = "%{a}%{_}"; - let mut m = HashMap::new(); - m.insert("a".into(), SimdValue::String("this".into())); - let p = Pattern::try_from(p).expect(""); - assert_eq!(p.extract("this ").expect(""), Dissect(m.clone())); - assert_eq!(p.extract("this ").expect(""), Dissect(m)); - } - #[test] - fn do_extract_with_padding_specific() { - let p = "this is a %{what}%{_( case)} named %{name}"; - let mut m = HashMap::new(); - m.insert("what".into(), SimdValue::String("test".into())); - m.insert("name".into(), SimdValue::String("cake".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this is a test case named cake") - .expect(""), - Dissect(m) - ) - } - - #[test] - fn do_extract_ignore() { - let p = "this is a %{?what} case named %{name}"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("cake".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this is a test case named cake") - .expect(""), - Dissect(m) - ); - } - - #[test] - fn do_kv() { - let p = "this is a %{?name} case named %{&name}"; - let mut m = HashMap::new(); - m.insert("test".into(), SimdValue::String("cake".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this is a test case named cake") - .expect(""), - Dissect(m) - ) - } - - #[test] - fn do_repeat_kv() { - let p = "%{?count}: %{&count:int}, %{?count}: %{&count:int}"; - let mut m = HashMap::new(); - m.insert("logstash".into(), SimdValue::from(0)); - m.insert("tremor".into(), SimdValue::from(1)); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("tremor: 1, logstash: 0") - .expect(""), - Dissect(m) - ) - } - - /* - #[test] - fn do_arr() { - let p = "this is a %{^arr} case named %{^arr}"); - let mut m = HashMap::new(); - m.insert( - "arr".into(), - Value::Array(vec![Value::String("test"), SimdValue::String("cake")]), - ); - assert_eq!(p.run("this is a test case named cake"), Dissect(m)) - } - - #[test] - fn do_arr_upgrade() { - let p = lex("this is a %{arr} case named %{^arr}").expect("failed to compile pattern"); - let mut m = HashMap::new(); - m.insert( - "arr".into(), - Value::Array(vec![Value::String("test"), SimdValue::String("cake")]), - ); - assert_eq!(p.run("this is a test case named cake"), Dissect(m)) - } - */ - - #[test] - fn do_str() { - let p = "this is a %{arr} %{+arr}"; - let mut m = HashMap::new(); - m.insert("arr".into(), SimdValue::String("test cake".into())); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("this is a test cake") - .expect(""), - Dissect(m) - ); - } - - #[test] - fn do_str_error1() { - let p = "this is a %{arr} %{+arr:int}"; - assert_eq!( - lex(p), - Err(DissectError::ParseError( - ParseError::AppendDoesNotSupportTypes("arr".into(), 17) - )) - ); - } - - #[test] - fn do_str_error2() { - let p = Pattern::try_from("this is a %{arr:int} %{+arr}"); - - assert_eq!( - p, - Err(DissectError::ParseError( - ParseError::AppendDoesNotSupportTypes("arr".into(), 21) - )) - ); - } - - #[test] - fn do_str_ts() { - let p = "%{}>%{+syslog_timestamp} %{+syslog_timestamp} %{+syslog_timestamp} %{syslog_hostname} %{syslog_program}: %{full_message}"; - let mut m = HashMap::new(); - m.insert( - "syslog_timestamp".into(), - SimdValue::String("2019-04-26 14:34 UTC+1".into()), - ); - m.insert( - "syslog_hostname".into(), - SimdValue::String("tremor.local".into()), - ); - m.insert("syslog_program".into(), SimdValue::String("tremor".into())); - m.insert( - "full_message".into(), - SimdValue::String("can do concat!".into()), - ); - assert_eq!( - Pattern::try_from(p) - .expect("") - .extract("INFO>2019-04-26 14:34 UTC+1 tremor.local tremor: can do concat!") - .expect(""), - Dissect(m) - ) - } - - #[test] - fn dissect_multiple_padding_in_the_middle() { - let p = "%{name}%{_}%{_(|)}%{age}"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("John".into())); - m.insert("age".into(), SimdValue::String("22".into())); - let input = "John ||22"; - assert_eq!( - Pattern::try_from(p).expect("").extract(input).expect(""), - Dissect(m) - ) - } - - #[test] - fn dissect_multiple_padding_in_the_middle_and_delim_err() { - let p = "%{name}%{_}%{_(|)}/ %{age}"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("John".into())); - m.insert("age".into(), SimdValue::String("22".into())); - let input = "John |/ 22"; - assert_eq!( - Pattern::try_from(p).expect("").extract(input).expect(""), - Dissect(m) - ); - } - - #[test] - fn dissect_multiple_padding_in_the_middle_and_delim_ok() { - let p = "%{name}%{_}%{_(|)}/%{age}"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("John".into())); - m.insert("age".into(), SimdValue::String("22".into())); - let input = "John/22"; - assert_eq!( - Pattern::try_from(p).expect("").extract(input).expect(""), - Dissect(m) - ); - } - - #[test] - fn dissect_multiple_padding_in_the_middle_and_delim_2() { - let p = "%{name}%{_}%{_(|)}/%{age}"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("John".into())); - m.insert("age".into(), SimdValue::String("22".into())); - let input = "John /22"; - assert_eq!( - Pattern::try_from(p).expect("").extract(input).expect(""), - Dissect(m) - ) - } - - #[test] - fn dissect_multiple_padding_in_the_middle_and_delim_3() { - let p = "%{name}%{_}%{_(|)}/%{age}"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("John".into())); - m.insert("age".into(), SimdValue::String("22".into())); - let input = "John|/22"; - assert_eq!( - Pattern::try_from(p).expect("").extract(input).expect(""), - Dissect(m) - ) - } - - #[test] - fn dissect_multiple_padding_in_the_middle_and_delim_4() { - let p = "%{name}%{_}%{_(|)}/%{age}"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("John".into())); - m.insert("age".into(), SimdValue::String("22".into())); - let input = "John |/22"; - assert_eq!( - Pattern::try_from(p).expect("").extract(input).expect(""), - Dissect(m) - ) - } - - #[test] - fn dissect_multiple_padding_in_the_middle_first_not_found() { - let p = "%{name}%{_}%{_(|)}%{age}"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("John".into())); - m.insert("age".into(), SimdValue::String("22".into())); - let input = "John||22"; - assert_eq!( - Pattern::try_from(p).expect("").extract(input).expect(""), - Dissect(m) - ); - } - - #[test] - fn dissect_multiple_padding_in_the_middle_last_not_found() { - let p = "%{name}%{_}%{_(|)}%{age}"; - let mut m = HashMap::new(); - m.insert("name".into(), SimdValue::String("John".into())); - m.insert("age".into(), SimdValue::String("22".into())); - let input = "John 22"; - assert_eq!( - Pattern::try_from(p).expect("").extract(input).expect(""), - Dissect(m) - ); - } - - #[test] - fn weblog() { - let pattern = r#"%{syslog_timestamp} %{syslog_hostname} %{?syslog_prog}: %{syslog_program_aux}[%{syslog_pid:int}] %{request_unix_time} %{request_timestamp} %{request_elapsed_time} %{server_addr}:%{server_port:int} %{remote_addr}:%{remote_port:int} "%{response_content_type}" %{response_content_length} %{request_status} %{bytes_sent} %{request_length} "%{url_scheme}" "%{http_host}" "%{request_method} %{request_url} %{request_protocol}" "%{http_referer}" "%{http_user_agent}" "%{http_x_forwarded_for}" "%{http_ttrue_client_ip}" "%{remote_user}" "%{is_bot}" "%{admin_user}" "%{http_via}" "%{response_location}" "%{set_cookie}" "%{http_cookie}" "%{moawsl_info}" "%{php_message}" "%{akamai_edgescape}" "%{uid_info}" "%{geoip_country}" "%{geoip_region}" "%{geoip_city}" "%{geoip_postal}" "%{geoip_dma}" "%{server_id}" "%{txid}" "%{hpcnt}" "%{client_accept}" "%{client_accept_charset}" "%{client_accept_encoding}" "%{client_accept_language}" "%{client_accept_datetime}" "%{client_pragma}" "%{client_transfer_encoding}" "%{client_attdeviceid}" "%{client_wap_profile}" %{weblog_end}"#; - let p = lex("%{name}%{_}%{_(|)}%{age}"); - assert!(lex(pattern).is_ok()); - assert!(p.is_ok()); - } - - #[test] - fn test_patterns() { - let patterns = vec![ - ( - "%{syslog_timestamp} %{wf_host} %{syslog_program}: %{syslog_message}%{_}", - "12345 host program: message ", - v(&([ - ("syslog_timestamp", "12345"), - ("wf_host", "host"), - ("syslog_program", "program"), - ("syslog_message", "message"), - ])), - ), - ( "%{syslog_timestamp} %{wf_host} %{syslog_program}: %{syslog_message}", - "12345 host program: message", - v(&([ - ("syslog_timestamp", "12345"), - ("wf_host", "host"), - ("syslog_program", "program"), - ("syslog_message", "message"), - ])), - ), - ( - "%{}, [%{log_timestamp} #%{pid}] %{log_level} -- %{}: %{message}", - "foo, [12345 #12] high -- 1: log failed", - v(&([ - ("log_timestamp", "12345"), - ("pid", "12"), - ("log_level", "high"), - ("message", "log failed"), - ])), - ), - - ( - "%{}>%{+syslog_timestamp} %{+syslog_timestamp} %{+syslog_timestamp} %{syslog_hostname} %{syslog_program}: %{full_message}", - "foo>12345 67890 12345 host program: log failed", - v(&([ - ("syslog_timestamp", "12345 67890 12345"), - ("syslog_hostname", "host"), - ("syslog_program", "program"), - ("full_message", "log failed") - ])) - ), - - ( - - "%{syslog_timestamp} %{wf_host} %{}: %{log_timestamp} %{+log_timestamp} %{+log_timestamp} %{+log_timestamp} %{+log_timestamp} %{job_name} %{build_num} %{message} completed: %{completed}\n", - "12345 host foo: 12345 67890 12345 67890 12345 some_job 12345 some_message completed: 100\n", - v(&([ - ("syslog_timestamp", "12345"), - ("wf_host", "host"), - ("log_timestamp", "12345 67890 12345 67890 12345"), - ("job_name", "some_job"), - ("build_num", "12345"), - ("message", "some_message"), - ("completed", "100"), - ])), - ), - - ( - - "%{syslog_timestamp} %{wf_host} %{}: %{log_timestamp} %{+log_timestamp} %{+log_timestamp} %{+log_timestamp} %{+log_timestamp} %{job_name} %{build_num} %{message}\n", - "12345 host foo: 12345 67890 12345 67890 12345 nice_job 900 here we go again\n", - v(&([ - ("syslog_timestamp", "12345"), - ("wf_host", "host"), - ("log_timestamp", "12345 67890 12345 67890 12345"), - ("job_name", "nice_job"), - ("build_num", "900"), - ("message", "here we go again") - ])) - ), - - ( - "%{syslog_timestamp} %{wf_host} %{} %{log_timestamp} %{log_level} %{main} %{logger}%{_}%{message}%{_}", - "12345 host foo 12345 high main dummy_logger some_message ", - v(&[ - ("syslog_timestamp", "12345"), - ("wf_host", "host"), - ("log_timestamp", "12345"), - ("log_level", "high"), - ("main", "main"), - ("logger", "dummy_logger"), - ("message", "some_message") - ]) - ), - - - ( - - "%{syslog_timestamp} %{host} %{?kafka_tag} %{log_timestamp}: %{log_level} (%{logger}): %{full_message}", - "12345 foo some_tag 12345: high (dummy): welcome", - v(&[ - ("syslog_timestamp", "12345"), - ("host", "foo"), - ("log_timestamp", "12345"), - ("log_level", "high"), - ("logger", "dummy"), - ("full_message", "welcome") - ]) - ), - - ( - "%{syslog_timestamp} %{host} %{} %{message}", - "12345 foo bar here we go", - v(&[ - ("syslog_timestamp", "12345"), - ("host", "foo"), - ("message", "here we go") - ]) - ), - - ( - - - "%{syslog_timestamp} %{host} %{log_timestamp} %{+log_timestamp} %{message}", - "12345 foo 12345 67890 this works well", - v(&[ - ("syslog_timestamp", "12345"), - ("host", "foo"), - ("log_timestamp", "12345 67890"), - ("message", "this works well") - ]) - - ), - - ( - "%{syslog_timestamp} %{host}%{_}[%{log_timestamp}][%{log_level}%{_}][%{logger}%{_}] %{message}", - "12345 foo [12345 67890][high ][dummy ] too many brackets here", - v(&[ - ("syslog_timestamp", "12345"), - ("host", "foo"), - ("log_timestamp", "12345 67890"), - ("log_level", "high"), - ("logger", "dummy"), - ("message", "too many brackets here") - ]) - ), - - ( - "%{syslog_timestamp} %{host} %{} %{} %{} %{} %{syslog_program}[%{syslog_pid}]: %{message}", - "12345 foo i dont care about program[12345]: some message here", - v(&[ - ("syslog_timestamp", "12345"), - ("host", "foo"), - ("syslog_program", "program"), - ("syslog_pid", "12345"), - ("message", "some message here") - ]) - - - ), - ( - - "%{syslog_timestamp} %{host}%{_}[%{log_timestamp}][%{log_level}%{_}][%{logger}%{_}] %{message}", - "12345 foo [12345][high ][dummy ] alexanderplatz", - v(&[ - ("syslog_timestamp", "12345"), - ("host", "foo"), - ("log_timestamp", "12345"), - ("log_level", "high"), - ("logger", "dummy"), - ("message", "alexanderplatz") - ]) - - ), - - ( - "%{} %{} %{} %{source} %{}:%{message}", - "foo bar baz light quox:this was fun", - v(&[ - ("source", "light"), - ("message", "this was fun") - ]) - ), - - ( - - "%{syslog_timestamp} %{wf_host}%{_}%{}: %{syslog_message}", - "12345 host foo: lorem ipsum", - v(&[ - ("syslog_timestamp", "12345"), - ("wf_host", "host"), - ("syslog_message", "lorem ipsum") - ]) - - ), - - ( - - "%{syslog_timestamp} %{host}%{_}%{}: %{syslog_message}", - "12345 ghost foo: this is the last one", - v(&[ - ("syslog_timestamp", "12345"), - ("host", "ghost"), - ("syslog_message", "this is the last one") - ]) - - ), - - ( - "this is a %{?what} named %{name}", - "this is a test named cake", - v(&[("name", "cake")]) - ) - - ]; - - patterns.iter().for_each(|(pattern, input, expected)| { - let p = Pattern::try_from(pattern).expect(""); - - let output = p.extract(input).expect(""); - assert_eq!(output, *expected); - }); - } + assert_pattern!( + "this is a %{what} case named %{name}", + "this is a test case named cake", + ("what", "test"), + ("name", "cake") + ) } - - -*/