json_pop/extra/
source.rs

1pub use self::source::*;
2
3mod source {
4    #[cfg(feature = "pretty_errors")]
5    use crate::extra::codespan;
6    use crate::{error, lex, parser, value};
7
8    use logos::Logos as _;
9
10    #[derive(Debug)]
11    pub struct Source<'a>(&'a str);
12
13    pub trait Parsable<'a> {
14        fn parse(&'a self) -> parser::Parsed<'a>;
15        fn source(&'a self) -> &Source<'a>;
16    }
17
18    impl<'a> Parsable<'a> for Source<'a> {
19        fn parse(&self) -> parser::Parsed {
20            let lexer = lex::Token::lexer(self.0)
21                .spanned()
22                .map(lex::Token::to_lalr_triple);
23            parser::Parsed(parser::jsonParser::new().parse(lexer))
24        }
25
26        fn source(&self) -> &Source<'a> {
27            self
28        }
29    }
30
31    pub trait ErrorHandling<'a> {
32        fn handle_errors(
33            &'a self,
34            parsed: parser::Parsed<'a>,
35        ) -> Result<value::Value<'a>, error::JsonPopError<'a>>;
36    }
37
38    impl<'a> ErrorHandling<'a> for Source<'a> {
39        fn handle_errors(
40            &'a self,
41            parsed: parser::Parsed<'a>,
42        ) -> Result<value::Value<'a>, error::JsonPopError<'a>> {
43            use cfg_if::cfg_if;
44            cfg_if! {
45                if #[cfg(feature = "pretty_errors")] {
46                    codespan::maybe_show_error(self.0, parsed.0)
47                } else {
48                  use std::io::Write;
49                  if parsed.0.is_err() == false {
50                      write!(std::io::stderr(), "{:#?}", self.0)?;
51                  }
52                  Ok(parsed.0?)
53               }
54            }
55        }
56    }
57
58    impl<'a, T: AsRef<str> + 'a> From<&'a T> for Source<'a> {
59        fn from(it: &'a T) -> Source<'a> {
60            Source(it.as_ref())
61        }
62    }
63
64    impl<'a> AsRef<str> for Source<'a> {
65        fn as_ref(&self) -> &str {
66            &self.0
67        }
68    }
69}