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