1use libc::c_uint;
2use std::marker;
3use std::mem;
4use std::str;
5
6use crate::call::Convert;
7use crate::util::Binding;
8use crate::{raw, Commit, FileFavor, Oid};
9
10pub struct AnnotatedCommit<'repo> {
16 raw: *mut raw::git_annotated_commit,
17 _marker: marker::PhantomData<Commit<'repo>>,
18}
19
20pub struct MergeOptions {
22 raw: raw::git_merge_options,
23}
24
25impl<'repo> AnnotatedCommit<'repo> {
26 pub fn id(&self) -> Oid {
28 unsafe { Binding::from_raw(raw::git_annotated_commit_id(self.raw)) }
29 }
30
31 pub fn refname(&self) -> Option<&str> {
35 str::from_utf8(self.refname_bytes()).ok()
36 }
37
38 pub fn refname_bytes(&self) -> &[u8] {
40 unsafe { crate::opt_bytes(self, raw::git_annotated_commit_ref(&*self.raw)).unwrap() }
41 }
42}
43
44impl Default for MergeOptions {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50impl MergeOptions {
51 pub fn new() -> MergeOptions {
53 let mut opts = MergeOptions {
54 raw: unsafe { mem::zeroed() },
55 };
56 assert_eq!(unsafe { raw::git_merge_init_options(&mut opts.raw, 1) }, 0);
57 opts
58 }
59
60 fn flag(&mut self, opt: u32, val: bool) -> &mut MergeOptions {
61 if val {
62 self.raw.flags |= opt;
63 } else {
64 self.raw.flags &= !opt;
65 }
66 self
67 }
68
69 pub fn find_renames(&mut self, find: bool) -> &mut MergeOptions {
71 self.flag(raw::GIT_MERGE_FIND_RENAMES as u32, find)
72 }
73
74 pub fn fail_on_conflict(&mut self, fail: bool) -> &mut MergeOptions {
77 self.flag(raw::GIT_MERGE_FAIL_ON_CONFLICT as u32, fail)
78 }
79
80 pub fn skip_reuc(&mut self, skip: bool) -> &mut MergeOptions {
82 self.flag(raw::GIT_MERGE_FAIL_ON_CONFLICT as u32, skip)
83 }
84
85 pub fn no_recursive(&mut self, disable: bool) -> &mut MergeOptions {
89 self.flag(raw::GIT_MERGE_NO_RECURSIVE as u32, disable)
90 }
91
92 pub fn rename_threshold(&mut self, thresh: u32) -> &mut MergeOptions {
94 self.raw.rename_threshold = thresh;
95 self
96 }
97
98 pub fn target_limit(&mut self, limit: u32) -> &mut MergeOptions {
103 self.raw.target_limit = limit as c_uint;
104 self
105 }
106
107 pub fn recursion_limit(&mut self, limit: u32) -> &mut MergeOptions {
112 self.raw.recursion_limit = limit as c_uint;
113 self
114 }
115
116 pub fn file_favor(&mut self, favor: FileFavor) -> &mut MergeOptions {
118 self.raw.file_favor = favor.convert();
119 self
120 }
121
122 fn file_flag(&mut self, opt: u32, val: bool) -> &mut MergeOptions {
123 if val {
124 self.raw.file_flags |= opt;
125 } else {
126 self.raw.file_flags &= !opt;
127 }
128 self
129 }
130
131 pub fn standard_style(&mut self, standard: bool) -> &mut MergeOptions {
133 self.file_flag(raw::GIT_MERGE_FILE_STYLE_MERGE as u32, standard)
134 }
135
136 pub fn diff3_style(&mut self, diff3: bool) -> &mut MergeOptions {
138 self.file_flag(raw::GIT_MERGE_FILE_STYLE_DIFF3 as u32, diff3)
139 }
140
141 pub fn simplify_alnum(&mut self, simplify: bool) -> &mut MergeOptions {
143 self.file_flag(raw::GIT_MERGE_FILE_SIMPLIFY_ALNUM as u32, simplify)
144 }
145
146 pub fn ignore_whitespace(&mut self, ignore: bool) -> &mut MergeOptions {
148 self.file_flag(raw::GIT_MERGE_FILE_IGNORE_WHITESPACE as u32, ignore)
149 }
150
151 pub fn ignore_whitespace_change(&mut self, ignore: bool) -> &mut MergeOptions {
153 self.file_flag(raw::GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE as u32, ignore)
154 }
155
156 pub fn ignore_whitespace_eol(&mut self, ignore: bool) -> &mut MergeOptions {
158 self.file_flag(raw::GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL as u32, ignore)
159 }
160
161 pub fn patience(&mut self, patience: bool) -> &mut MergeOptions {
163 self.file_flag(raw::GIT_MERGE_FILE_DIFF_PATIENCE as u32, patience)
164 }
165
166 pub fn minimal(&mut self, minimal: bool) -> &mut MergeOptions {
168 self.file_flag(raw::GIT_MERGE_FILE_DIFF_MINIMAL as u32, minimal)
169 }
170
171 pub unsafe fn raw(&self) -> *const raw::git_merge_options {
173 &self.raw as *const _
174 }
175}
176
177impl<'repo> Binding for AnnotatedCommit<'repo> {
178 type Raw = *mut raw::git_annotated_commit;
179 unsafe fn from_raw(raw: *mut raw::git_annotated_commit) -> AnnotatedCommit<'repo> {
180 AnnotatedCommit {
181 raw,
182 _marker: marker::PhantomData,
183 }
184 }
185 fn raw(&self) -> *mut raw::git_annotated_commit {
186 self.raw
187 }
188}
189
190impl<'repo> Drop for AnnotatedCommit<'repo> {
191 fn drop(&mut self) {
192 unsafe { raw::git_annotated_commit_free(self.raw) }
193 }
194}