ruby_prism/parse_result/
comments.rs1use std::marker::PhantomData;
4
5use ruby_prism_sys::{pm_comment_location, pm_comment_t, pm_comment_type, pm_comment_type_t, pm_magic_comment_key, pm_magic_comment_t, pm_magic_comment_value, pm_parser_start, pm_parser_t};
6
7use super::Location;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum CommentType {
12 InlineComment,
14 EmbDocComment,
16}
17
18#[derive(Debug)]
20pub struct Comment<'pr> {
21 raw: *const pm_comment_t,
22 parser: *const pm_parser_t,
23 marker: PhantomData<&'pr pm_comment_t>,
24}
25
26impl<'pr> Comment<'pr> {
27 #[must_use]
29 pub fn text(&self) -> &[u8] {
30 self.location().as_slice()
31 }
32
33 #[must_use]
35 pub fn type_(&self) -> CommentType {
36 let type_ = unsafe { pm_comment_type(self.raw) };
37 if type_ == pm_comment_type_t::PM_COMMENT_EMBDOC {
38 CommentType::EmbDocComment
39 } else {
40 CommentType::InlineComment
41 }
42 }
43
44 #[must_use]
46 pub fn location(&self) -> Location<'pr> {
47 let loc = unsafe { pm_comment_location(self.raw) };
48 Location {
49 parser: self.parser,
50 start: loc.start,
51 length: loc.length,
52 marker: PhantomData,
53 }
54 }
55}
56
57pub struct Comments<'pr> {
59 ptrs: Vec<*const pm_comment_t>,
60 index: usize,
61 parser: *const pm_parser_t,
62 marker: PhantomData<&'pr pm_comment_t>,
63}
64
65impl Comments<'_> {
66 pub(crate) const fn new(ptrs: Vec<*const pm_comment_t>, parser: *const pm_parser_t) -> Self {
67 Comments { ptrs, index: 0, parser, marker: PhantomData }
68 }
69}
70
71impl<'pr> Iterator for Comments<'pr> {
72 type Item = Comment<'pr>;
73
74 fn next(&mut self) -> Option<Self::Item> {
75 if self.index < self.ptrs.len() {
76 let comment = self.ptrs[self.index];
77 self.index += 1;
78 Some(Comment { raw: comment, parser: self.parser, marker: PhantomData })
79 } else {
80 None
81 }
82 }
83}
84
85#[derive(Debug)]
87pub struct MagicComment<'pr> {
88 parser: *const pm_parser_t,
89 raw: *const pm_magic_comment_t,
90 marker: PhantomData<&'pr pm_magic_comment_t>,
91}
92
93impl MagicComment<'_> {
94 #[must_use]
96 pub fn key(&self) -> &[u8] {
97 unsafe {
98 let loc = pm_magic_comment_key(self.raw);
99 let start = pm_parser_start(self.parser).add(loc.start as usize);
100 std::slice::from_raw_parts(start, loc.length as usize)
101 }
102 }
103
104 #[must_use]
106 pub fn value(&self) -> &[u8] {
107 unsafe {
108 let loc = pm_magic_comment_value(self.raw);
109 let start = pm_parser_start(self.parser).add(loc.start as usize);
110 std::slice::from_raw_parts(start, loc.length as usize)
111 }
112 }
113}
114
115pub struct MagicComments<'pr> {
117 ptrs: Vec<*const pm_magic_comment_t>,
118 index: usize,
119 parser: *const pm_parser_t,
120 marker: PhantomData<&'pr pm_magic_comment_t>,
121}
122
123impl MagicComments<'_> {
124 pub(crate) const fn new(ptrs: Vec<*const pm_magic_comment_t>, parser: *const pm_parser_t) -> Self {
125 MagicComments { ptrs, index: 0, parser, marker: PhantomData }
126 }
127}
128
129impl<'pr> Iterator for MagicComments<'pr> {
130 type Item = MagicComment<'pr>;
131
132 fn next(&mut self) -> Option<Self::Item> {
133 if self.index < self.ptrs.len() {
134 let comment = self.ptrs[self.index];
135 self.index += 1;
136 Some(MagicComment { parser: self.parser, raw: comment, marker: PhantomData })
137 } else {
138 None
139 }
140 }
141}