Skip to main content

echoes/
reuse.rs

1//! Dependency context findings and search parameters.
2
3use crate::ContextSite;
4use alloc::string::String;
5use alloc::vec::Vec;
6
7/// Parameters for dependency context discovery.
8#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
9#[serde(default, deny_unknown_fields, rename_all = "kebab-case")]
10pub struct DependencySearch {
11    /// Maximum shortest-path dependency distance, default zero.
12    pub depth: Option<usize>,
13    /// Include development dependency edges.
14    pub include_dev: Option<bool>,
15    /// Include build dependency edges.
16    pub include_build: Option<bool>,
17    /// Explore optional dependency paths outside the selected feature configuration.
18    pub all_optional: Option<bool>,
19    /// Cargo features enabled for discovery.
20    pub features: Option<Vec<String>>,
21    /// Enable all workspace features for discovery.
22    pub all_features: Option<bool>,
23    /// Disable default workspace features for discovery.
24    pub no_default_features: Option<bool>,
25    /// Target triple used for dependency discovery.
26    pub target: Option<String>,
27    /// Persistent index directory, defaulting to the user cache directory.
28    pub cache_dir: Option<String>,
29    /// Check the latest published release, default true.
30    pub check_latest: Option<bool>,
31    /// Make dependency findings fail the duplicate gate, default false.
32    pub fail_on_findings: Option<bool>,
33}
34
35impl DependencySearch {
36    #[cfg(feature = "std")]
37    pub(crate) fn fill_from(mut self, defaults: &Self) -> Self {
38        self.depth = self.depth.or(defaults.depth);
39        self.include_dev = self.include_dev.or(defaults.include_dev);
40        self.include_build = self.include_build.or(defaults.include_build);
41        self.all_optional = self.all_optional.or(defaults.all_optional);
42        self.features = self.features.or_else(|| defaults.features.clone());
43        self.all_features = self.all_features.or(defaults.all_features);
44        self.no_default_features = self.no_default_features.or(defaults.no_default_features);
45        self.target = self.target.or_else(|| defaults.target.clone());
46        self.cache_dir = self.cache_dir.or_else(|| defaults.cache_dir.clone());
47        self.check_latest = self.check_latest.or(defaults.check_latest);
48        self.fail_on_findings = self.fail_on_findings.or(defaults.fail_on_findings);
49        self
50    }
51}
52
53/// Source-established accessibility of a lexical context.
54#[derive(
55    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
56)]
57#[serde(rename_all = "kebab-case")]
58pub enum ContextAccess {
59    /// A whole function with an established public path.
60    PublicFunction,
61    /// A whole method with an established public receiver and item path.
62    PublicMethod,
63    /// A whole function whose declaration is internal.
64    InternalFunction,
65    /// A whole method whose declaration is internal.
66    InternalMethod,
67    /// An embedded lexical context requiring extraction.
68    Embedded,
69    /// Source analysis does not establish external accessibility.
70    Unresolved,
71}
72
73/// The reuse path suggested by source evidence.
74#[derive(
75    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
76)]
77#[serde(rename_all = "kebab-case")]
78pub enum ReuseAction {
79    /// Review an accessible API in the resolved version.
80    ReuseApi,
81    /// Review an accessible API in a newer published release.
82    UpgradeApi,
83    /// Request extraction or exposure of an internal context.
84    RequestExtraction,
85    /// Establish accessibility before choosing a reuse path.
86    Unresolved,
87}
88
89/// An existing tagged upstream extraction request.
90#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
91pub struct ExistingIssue {
92    /// Full GitHub issue URL.
93    pub url: String,
94    /// Current upstream issue state.
95    pub state: String,
96}
97
98/// An upstream lexical context matching selected local code.
99#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
100pub struct DependencyCandidate {
101    /// Dependency package name.
102    pub package: String,
103    /// Indexed package version.
104    pub version: String,
105    /// Resolved dependency source identity.
106    pub source: String,
107    /// Shortest dependency distance from selected local crates.
108    pub depth: usize,
109    /// Original package-relative source range.
110    pub site: ContextSite,
111    /// Source-established accessibility.
112    pub access: ContextAccess,
113    /// An established externally accessible function or method path.
114    pub api_path: Option<String>,
115    /// Conditional-compilation requirements retained from source.
116    pub conditions: Vec<String>,
117    /// Source-established extraction constraints and unresolved facts.
118    pub notes: Vec<String>,
119    /// Suggested reuse path requiring human compatibility review.
120    pub action: ReuseAction,
121    /// GitHub repository explicitly declared by the upstream package.
122    pub repository: Option<String>,
123    /// Verified commit-pinned upstream source range.
124    pub source_url: Option<String>,
125    /// Prefilled extraction request URL when no existing request was established.
126    pub issue_url: Option<String>,
127    /// Existing tagged request for the same source URL.
128    pub existing_issue: Option<ExistingIssue>,
129    /// Unresolved source-link or issue-lookup condition.
130    pub lookup_warning: Option<String>,
131}
132
133/// Dependency reuse alternatives for one selected local context.
134#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
135pub struct ReuseGroup {
136    /// Canonical-form hash used to associate local and dependency contexts.
137    pub hash: String,
138    /// Weighted canonical token count.
139    pub tokens: usize,
140    /// Selected local source range.
141    pub local: ContextSite,
142    /// Upstream alternatives ordered with accessible APIs first.
143    pub candidates: Vec<DependencyCandidate>,
144}
145
146/// Coverage and failures of a requested dependency search.
147#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
148pub struct DependencyCoverage {
149    /// Whether every requested dependency analysis job completed.
150    pub complete: bool,
151    /// Distinct dependency source packages examined.
152    pub packages: usize,
153    /// Source files examined through the persistent index.
154    pub indexed_files: usize,
155    /// Source files loaded from a valid persistent index.
156    pub cached_files: usize,
157    /// Failures that leave requested analysis incomplete.
158    pub failures: Vec<String>,
159    /// Non-fatal provenance, lookup or cache diagnostics.
160    pub warnings: Vec<String>,
161}
162
163impl Default for DependencyCoverage {
164    fn default() -> Self {
165        Self {
166            complete: true,
167            packages: 0,
168            indexed_files: 0,
169            cached_files: 0,
170            failures: Vec::new(),
171            warnings: Vec::new(),
172        }
173    }
174}
175
176/// Grouped dependency findings and requested-analysis coverage.
177#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
178pub struct ReuseReport {
179    /// Reuse opportunities grouped by selected local context.
180    pub groups: Vec<ReuseGroup>,
181    /// Completed jobs and missing analysis coverage.
182    pub coverage: DependencyCoverage,
183    /// Whether findings participate in the duplicate gate.
184    #[serde(skip)]
185    pub fail_on_findings: bool,
186}
187
188#[cfg(feature = "std")]
189pub(crate) struct PackageSource {
190    pub(crate) name: String,
191    pub(crate) version: String,
192    pub(crate) source: String,
193    pub(crate) root: std::path::PathBuf,
194    pub(crate) repository: Option<String>,
195    pub(crate) source_hashes: alloc::collections::BTreeMap<String, String>,
196}