Skip to main content

cargo/lints/rules/
im_a_teapot.rs

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