cargo_deny/diag/
general.rs

1//! Contains general diagnostics that are shared between various checks
2
3use crate::{
4    Span,
5    diag::{Diagnostic, FileId, Label, Severity},
6};
7use std::fmt;
8
9#[derive(
10    strum::Display,
11    strum::EnumString,
12    strum::EnumIter,
13    strum::IntoStaticStr,
14    Copy,
15    Clone,
16    Debug,
17    PartialEq,
18    Eq,
19    PartialOrd,
20    Ord,
21)]
22#[strum(serialize_all = "kebab-case")]
23pub enum Code {
24    Deprecated,
25}
26
27impl Code {
28    #[inline]
29    pub fn description(self) -> &'static str {
30        match self {
31            Self::Deprecated => "A deprecated field was detected",
32        }
33    }
34}
35
36impl From<Code> for String {
37    fn from(c: Code) -> Self {
38        c.to_string()
39    }
40}
41
42pub enum DeprecationReason {
43    WillBeRemoved(Option<&'static str>),
44    Moved(&'static str),
45    Renamed(&'static str),
46    MovedAndRenamed {
47        table: &'static str,
48        key: &'static str,
49    },
50    Removed(&'static str),
51}
52
53impl fmt::Display for DeprecationReason {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        match self {
56            Self::WillBeRemoved(url) => {
57                if let Some(url) = url {
58                    write!(
59                        f,
60                        "this key will be removed in a future update, see {url} for details"
61                    )
62                } else {
63                    f.write_str("this key will be removed in a future update")
64                }
65            }
66            Self::Moved(tab) => write!(f, "this key has been moved to [{tab}]"),
67            Self::Renamed(nname) => write!(f, "this key has been renamed to '{nname}'"),
68            Self::MovedAndRenamed { table, key } => {
69                write!(f, "this key been moved to [{table}] and renamed to '{key}'")
70            }
71            Self::Removed(url) => {
72                write!(
73                    f,
74                    "this key has been removed, see {url} for migration information"
75                )
76            }
77        }
78    }
79}
80
81pub struct Deprecated {
82    pub key: Span,
83    pub reason: DeprecationReason,
84    pub file_id: FileId,
85}
86
87impl From<Deprecated> for Diagnostic {
88    fn from(dep: Deprecated) -> Self {
89        let severity = if matches!(dep.reason, DeprecationReason::Removed(_)) {
90            Severity::Error
91        } else {
92            Severity::Warning
93        };
94
95        Diagnostic::new(severity)
96            .with_message(dep.reason)
97            .with_labels(vec![Label::primary(dep.file_id, dep.key)])
98            .with_code(Code::Deprecated)
99    }
100}