serde_select/
read.rs

1use serde::{Deserialize, Serialize};
2use std::convert::TryInto;
3
4use crate::error::*;
5use crate::tokenizer::tokenize_with_seperator;
6use crate::object::*;
7use crate::tokenizer::Token;
8use crate::query::Query;
9
10pub trait Read<'doc> : Object<'doc> + Sized {
11    fn read(&'doc self, query: &Query) -> Result<Option<&'doc Self>> {
12        query_with_token(self, query.token())
13    }
14}
15
16#[cfg(feature = "backend_toml")]
17impl<'doc> Read<'doc> for toml::Value { }
18
19#[cfg(feature = "backend_serde_json")]
20impl<'doc> Read<'doc> for serde_json::Value { }
21
22fn query_with_token<'doc, O>(obj: &'doc O, token: &Token) -> Result<Option<&'doc O>>
23    where O: Object<'doc>
24{
25    match token {
26        Token::Identifier{ ident, .. } => {
27            let object = obj.at_key(ident)?;
28            if let Some(object) = object {
29                if let Some(next_token) = token.next() {
30                    query_with_token(object, next_token)
31                } else {
32                    Ok(Some(object))
33                }
34            } else {
35                Ok(None)
36            }
37        }
38
39        Token::Index { idx, .. } => {
40            let object = obj.at_index(*idx)?;
41            if let Some(object) = object {
42                if let Some(next_token) = token.next() {
43                    query_with_token(object, next_token)
44                } else {
45                    Ok(Some(object))
46                }
47            } else {
48                Ok(None)
49            }
50        }
51    }
52}
53