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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
use crate::debug_level; use crate::source::CustomDecoder; use crate::token_rewriter::TokenRewriter; /// Configuration of the parser #[derive(Debug)] pub struct ParserOptions { /// Name of the buffer. Used in all diagnostic messages pub buffer_name: String, /// Controls which debug information is printed during parsing /// /// Can be: /// /// + lib_ruby_parser::debug_level::None /// + lib_ruby_parser::debug_level::Parser /// + lib_ruby_parser::debug_level::Lexer /// + lib_ruby_parser::debug_level::Buffer /// + or a combination of them (like `Lexer | Buffer`, these value is just a bitmask) pub debug: debug_level::Type, /// Custom decoder that can be used if the source is encoded /// in unknown encoding. Only UTF-8 and ASCII-8BIT/BINARY are /// supported out of the box. /// /// # Example /// ```rust /// use lib_ruby_parser::source::{CustomDecoder, CustomDecoderResult, InputError}; /// use lib_ruby_parser::{debug_level, Parser, ParserOptions, ParserResult}; /// /// fn decode(encoding: String, input: Vec<u8>) -> CustomDecoderResult { /// if "US-ASCII" == encoding.to_uppercase() { /// // reencode and return Ok(result) /// return CustomDecoderResult::Ok(b"# encoding: us-ascii\ndecoded".to_vec().into()); /// } /// CustomDecoderResult::Err(InputError::DecodingError( /// "only us-ascii is supported".into(), /// )) /// } /// /// let decoder = CustomDecoder::new(Box::new(decode)); /// let options = ParserOptions { /// decoder, /// debug: debug_level::PARSER, /// ..Default::default() /// }; /// let parser = Parser::new(b"# encoding: us-ascii\n3 + 3".to_vec(), options); /// let ParserResult { ast, input, .. } = parser.do_parse(); /// /// assert_eq!( /// ast.unwrap().expression().source(&input).unwrap(), /// "decoded".to_string() /// ) /// ``` pub decoder: CustomDecoder, /// Optional token rewriter, see TokenRewriter API /// /// # Example /// ``` /// use lib_ruby_parser::{ /// nodes::*, /// token_rewriter::*, /// Bytes, BytesTrait, Node, Parser, ParserOptions, ParserResult, Token, TokenTrait, /// }; /// fn rewrite_foo_to_bar(mut token: Box<Token>, input: &[u8]) -> TokenRewriterResult { /// // simply rewrite all tokens "foo" to "bar" /// if token.to_string_lossy() == "foo" { /// token.set_token_value(Bytes::new(b"bar".to_vec())); /// } /// /// // return token + keep it + keep lexer's state /// TokenRewriterResult { /// rewritten_token: token, /// token_action: RewriteAction::Keep, /// lex_state_action: LexStateAction::Keep, /// } /// } /// let token_rewriter = TokenRewriter::new(Box::new(rewrite_foo_to_bar)); /// let options = ParserOptions { /// token_rewriter, /// ..Default::default() /// }; /// let ParserResult { ast, .. } = Parser::new(b"foo = 1".to_vec(), options).do_parse(); /// /// let ast = ast.unwrap(); /// /// let lvar_name = match &*ast { /// Node::Lvasgn(Lvasgn { name, .. }) => name, /// other => panic!("expected lvasgn node, got {:?}", other), /// }; /// assert_eq!(*lvar_name, String::from("bar")); /// ``` pub token_rewriter: TokenRewriter, /// When set to true Parser records tokens. /// When set to false `ParserResult.tokens` is guaranteed to be empty. /// If you don't need tokens better set it to false to speed up parsing. pub record_tokens: bool, } const DEFAULT_BUFFER_NAME: &str = "(eval)"; impl Default for ParserOptions { fn default() -> Self { Self { buffer_name: DEFAULT_BUFFER_NAME.to_string(), debug: debug_level::NONE, decoder: CustomDecoder::none(), token_rewriter: TokenRewriter::none(), record_tokens: true, } } }