-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support serde::Serialize
and serde::Deserialize
for the engine
#624
Comments
Tagging @V0ldek for notifications |
Do you mean serializing and deserializing the So the
So to serialize one would serialize only the Support for serialization must be behind a new I'd expect some basic proptests to make sure serialization round-trips. Could you tell me what format you're planning on serializing into? |
One more thing is versioning – we don't expect the |
We use engine like this: we convert paths from let paths: Vec<String> = vec![
"$.personal.details.contact.information.phones.home".to_string(),
"$.personal.details.contact.information.phones.office".to_string(),
];
let engines: Vec<RsonpathEngine> = paths
.iter()
.map(|path| {
let a = Automaton::new(&rsonpath_syntax::parse(path).unwrap()).unwrap();
RsonpathEngine::from_compiled_query(a)
})
.collect(); And I thought it would be a good idea. Deserialize engine from jsonpath, and serialize to path. But maybe I'm missing something. And this view is one narrow use case among many. Then good way will be provide API just about jsonpathquery ( |
I see. The engine doesn't preserve the underlying query, so you'd need to hold it alongside. The main reason to make the engine serialize/deserialize would be to save on compilation time. Parsing and compiling an engine is relatively fast, but I'm pretty sure deserializing it from a binary format would be much faster, so it's something that might be worth supporting. For example, a quick microbenchmark tells me cloning an engine with your query is ~10x faster than recompiling it. Deserialization from a binary payload would presumably be closer to a In any case, a parsed let query_str_1 = "$.personal.details.contact.information.phones.home";
let query_1 = rsonpath_syntax::parse(query_str_1).unwrap();
let automaton_1 = Automaton::new(&query_1).unwrap();
let query_str_2 = query_1.to_string();
let query_2 = rsonpath_syntax::parse(&query_str_2).unwrap();
let automaton_2 = Automaton::new(&query_2).unwrap();
assert_eq!(query_1, query_2);
assert_eq!(automaton_1, automaton_2); Just note that the string representation is not preserved as we convert to a canonical representation, so: println!("{query_str_2}"); prints $['personal']['details']['contact']['information']['phones']['home'] |
I realize in your code: impl MainEngine {
pub fn get_jsonpath_strings(&self) -> Vec<String> {
self.automaton.get_jsonpath_strings()
}
} automation.rs impl Automation {
#[must_use]
#[inline(always)]
pub fn get_jsonpath_strings(&self) -> Vec<String> {
self.states
.iter()
.flat_map(|state| state.member_transitions.iter().map(|(pattern, _)| pattern.unquoted()))
.map(|pattern| std::str::from_utf8(pattern).unwrap().to_string())
.collect()
}
} I am satisfied with this result: let paths = vec![
"$.personal.details.contact.information.phones.home".to_string(),
"$.personal.details.contact.information.phones.office".to_string(),
];
let engines: Vec<RsonpathEngine> = paths
.iter()
.map(|path| {
let a = Automaton::new(&rsonpath_syntax::parse(path).unwrap()).unwrap();
RsonpathEngine::from_compiled_query(a)
})
.collect();
let s = engines.get(0).unwrap().get_jsonpath_strings();
println!("{:?}", s)
Is possible to add API like this? |
I don't like it, it's not obvious what this function would do for more complex queries. Does
Is the semantics literally "return the labels from left to right as in the query"? That sounds like a syntactic property, and the For syntactic properties you have the use rsonpath_syntax::prelude::*;
let paths = vec![
"$.personal.details.contact.information.phones.home".to_string(),
"$.personal.details.contact.information.phones.office".to_string(),
];
let engines: Vec<(JsonPathQuery, RsonpathEngine)> = paths
.iter()
.map(|path| {
let q = rsonpath_syntax::parse(path).unwrap();
let e = RsonpathEngine::compile_query(&q).unwrap();
(q, e)
})
.collect();
let s: Vec<&str> = engines[0]
.0
.segments()
.iter()
.filter_map(|s| match s {
Segment::Child(ss) => match ss.first() {
Selector::Name(str) => Some(str.unquoted()),
_ => None,
},
_ => None,
})
.collect();
println!("{:?}", s);
If something like this is useful we could add it to the |
Or may be rename to |
Okay, so continuing the discussion on serialization/deserialization, I can implement it easily. If you could please tell me what target format will you plan to use so that I can add snapshot tests specifically for that it'd be nice. |
Let me tell you how we use it. All we need is from jsonpathquery compile and match incoming json. We store jsonpath as parameter config yaml jsonpath:
- $.phones.home
- $.phones.office And then we check incoming JSON if is matched or not. Thats why I need to serialize/deserialize to something that looks like jsonpath. Thats why I use unqoted_segment: I can manually |
I think you can implement serialize / deserialize as you see fit. For my tasks i wrote wrapper around Engine and store original jsonpathquery in the string =) |
serde::Serialize
and serde::Deserialize
for the engine
Implemented `serde::Serialize` and `serde::Deserialize` for `MainEngine` in rsonpath-lib, and `JsonPathQuery` in rsonpath-syntax with all of its constituent substructs. The `serde` dependency is guarded behind an optional feature. To properly proptest this feature `rsonpath-lib` needs access to the arbitrary query generation from `rsonpath-syntax`. The cleanest way to do this is to extract the logic to a separate crate, giving rise to `rsonpath-syntax-proptest`. The serialization format is not stable, as the `Automaton` is expected to evolve. Thus, serialization includes a version and deserialization will fail if the version disagrees. Ref: #624
Added snapshot tests based on `insta` to both the rsonpath-syntax and rsonpath-lib serialization features. Ref: #624
This was released in 0.9.4. |
Is it possible to implement traits Serialization and Deserialization?
If it difficult may be provide API to inner jsonpath query that stored in MainEngine?
The text was updated successfully, but these errors were encountered: