Skip to main content

cli/semantic/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Semantic facade for the CLI crate.
3
4use std::path::PathBuf;
5
6use objects::object::{ContentHash, FileChangeSet};
7use repo::{Repository, WorktreeStatusOptions};
8use semantic::diff::WorktreeStatus;
9pub use semantic::diff::{
10    SemanticCheckOnlyResult, SemanticCheckStatus, SemanticDiffOptions, SemanticFallbackReason,
11    SemanticSummaryResult,
12};
13
14#[derive(Clone, Debug, Default)]
15pub struct SemanticDiffResult {
16    pub changes: Vec<objects::object::SemanticChange>,
17    pub file_renames: Vec<(PathBuf, PathBuf)>,
18    pub file_changes: FileChangeSet,
19}
20
21pub fn semantic_diff(
22    repo: &Repository,
23    from_tree_hash: &ContentHash,
24    to_tree_hash: &ContentHash,
25    options: &SemanticDiffOptions,
26) -> Result<SemanticDiffResult, anyhow::Error> {
27    let result =
28        semantic::diff::semantic_diff(repo.store(), from_tree_hash, to_tree_hash, options)?;
29    Ok(map_result(result))
30}
31
32pub fn semantic_check_only(
33    repo: &Repository,
34    from_tree_hash: &ContentHash,
35    to_tree_hash: &ContentHash,
36    options: &SemanticDiffOptions,
37) -> Result<SemanticCheckOnlyResult, anyhow::Error> {
38    semantic::diff::semantic_check_only(repo.store(), from_tree_hash, to_tree_hash, options)
39}
40
41pub fn semantic_diff_summary(
42    repo: &Repository,
43    from_tree_hash: &ContentHash,
44    to_tree_hash: &ContentHash,
45    options: &SemanticDiffOptions,
46) -> Result<SemanticSummaryResult, anyhow::Error> {
47    semantic::diff::semantic_diff_summary(repo.store(), from_tree_hash, to_tree_hash, options)
48}
49
50pub fn semantic_diff_worktree(
51    repo: &Repository,
52    from_tree_hash: &ContentHash,
53    options: &SemanticDiffOptions,
54    status_options: &WorktreeStatusOptions,
55) -> Result<SemanticDiffResult, anyhow::Error> {
56    let from_tree = repo.require_tree(from_tree_hash)?;
57    let status = repo.compare_worktree_cached_with_options(&from_tree, status_options)?;
58
59    let status = WorktreeStatus {
60        modified: status.modified,
61        added: status.added,
62        deleted: status.deleted,
63    };
64
65    let result = semantic::diff::semantic_diff_worktree(
66        repo.store(),
67        from_tree_hash,
68        repo.root(),
69        &status,
70        options,
71    )?;
72
73    Ok(map_result(result))
74}
75
76pub fn semantic_check_only_worktree(
77    repo: &Repository,
78    from_tree_hash: &ContentHash,
79    options: &SemanticDiffOptions,
80    status_options: &WorktreeStatusOptions,
81) -> Result<SemanticCheckOnlyResult, anyhow::Error> {
82    let from_tree = repo.require_tree(from_tree_hash)?;
83    let status = repo.compare_worktree_cached_with_options(&from_tree, status_options)?;
84
85    let status = WorktreeStatus {
86        modified: status.modified,
87        added: status.added,
88        deleted: status.deleted,
89    };
90
91    semantic::diff::semantic_check_only_worktree(
92        repo.store(),
93        from_tree_hash,
94        repo.root(),
95        &status,
96        options,
97    )
98}
99
100pub fn semantic_diff_summary_worktree(
101    repo: &Repository,
102    from_tree_hash: &ContentHash,
103    options: &SemanticDiffOptions,
104    status_options: &WorktreeStatusOptions,
105) -> Result<SemanticSummaryResult, anyhow::Error> {
106    let from_tree = repo.require_tree(from_tree_hash)?;
107    let status = repo.compare_worktree_cached_with_options(&from_tree, status_options)?;
108
109    let status = WorktreeStatus {
110        modified: status.modified,
111        added: status.added,
112        deleted: status.deleted,
113    };
114
115    semantic::diff::semantic_diff_summary_worktree(
116        repo.store(),
117        from_tree_hash,
118        repo.root(),
119        &status,
120        options,
121    )
122}
123
124fn map_result(result: semantic::diff::SemanticDiffResult) -> SemanticDiffResult {
125    SemanticDiffResult {
126        changes: result.changes,
127        file_renames: result.file_renames,
128        file_changes: result.file_changes,
129    }
130}