Skip to main content

cargo/diagnostics/rules/
im_a_teapot.rs

1use std::path::Path;
2
3use cargo_util_schemas::manifest::TomlToolLints;
4use cargo_util_terminal::report::AnnotationKind;
5use cargo_util_terminal::report::Group;
6use cargo_util_terminal::report::Level;
7use cargo_util_terminal::report::Origin;
8use cargo_util_terminal::report::Snippet;
9use tracing::instrument;
10
11use super::TEST_DUMMY_UNSTABLE;
12use crate::CargoResult;
13use crate::GlobalContext;
14use crate::core::Feature;
15use crate::core::Package;
16use crate::diagnostics::Lint;
17use crate::diagnostics::LintLevel;
18use crate::diagnostics::get_key_value_span;
19use crate::diagnostics::rel_cwd_manifest_path;
20
21/// This lint is only to be used for testing purposes
22pub static LINT: &Lint = &Lint {
23    name: "im_a_teapot",
24    desc: "`im_a_teapot` is specified",
25    primary_group: &TEST_DUMMY_UNSTABLE,
26    msrv: None,
27    feature_gate: Some(Feature::test_dummy_unstable()),
28    docs: None,
29};
30
31#[instrument(skip_all)]
32pub fn check_im_a_teapot(
33    pkg: &Package,
34    path: &Path,
35    pkg_lints: &TomlToolLints,
36    error_count: &mut usize,
37    gctx: &GlobalContext,
38) -> CargoResult<()> {
39    let manifest = pkg.manifest();
40    let (lint_level, source) =
41        LINT.level(pkg_lints, pkg.rust_version(), manifest.unstable_features());
42
43    if lint_level == LintLevel::Allow {
44        return Ok(());
45    }
46
47    if manifest
48        .normalized_toml()
49        .package()
50        .is_some_and(|p| p.im_a_teapot.is_some())
51    {
52        if lint_level.is_error() {
53            *error_count += 1;
54        }
55        let level = lint_level.to_diagnostic_level();
56        let manifest_path = rel_cwd_manifest_path(path, gctx);
57        let emitted_source = LINT.emitted_source(lint_level, source);
58
59        let mut desc = Group::with_title(level.primary_title(LINT.desc));
60
61        if let Some(document) = manifest.document()
62            && let Some(contents) = manifest.contents()
63        {
64            let span = get_key_value_span(document, &["package", "im-a-teapot"]).unwrap();
65
66            desc = desc.element(
67                Snippet::source(contents)
68                    .path(&manifest_path)
69                    .annotation(AnnotationKind::Primary.span(span.key.start..span.value.end)),
70            );
71        } else {
72            desc = desc.element(Origin::path(&manifest_path));
73        }
74
75        let report = &[desc.element(Level::NOTE.message(&emitted_source))];
76
77        gctx.shell().print_report(report, lint_level.force())?;
78    }
79    Ok(())
80}