1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use std::error::Error;

use crate::json_path::{JSONPath, JSONPathError};

/// The context to run the evaluation, you can have an empty context with
/// `PredicateContext::default()`.
#[derive(Default, Clone, Debug)]
pub struct PredicateContext {
    location: Option<JSONPath>,
}

#[derive(Debug, thiserror::Error)]
pub enum PredicateContextError {
    #[error("{0}")]
    Deserialize(#[from] Box<dyn Error>),
    #[error("{0}")]
    JSONPath(#[from] JSONPathError),
}

impl From<JSONPath> for PredicateContext {
    fn from(value: JSONPath) -> Self {
        Self {
            location: Some(value),
        }
    }
}

impl From<Option<JSONPath>> for PredicateContext {
    fn from(value: Option<JSONPath>) -> Self {
        Self { location: value }
    }
}

impl PredicateContext {
    pub fn new(path: String) -> Result<Self, PredicateContextError> {
        let location = JSONPath::new(path)?;

        Ok(Self {
            location: Some(location),
        })
    }

    pub fn final_path(&self, path: &Option<JSONPath>) -> Option<JSONPath> {
        // TODO: Remove cloning
        match (self.location.clone(), path.clone()) {
            (None, None) => None,
            (Some(path), None) | (None, Some(path)) => Some(path),
            (Some(root), Some(path)) => Some(root + path),
        }
    }
}