cargo-dry4rust 0.4.0

A cargo subcommand that detects duplicate and near-duplicate code blocks in Rust codebases using AST normalization
Documentation
// Copyright (c) 2026 Matjaz Domen Pecan
// Copyright 2026 Umberto Gotti <umberto.gotti@umbertogotti.dev>
// Licensed under the MIT License
// SPDX-License-Identifier: MIT

use std::borrow::Cow;
use std::io;
use std::path::Path;

use crate::grouper::{DuplicateGroup, DuplicationStats};
use crate::output::check_breach::CheckBreach;
use crate::output::report::Report;

/// Compute a display path relative to an optional base, falling back to the absolute path.
#[must_use]
pub fn display_path<'a>(base: Option<&Path>, path: &'a Path) -> Cow<'a, str> {
    if let Some(base) = base
        && let Ok(rel) = path.strip_prefix(base)
    {
        return rel.to_string_lossy();
    }
    path.to_string_lossy()
}

/// Trait for reporting analysis results.
///
/// The section methods write one part each, which suits a format whose parts
/// stand alone. `report` and `report_check` write a whole document, which is
/// what a format that has to be one value needs -- the implementation decides
/// how its parts fit together, because only it knows whether they can be
/// concatenated.
pub trait Reporter {
    /// Build a full report as one document.
    fn report(&self, report: &Report<'_>) -> io::Result<String>;

    /// Build a check verdict as one document. No breaches means it passed.
    fn report_check(
        &self,
        stats: &DuplicationStats,
        breaches: &[CheckBreach<'_>],
    ) -> io::Result<String>;

    fn report_stats(&self, stats: &DuplicationStats) -> io::Result<String>;
    fn report_exact(&self, groups: &[DuplicateGroup]) -> io::Result<String>;
    fn report_near(&self, groups: &[DuplicateGroup]) -> io::Result<String>;
    fn report_sub_exact(&self, groups: &[DuplicateGroup]) -> io::Result<String>;
    fn report_sub_near(&self, groups: &[DuplicateGroup]) -> io::Result<String>;
}