ruby_prism/parse_result/
diagnostics.rs1use std::ffi::CStr;
4use std::marker::PhantomData;
5
6use ruby_prism_sys::{pm_diagnostic_location, pm_diagnostic_message, pm_diagnostic_t, pm_parser_t};
7
8use super::Location;
9
10#[derive(Debug)]
12pub struct Diagnostic<'pr> {
13 raw: *const pm_diagnostic_t,
14 parser: *const pm_parser_t,
15 marker: PhantomData<&'pr pm_diagnostic_t>,
16}
17
18impl<'pr> Diagnostic<'pr> {
19 #[must_use]
25 pub fn message(&self) -> &str {
26 unsafe {
27 let message = pm_diagnostic_message(self.raw);
28 CStr::from_ptr(message).to_str().expect("prism allows only UTF-8 for diagnostics.")
29 }
30 }
31
32 #[must_use]
34 pub fn location(&self) -> Location<'pr> {
35 let loc = unsafe { pm_diagnostic_location(self.raw) };
36 Location {
37 parser: self.parser,
38 start: loc.start,
39 length: loc.length,
40 marker: PhantomData,
41 }
42 }
43}
44
45pub struct Diagnostics<'pr> {
47 ptrs: Vec<*const pm_diagnostic_t>,
48 index: usize,
49 parser: *const pm_parser_t,
50 marker: PhantomData<&'pr pm_diagnostic_t>,
51}
52
53impl Diagnostics<'_> {
54 pub(crate) const fn new(ptrs: Vec<*const pm_diagnostic_t>, parser: *const pm_parser_t) -> Self {
55 Diagnostics { ptrs, index: 0, parser, marker: PhantomData }
56 }
57}
58
59impl<'pr> Iterator for Diagnostics<'pr> {
60 type Item = Diagnostic<'pr>;
61
62 fn next(&mut self) -> Option<Self::Item> {
63 if self.index < self.ptrs.len() {
64 let diagnostic = self.ptrs[self.index];
65 self.index += 1;
66 Some(Diagnostic {
67 raw: diagnostic,
68 parser: self.parser,
69 marker: PhantomData,
70 })
71 } else {
72 None
73 }
74 }
75}