1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum DiagnosticSeverity {
4 Warning,
6 Error,
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum DiagnosticStage {
13 Header,
15 ConstantPool,
17 Member,
19 Attribute,
21 Code,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct Diagnostic {
28 severity: DiagnosticSeverity,
29 stage: DiagnosticStage,
30 offset: Option<usize>,
31 message: String,
32}
33
34impl Diagnostic {
35 pub(crate) fn from_decode_error(error: &FerroBabeError) -> Self {
36 let (stage, offset, message) = match error {
37 FerroBabeError::Decode { source } => match source {
38 ClassReadError::UnexpectedEof => {
39 (DiagnosticStage::Member, None, source.to_string())
40 }
41 ClassReadError::InvalidConstantPoolTag(_) | ClassReadError::InvalidIndex(_) => {
42 (DiagnosticStage::ConstantPool, None, source.to_string())
43 }
44 ClassReadError::InvalidAttribute(_) => {
45 (DiagnosticStage::Attribute, None, source.to_string())
46 }
47 ClassReadError::InvalidOpcode { offset, .. } => {
48 (DiagnosticStage::Code, Some(*offset), source.to_string())
49 }
50 ClassReadError::InvalidMagic(_) | ClassReadError::InvalidClassVersion(_) => {
51 (DiagnosticStage::Header, None, source.to_string())
52 }
53 ClassReadError::Utf8Error(_) => {
54 (DiagnosticStage::ConstantPool, None, source.to_string())
55 }
56 },
57 _ => (DiagnosticStage::Header, None, error.to_string()),
58 };
59
60 Self {
61 severity: DiagnosticSeverity::Error,
62 stage,
63 offset,
64 message,
65 }
66 }
67
68 #[must_use]
70 pub fn severity(&self) -> DiagnosticSeverity {
71 self.severity
72 }
73
74 #[must_use]
76 pub fn stage(&self) -> DiagnosticStage {
77 self.stage
78 }
79
80 #[must_use]
84 pub fn offset(&self) -> Option<usize> {
85 self.offset
86 }
87
88 #[must_use]
90 pub fn message(&self) -> &str {
91 &self.message
92 }
93}
94use rust_asm::error::ClassReadError;
95
96use crate::FerroBabeError;