// Copyright (C) 2021-2022 Soni L. // SPDX-License-Identifier: MIT OR Apache-2.0 use serde_json::Deserializer as JsonDer; use serde::Deserialize; //use datafu::Predicate; #[test] fn test_basic() { let mut der = JsonDer::from_str(r#"{"foo": 1, "bar": {"baz": 2}}"#); let pat = datafu::PatternBuilder::for_pattern("->[x]:?map->[yk]y").compile().unwrap(); #[derive(Deserialize)] struct Values { x: String, yk: String, y: usize, } let matches: Values = pat.deserialize(&mut der).unwrap().collect().unwrap(); assert_eq!(matches.x, "bar"); assert_eq!(matches.yk, "baz"); assert_eq!(matches.y, 2); assert!(der.end().is_ok()); } #[test] fn test_real_use_case() { let pat = datafu::PatternBuilder::for_pattern( " :map ->['projects'?]:map ->[commit:?str]:?map ->[url:?str]:?map ->[branch:?str]:?map (->['active'?]active:?bool)? (->['federate'?]?federate:?bool)? (->['pinned'?]?pinned:?bool)? " ).compile().unwrap(); let data = r#" {"base_url": "https://ganarchy.autistic.space", "repo_list_srcs": {"https://ganarchy.autistic.space/index.toml": {"active": false}}, "projects": {"385e734a52e13949a7a5c71827f6de920dbfea43": {"https://github.com/ganarchy/GAnarchy": {"HEAD": {"active": true}}, "https://soniex2.autistic.space/git-repos/ganarchy.git": {"HEAD": {"active": true, "pinned": true}}}, "a8fb5087f79eafe312db270082c052c427b208c2": {"https://soniex2.autistic.space/git-repos/mmorfc.git": {"HEAD": {"active": true, "pinned": true}}}, "2d0b363fe3179087de59d9ef4a2d14af21d89071": {"https://soniex2.autistic.space/git-repos/chewstuff.git": {"HEAD": {"active": true, "pinned": true}}}}} "#; let mut der = JsonDer::from_str(data); #[derive(Deserialize)] struct Values { commit: String, url: String, branch: String, active: bool, #[serde(default)] federate: bool, #[serde(default)] pinned: bool, } let graph = pat.deserialize(&mut der).unwrap(); let matches: Vec = graph.collect().unwrap(); assert!(der.end().is_ok()); } //#[test] //fn test_str() { // //let tree = Value::M(vec![ // // ("foo".into(), Value::U(1)), // // ("bar".into(), Value::M(vec![ // // ("baz".into(), Value::U(2)), // // ].into_iter().collect())), // //].into_iter().collect()); // let der = JsonDer::from_str(r#"{"foo": 1, "bar": {"baz": 2}}"#) // let preds = vec![("dict", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::M(_)))) as Box>)].into_iter().collect(); // let pat = datafu::Pattern::::compile::<&str, &str>("->X'bar'->Y", Some(preds), None).unwrap(); // let mut matcher = pat.attempt_match(&tree); // let m = matcher.next().unwrap().unwrap(); // assert_eq!(m["X"].0, RefOwn::Ref(&Value::from("bar"))); // assert_eq!(m["Y"].0, RefOwn::Ref(&Value::from("baz"))); // assert_eq!(m["Y"].1, RefOwn::Ref(&Value::U(2))); // assert!(matcher.next().is_none()); //} // //#[test] //fn test_basic_2() { // let tree = Value::M(vec![ // ("projects".into(), Value::M(vec![ // ("385e734a52e13949a7a5c71827f6de920dbfea43".into(), Value::M(vec![ // ("https://soniex2.autistic.space/git-repos/ganarchy.git".into(), Value::M(vec![ // ("HEAD".into(), Value::M(vec![ // ("active".into(), Value::B(true)), // ].into_iter().collect())), // ].into_iter().collect())), // ].into_iter().collect())), // ].into_iter().collect())), // ].into_iter().collect()); // let preds = vec![("d", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::M(_)))) as Box>)].into_iter().collect(); // let pat = datafu::Pattern::::compile::<&str, &str>("->'projects':?$d->P/[0-9a-fA-F]{40}|[0-9a-fA-F]{64}/?:?$d->U:?$d->B", Some(preds), None).unwrap(); // let mut matcher = pat.attempt_match(&tree); // let m = matcher.next().unwrap().unwrap(); // assert_eq!(m["P"].0, RefOwn::Ref(&Value::from("385e734a52e13949a7a5c71827f6de920dbfea43"))); // assert_eq!(m["U"].0, RefOwn::Ref(&Value::from("https://soniex2.autistic.space/git-repos/ganarchy.git"))); // assert_eq!(m["B"].0, RefOwn::Ref(&Value::from("HEAD"))); // assert_eq!(m["B"].1, RefOwn::Ref(&Value::M(vec![(Value::from("active"), Value::B(true))].into_iter().collect()))); // assert!(matcher.next().is_none()); //} // //#[test] //fn test_spaces() { // let tree = Value::M(vec![ // ("projects".into(), Value::M(vec![ // ("385e734a52e13949a7a5c71827f6de920dbfea43".into(), Value::M(vec![ // ("https://soniex2.autistic.space/git-repos/ganarchy.git".into(), Value::M(vec![ // ("HEAD".into(), Value::M(vec![ // ("active".into(), Value::B(true)), // ].into_iter().collect())), // ].into_iter().collect())), // ].into_iter().collect())), // ].into_iter().collect())), // ].into_iter().collect()); // let preds = vec![("dict", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::M(_)))) as Box>)].into_iter().collect(); // let pat = datafu::Pattern::::compile::<_, &str>(" // -> 'projects'? // -> commit /[0-9a-fA-F]{40}|[0-9a-fA-F]{64}/? :?$dict // -> url :?$dict // -> branch :?$dict", // Some(preds), // None, // ).unwrap(); // let mut matcher = pat.attempt_match(&tree); // let m = matcher.next().unwrap().unwrap(); // assert_eq!(m["commit"].0, RefOwn::Ref(&Value::from("385e734a52e13949a7a5c71827f6de920dbfea43"))); // assert_eq!(m["url"].0, RefOwn::Ref(&Value::from("https://soniex2.autistic.space/git-repos/ganarchy.git"))); // assert_eq!(m["branch"].0, RefOwn::Ref(&Value::from("HEAD"))); // assert_eq!(m["branch"].1, RefOwn::Ref(&Value::M(vec![(Value::from("active"), Value::B(true))].into_iter().collect()))); // assert!(matcher.next().is_none()); //} // //#[test] //fn test_harder() { // let tree = Value::M(vec![ // ("projects".into(), Value::M(vec![ // ("385e734a52e13949a7a5c71827f6de920dbfea43".into(), Value::M(vec![ // ("https://soniex2.autistic.space/git-repos/ganarchy.git".into(), Value::M(vec![ // ("HEAD".into(), Value::M(vec![ // ("active".into(), Value::B(true)), // ].into_iter().collect())), // ].into_iter().collect())), // ].into_iter().collect())), // ].into_iter().collect())), // ].into_iter().collect()); // let preds = vec![ // ("dict", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::M(_)))) as Box>), // ("str", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::S(_)))) as Box>), // ("bool", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::B(_)))) as Box>), // // stubs, we don't particularly need to test these // ("commit", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::S(_)))) as Box>), // ("uri", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::S(_)))) as Box>), // ].into_iter().collect(); // let pat = datafu::Pattern::::compile::<_, &str>(" // ->'projects':$dict // ->commit[:?$str:?$commit]:?$dict // ->url[:?$str:?$uri]:?$dict // ->branch:?$dict // (->active'active'?:?$bool) // (->federate'federate'?:?$bool)?", // Some(preds), // None, // ).unwrap(); // let mut matcher = pat.attempt_match(&tree); // let m = matcher.next().unwrap().unwrap(); // assert_eq!(m["commit"].0, RefOwn::Ref(&Value::from("385e734a52e13949a7a5c71827f6de920dbfea43"))); // assert_eq!(m["url"].0, RefOwn::Ref(&Value::from("https://soniex2.autistic.space/git-repos/ganarchy.git"))); // assert_eq!(m["branch"].0, RefOwn::Ref(&Value::from("HEAD"))); // assert_eq!(m["active"].1, RefOwn::Ref(&Value::B(true))); // assert_eq!(m.get("federate"), None); // assert!(matcher.next().is_none()); //}