binaryninja/collaboration/
merge.rs1use binaryninjacore_sys::*;
2use std::ptr::NonNull;
3
4use crate::database::{snapshot::Snapshot, Database};
5use crate::file_metadata::FileMetadata;
6use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
7use crate::string::{BnString, IntoCStr};
8
9pub type MergeConflictDataType = BNMergeConflictDataType;
10
11#[repr(transparent)]
13pub struct MergeConflict {
14 handle: NonNull<BNAnalysisMergeConflict>,
15}
16
17impl MergeConflict {
18 pub(crate) unsafe fn from_raw(handle: NonNull<BNAnalysisMergeConflict>) -> Self {
19 Self { handle }
20 }
21
22 #[allow(unused)]
23 pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNAnalysisMergeConflict>) -> Ref<Self> {
24 Ref::new(Self { handle })
25 }
26
27 pub fn database(&self) -> Database {
29 let result = unsafe { BNAnalysisMergeConflictGetDatabase(self.handle.as_ptr()) };
30 unsafe { Database::from_raw(NonNull::new(result).unwrap()) }
31 }
32
33 pub fn base_snapshot(&self) -> Option<Snapshot> {
35 let result = unsafe { BNAnalysisMergeConflictGetBaseSnapshot(self.handle.as_ptr()) };
36 NonNull::new(result).map(|handle| unsafe { Snapshot::from_raw(handle) })
37 }
38
39 pub fn first_snapshot(&self) -> Option<Snapshot> {
41 let result = unsafe { BNAnalysisMergeConflictGetFirstSnapshot(self.handle.as_ptr()) };
42 NonNull::new(result).map(|handle| unsafe { Snapshot::from_raw(handle) })
43 }
44
45 pub fn second_snapshot(&self) -> Option<Snapshot> {
47 let result = unsafe { BNAnalysisMergeConflictGetSecondSnapshot(self.handle.as_ptr()) };
48 NonNull::new(result).map(|handle| unsafe { Snapshot::from_raw(handle) })
49 }
50
51 pub fn path_item_string(&self, path: &str) -> Result<BnString, ()> {
52 let path = path.to_cstr();
53 let result = unsafe {
54 BNAnalysisMergeConflictGetPathItemString(self.handle.as_ptr(), path.as_ptr())
55 };
56 (!result.is_null())
57 .then(|| unsafe { BnString::from_raw(result) })
58 .ok_or(())
59 }
60
61 pub fn base_file(&self) -> Option<Ref<FileMetadata>> {
64 let result = unsafe { BNAnalysisMergeConflictGetBaseFile(self.handle.as_ptr()) };
65 (!result.is_null()).then(|| unsafe { Ref::new(FileMetadata::from_raw(result)) })
66 }
67
68 pub fn first_file(&self) -> Option<Ref<FileMetadata>> {
71 let result = unsafe { BNAnalysisMergeConflictGetFirstFile(self.handle.as_ptr()) };
72 (!result.is_null()).then(|| unsafe { Ref::new(FileMetadata::from_raw(result)) })
73 }
74
75 pub fn second_file(&self) -> Option<Ref<FileMetadata>> {
78 let result = unsafe { BNAnalysisMergeConflictGetSecondFile(self.handle.as_ptr()) };
79 (!result.is_null()).then(|| unsafe { Ref::new(FileMetadata::from_raw(result)) })
80 }
81
82 pub fn base(&self) -> Option<BnString> {
84 let result = unsafe { BNAnalysisMergeConflictGetBase(self.handle.as_ptr()) };
85 (!result.is_null()).then(|| unsafe { BnString::from_raw(result) })
86 }
87
88 pub fn first(&self) -> Option<BnString> {
90 let result = unsafe { BNAnalysisMergeConflictGetFirst(self.handle.as_ptr()) };
91 (!result.is_null()).then(|| unsafe { BnString::from_raw(result) })
92 }
93
94 pub fn second(&self) -> Option<BnString> {
96 let result = unsafe { BNAnalysisMergeConflictGetSecond(self.handle.as_ptr()) };
97 (!result.is_null()).then(|| unsafe { BnString::from_raw(result) })
98 }
99
100 pub fn data_type(&self) -> MergeConflictDataType {
102 unsafe { BNAnalysisMergeConflictGetDataType(self.handle.as_ptr()) }
103 }
104
105 pub fn conflict_type(&self) -> String {
108 let result = unsafe { BNAnalysisMergeConflictGetType(self.handle.as_ptr()) };
109 assert!(!result.is_null());
110 unsafe { BnString::into_string(result) }
111 }
112
113 pub fn key(&self) -> String {
116 let result = unsafe { BNAnalysisMergeConflictGetKey(self.handle.as_ptr()) };
117 assert!(!result.is_null());
118 unsafe { BnString::into_string(result) }
119 }
120
121 pub fn success(&self, value: &str) -> Result<(), ()> {
123 let value = value.to_cstr();
124 let success =
125 unsafe { BNAnalysisMergeConflictSuccess(self.handle.as_ptr(), value.as_ptr()) };
126 success.then_some(()).ok_or(())
127 }
128
129 pub unsafe fn get_path_item_number(&self, path_key: &str) -> Option<u64> {
131 let path_key = path_key.to_cstr();
132 let value =
133 unsafe { BNAnalysisMergeConflictGetPathItem(self.handle.as_ptr(), path_key.as_ptr()) };
134 match value.is_null() {
135 false => Some(value as u64),
137 true => None,
138 }
139 }
140
141 pub unsafe fn get_path_item_string(&self, path_key: &str) -> Option<BnString> {
142 let path_key = path_key.to_cstr();
143 let value = unsafe {
144 BNAnalysisMergeConflictGetPathItemString(self.handle.as_ptr(), path_key.as_ptr())
145 };
146 match value.is_null() {
147 false => Some(unsafe { BnString::from_raw(value) }),
148 true => None,
149 }
150 }
151}
152
153impl ToOwned for MergeConflict {
154 type Owned = Ref<Self>;
155
156 fn to_owned(&self) -> Self::Owned {
157 unsafe { RefCountable::inc_ref(self) }
158 }
159}
160
161unsafe impl RefCountable for MergeConflict {
162 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
163 Ref::new(Self {
164 handle: NonNull::new(BNNewAnalysisMergeConflictReference(handle.handle.as_ptr()))
165 .unwrap(),
166 })
167 }
168
169 unsafe fn dec_ref(handle: &Self) {
170 BNFreeAnalysisMergeConflict(handle.handle.as_ptr());
171 }
172}
173
174impl CoreArrayProvider for MergeConflict {
175 type Raw = *mut BNAnalysisMergeConflict;
176 type Context = ();
177 type Wrapped<'a> = Guard<'a, Self>;
178}
179
180unsafe impl CoreArrayProviderInner for MergeConflict {
181 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
182 BNFreeAnalysisMergeConflictList(raw, count)
183 }
184
185 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
186 let raw_ptr = NonNull::new(*raw).unwrap();
187 Guard::new(Self::from_raw(raw_ptr), context)
188 }
189}