thrift_analyzer/analyzer/
macros.rs1#[macro_export]
3macro_rules! parse_header {
4 ($self:ident, $headers:ident, $($kind:ident => $parse_fn:ident),* $(,)?) => {
5 match $self.peek_next_token().kind {
6 $(
7 TokenKind::$kind => {
8 if let Some(node) = $self.$parse_fn() {
9 $headers.push(Rc::new(HeaderNode::$kind(node)));
10 } else {
11 $self.recover_to_next_line();
12 }
13 }
14 )*
15 _ => break,
16 }
17 };
18}
19
20#[macro_export]
22macro_rules! parse_definition {
23 ($self:ident, $definitions:ident, $($kind:ident => $parse_fn:ident),* $(,)?) => {
24 let next_token = $self.peek_next_token();
25
26 match next_token.kind {
27 $(
28 TokenKind::$kind => {
29 if let Some(node) = $self.$parse_fn() {
30 $definitions.push(Rc::new(DefinitionNode::$kind(node)));
31 } else {
32 $self.recover_to_next_definition();
33 }
34 }
35 )*
36 TokenKind::Eof => break,
37 _ => {
38 $self.add_error(
39 format!("Unexpected token: {}", next_token.kind),
40 next_token.range(),
41 );
42 $self.eat_next_token();
43 $self.recover_to_next_definition();
44 }
45 }
46 };
47}
48
49#[macro_export]
51macro_rules! extract_token_value {
52 ($self:expr, $token:expr, $value_type:ident, $kind:expr) => {
53 if let TokenKind::$value_type(value) = $token.kind {
54 value
55 } else {
56 $self.add_error(
57 format!("Expected {}, but got {}", $kind, $token.kind),
58 $token.range(),
59 );
60 return None;
61 }
62 };
63}
64
65#[macro_export]
67macro_rules! expect_token {
68 ($self:expr, $kind:ident, $expected_str:expr) => {
69 let token = $self.next_token();
70 if token.kind != TokenKind::$kind {
71 $self.add_error(
72 format!("Expected {}, but got {}", $expected_str, token.kind),
73 token.range(),
74 );
75 return None;
76 }
77 };
78}
79
80#[macro_export]
82macro_rules! expect {
83 ($self:expr, $expected:expr, $expected_str:expr) => {
84 let token = $self.next_token();
85 if token.kind != $expected {
86 $self.add_error(
87 format!("Expected {}, but got {}", $expected_str, token.kind),
88 token.range(),
89 );
90 return None;
91 }
92 };
93}
94
95#[macro_export]
97macro_rules! opt_list_separator {
98 ($self:expr) => {
99 let token = $self.peek_next_token();
100 if token.is_line_separator() {
101 $self.eat_next_token();
102 }
103 };
104}
105
106#[macro_export]
108macro_rules! break_opt_token_or_eof {
109 ($self:expr, $kind:ident) => {
110 let next_token = $self.peek_next_token();
111 if next_token.kind == TokenKind::$kind {
112 $self.eat_next_token();
113 break;
114 }
115 if next_token.is_eof() {
116 $self.add_error("Unexpected end of file".to_string(), next_token.range());
117 break;
118 }
119 };
120}