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