1use 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}