binaryninja/collaboration/
changeset.rs1use binaryninjacore_sys::*;
2use std::ptr::NonNull;
3
4use super::{RemoteFile, RemoteUser};
5
6use crate::database::snapshot::SnapshotId;
7use crate::database::Database;
8use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
9use crate::string::{BnString, IntoCStr};
10
11#[repr(transparent)]
13pub struct Changeset {
14 handle: NonNull<BNCollaborationChangeset>,
15}
16
17impl Changeset {
18 pub(crate) unsafe fn from_raw(handle: NonNull<BNCollaborationChangeset>) -> Self {
19 Self { handle }
20 }
21
22 #[allow(unused)]
23 pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNCollaborationChangeset>) -> Ref<Self> {
24 Ref::new(Self { handle })
25 }
26
27 pub fn database(&self) -> Result<Database, ()> {
29 let result = unsafe { BNCollaborationChangesetGetDatabase(self.handle.as_ptr()) };
30 let raw = NonNull::new(result).ok_or(())?;
31 Ok(unsafe { Database::from_raw(raw) })
32 }
33
34 pub fn file(&self) -> Result<Ref<RemoteFile>, ()> {
36 let result = unsafe { BNCollaborationChangesetGetFile(self.handle.as_ptr()) };
37 NonNull::new(result)
38 .map(|raw| unsafe { RemoteFile::ref_from_raw(raw) })
39 .ok_or(())
40 }
41
42 pub fn snapshot_ids(&self) -> Result<Array<SnapshotId>, ()> {
44 let mut count = 0;
45 let result =
46 unsafe { BNCollaborationChangesetGetSnapshotIds(self.handle.as_ptr(), &mut count) };
47 (!result.is_null())
48 .then(|| unsafe { Array::new(result, count, ()) })
49 .ok_or(())
50 }
51
52 pub fn author(&self) -> Result<Ref<RemoteUser>, ()> {
54 let result = unsafe { BNCollaborationChangesetGetAuthor(self.handle.as_ptr()) };
55 NonNull::new(result)
56 .map(|raw| unsafe { RemoteUser::ref_from_raw(raw) })
57 .ok_or(())
58 }
59
60 pub fn name(&self) -> String {
62 let result = unsafe { BNCollaborationChangesetGetName(self.handle.as_ptr()) };
63 assert!(!result.is_null());
64 unsafe { BnString::into_string(result) }
65 }
66
67 pub fn set_name(&self, value: &str) -> bool {
69 let value = value.to_cstr();
70 unsafe { BNCollaborationChangesetSetName(self.handle.as_ptr(), value.as_ptr()) }
71 }
72}
73
74impl ToOwned for Changeset {
75 type Owned = Ref<Self>;
76
77 fn to_owned(&self) -> Self::Owned {
78 unsafe { RefCountable::inc_ref(self) }
79 }
80}
81
82unsafe impl RefCountable for Changeset {
83 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
84 Ref::new(Self {
85 handle: NonNull::new(BNNewCollaborationChangesetReference(handle.handle.as_ptr()))
86 .unwrap(),
87 })
88 }
89
90 unsafe fn dec_ref(handle: &Self) {
91 BNFreeCollaborationChangeset(handle.handle.as_ptr());
92 }
93}
94
95impl CoreArrayProvider for Changeset {
96 type Raw = *mut BNCollaborationChangeset;
97 type Context = ();
98 type Wrapped<'a> = Guard<'a, Self>;
99}
100
101unsafe impl CoreArrayProviderInner for Changeset {
102 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
103 BNFreeCollaborationChangesetList(raw, count)
104 }
105
106 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
107 let raw_ptr = NonNull::new(*raw).unwrap();
108 Guard::new(Self::from_raw(raw_ptr), context)
109 }
110}