harper_core/linting/lint.rs
1use std::hash::{DefaultHasher, Hash, Hasher};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{Span, render_markdown::render_markdown};
6
7use super::{LintKind, Suggestion};
8
9/// An error found in text.
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Hash)]
11pub struct Lint {
12 /// The location in the source text the error lies.
13 /// Important for automatic lint resolution through [`Self::suggestions`].
14 pub span: Span<char>,
15 /// The general category the lint belongs to.
16 /// Mostly used for UI elements in integrations.
17 pub lint_kind: LintKind,
18 /// A list of zero or more suggested edits that would resolve the underlying problem.
19 /// See [`Suggestion`].
20 pub suggestions: Vec<Suggestion>,
21 /// A message to be displayed to the user describing the specific error found.
22 ///
23 /// You may use the [`format`] macro to generate more complex messages.
24 pub message: String,
25 /// A numerical value for the importance of a lint.
26 /// Lower = more important.
27 pub priority: u8,
28}
29
30impl Lint {
31 /// Creates a SHA-3 hash of all elements of the lint, sans [`Self::span`].
32 /// This is useful for comparing lints while ignoring their position within the document.
33 ///
34 /// Do not assume that these hash values are stable across Harper versions.
35 pub fn spanless_hash(&self) -> u64 {
36 let mut hasher = DefaultHasher::new();
37
38 self.lint_kind.hash(&mut hasher);
39 self.suggestions.hash(&mut hasher);
40 self.message.hash(&mut hasher);
41 self.priority.hash(&mut hasher);
42
43 hasher.finish()
44 }
45
46 /// Interpret the message as Markdown and render it to HTML.
47 pub fn message_html(&self) -> String {
48 render_markdown(&self.message)
49 }
50
51 /// Get the lint's span content as a slice of characters.
52 pub fn get_ch<'a>(&self, source: &'a [char]) -> &'a [char] {
53 self.span.get_content(source)
54 }
55
56 /// Get the lint's span content as a string.
57 pub fn get_str(&self, source: &[char]) -> String {
58 self.span.get_content_string(source)
59 }
60}
61
62impl Default for Lint {
63 fn default() -> Self {
64 Self {
65 span: Default::default(),
66 lint_kind: Default::default(),
67 suggestions: Default::default(),
68 message: Default::default(),
69 priority: 127,
70 }
71 }
72}