Skip to main content

foch_annotation/
diagnostic.rs

1//! Problems in annotations, located in the original source.
2
3use crate::source::SourceSpan;
4use serde::{Deserialize, Serialize};
5use std::fmt;
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum Severity {
10	Error,
11	Warning,
12}
13
14#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
15#[serde(rename_all = "snake_case")]
16#[non_exhaustive]
17pub enum Code {
18	/// The surrounding script does not parse.
19	Parse,
20	/// Malformed annotation syntax, such as an unterminated `#test(`.
21	Malformed,
22	/// A comment shaped like an annotation with an unknown name.
23	UnknownAnnotation,
24	UnknownParameter,
25	MissingParameter,
26	DuplicateParameter,
27	InvalidValue,
28	/// Not followed by what it applies to.
29	Orphan,
30	/// Inside a definition rather than before it.
31	Nested,
32	/// Attached to a definition the annotation does not support.
33	UnsupportedTarget,
34	DuplicateModifier,
35}
36
37#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
38pub struct Diagnostic {
39	pub code: Code,
40	pub severity: Severity,
41	pub span: SourceSpan,
42	pub message: String,
43}
44
45impl Diagnostic {
46	pub(crate) fn error(code: Code, span: SourceSpan, message: impl Into<String>) -> Self {
47		Self {
48			code,
49			severity: Severity::Error,
50			span,
51			message: message.into(),
52		}
53	}
54}
55
56impl fmt::Display for Diagnostic {
57	fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
58		let severity = match self.severity {
59			Severity::Error => "error",
60			Severity::Warning => "warning",
61		};
62		write!(formatter, "{}: {severity}: {}", self.span, self.message)
63	}
64}