ajson 0.3.1

JSON Parser for Rust - Get JSON values quickly
Documentation
mod builder;
mod parser;

mod query;
mod sub_selector;

use std::fmt;

use builder::Builder;
pub use sub_selector::SubSelector;

use self::query::{Query, DEFAULT_NONE_QUERY};
#[cfg(feature = "wild")]
use crate::wild;
use crate::{unescape, util, Result};

pub const DEFAULT_NONE_PATH: Path = Path {
    ok: false,
    part: &[],
    next: &[],
    more: false,
    #[cfg(feature = "wild")]
    wild: false,
    arrch: false,

    query:     None,
    selectors: None,
    arrsel:    false,
    esc:       false,
};

#[derive(Default)]
pub struct Path<'a> {
    pub ok:        bool,
    pub part:      &'a [u8],
    pub next:      &'a [u8],
    pub query:     Option<Query<'a>>,
    pub selectors: Option<Vec<SubSelector<'a>>>,
    pub arrsel:    bool,
    pub more:      bool,
    #[cfg(feature = "wild")]
    pub wild:      bool,
    pub arrch:     bool,
    pub esc:       bool,
}

impl<'a> fmt::Debug for Path<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<Path")?;
        write!(f, " ok={}", self.ok)?;
        write!(f, " part=`{:?}`", unsafe {
            std::str::from_utf8_unchecked(self.part)
        })?;

        write!(f, " more={}", self.more)?;
        #[cfg(feature = "wild")]
        write!(f, " wild={}", self.wild)?;
        write!(f, " arrch={}", self.arrch)?;

        if self.selectors.is_some() {
            for sel in self.borrow_selectors() {
                write!(f, "\n\tselector {:?}", sel)?;
            }
        }
        if self.has_query() {
            write!(f, " query={:?}", self.query)?;
        }
        write!(f, ">")
    }
}

impl<'a> Path<'a> {
    pub fn from_slice(v: &'a [u8]) -> Result<Path<'a>> {
        parser::parse(v)
    }

    pub fn builder<'b>() -> Builder<'b> {
        Default::default()
    }

    pub fn is_match(&self, key: &[u8], key_esc: bool) -> bool {
        #[cfg(feature = "wild")]
        if self.wild {
            return wild::is_match_u8(key, self.part);
            return false;
        }

        if key_esc {
            let s = unescape(key);
            s.as_bytes().eq(self.part)
        } else if self.esc {
            util::equal_escape_u8(key, self.part)
        } else {
            key.eq(self.part)
        }
    }

    pub fn parse_next(&self) -> Result<Path<'a>> {
        if self.next.is_empty() {
            Ok(Path::default())
        } else {
            Path::from_slice(self.next)
        }
    }

    pub fn has_query(&self) -> bool {
        self.query.is_some()
    }

    pub fn borrow_query(&self) -> &Query<'a> {
        match self.query {
            Some(_) => self.query.as_ref().unwrap(),
            None => &DEFAULT_NONE_QUERY,
        }
    }

    pub fn has_selectors(&self) -> bool {
        self.selectors.is_some()
    }

    pub fn borrow_selectors(&self) -> &[SubSelector<'a>] {
        match self.selectors {
            Some(_) => self.selectors.as_ref().unwrap(),
            None => &[],
        }
    }
}