comment_parser/syntax.rs
1use std::fmt;
2use std::str::from_utf8;
3
4/// The [parser][`CommentParser`] uses a few syntax rules, to be
5/// able to identify comments and strings.
6///
7/// The crate includes a bunch of predefined syntax rules,
8/// which can be accessed by calling [`get_syntax`].
9///
10/// [`CommentParser`]: struct.CommentParser.html
11/// [`get_syntax`]: fn.get_syntax.html
12///
13/// # Panics
14///
15/// Note that [`CommentParser`] panics immediately upon calling [`new`][CommentParser::new],
16/// if any `SyntaxRule` contains an empty `&[u8]`.
17///
18/// # Example
19///
20/// If you want to create syntax rules, for a parser only capturing
21/// [doc line comments][doc comments], then that would look like this:
22///
23/// [doc comments]: https://doc.rust-lang.org/stable/reference/comments.html#doc-comments
24///
25/// ```
26/// use comment_parser::SyntaxRule;
27///
28/// let rules = [
29/// SyntaxRule::LineComment(b"//!"),
30/// ];
31/// ```
32///
33/// That is enough to catch all doc line comments.
34///
35/// However, it is highly recommended to include syntax rules for strings.
36/// Otherwise, with the input `"foo //! bar"` the parser will capture that
37/// as a line comment. Since it was not given any rules on how to identify
38/// and skip strings.
39///
40/// ```
41/// # use comment_parser::SyntaxRule;
42/// let rules = [
43/// SyntaxRule::LineComment(b"//!"),
44/// SyntaxRule::String(b"\""),
45/// ];
46/// ```
47///
48/// Go to [`CommentParser`][CommentParser::new] to see an example on how to
49/// use custom syntax rules.
50///
51/// [CommentParser::new]: struct.CommentParser.html#method.new
52///
53/// # Unsupported Language
54///
55/// If you implement syntax rules for an unsupported language, then feel free to submit
56/// your `rules` on the [issue tracker], or add it to [languages.rs] and submit
57/// a [pull request].
58///
59/// [issue tracker]: https://github.com/vallentin/comment-parser/issues
60/// [pull request]: https://github.com/vallentin/comment-parser/pulls
61/// [languages.rs]: https://github.com/vallentin/comment-parser/blob/master/src/languages.rs
62#[derive(Clone)]
63pub enum SyntaxRule<'a> {
64 /// `LineComment(start)`
65 LineComment(&'a [u8]),
66 /// `BlockComment(start, end)`
67 BlockComment(&'a [u8], &'a [u8]),
68 /// `String(delimiter)`
69 String(&'a [u8]),
70}
71
72impl<'a> fmt::Debug for SyntaxRule<'a> {
73 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
74 use SyntaxRule::*;
75 match self {
76 LineComment(start) => {
77 if let Ok(start) = from_utf8(start) {
78 fmt.debug_tuple("LineComment").field(&start).finish()
79 } else {
80 fmt.debug_tuple("LineComment").field(start).finish()
81 }
82 }
83 BlockComment(start, end) => {
84 if let (Ok(start), Ok(end)) = (from_utf8(start), from_utf8(end)) {
85 fmt.debug_tuple("BlockComment")
86 .field(&start)
87 .field(&end)
88 .finish()
89 } else {
90 fmt.debug_tuple("BlockComment")
91 .field(&start)
92 .field(&end)
93 .finish()
94 }
95 }
96 String(start) => {
97 if let Ok(start) = from_utf8(start) {
98 fmt.debug_tuple("String").field(&start).finish()
99 } else {
100 fmt.debug_tuple("String").field(start).finish()
101 }
102 }
103 }
104 }
105}