summaryrefslogtreecommitdiff
path: root/rust/src/collaboration/undo.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/collaboration/undo.rs')
-rw-r--r--rust/src/collaboration/undo.rs166
1 files changed, 166 insertions, 0 deletions
diff --git a/rust/src/collaboration/undo.rs b/rust/src/collaboration/undo.rs
new file mode 100644
index 00000000..9f1cc5f0
--- /dev/null
+++ b/rust/src/collaboration/undo.rs
@@ -0,0 +1,166 @@
+use crate::collaboration::{Remote, RemoteFile, RemoteProject, RemoteSnapshot};
+use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
+use crate::string::BnString;
+use binaryninjacore_sys::{
+ BNCollaborationFreeIdList, BNCollaborationUndoEntry, BNCollaborationUndoEntryGetData,
+ BNCollaborationUndoEntryGetFile, BNCollaborationUndoEntryGetId,
+ BNCollaborationUndoEntryGetParent, BNCollaborationUndoEntryGetParentId,
+ BNCollaborationUndoEntryGetProject, BNCollaborationUndoEntryGetRemote,
+ BNCollaborationUndoEntryGetSnapshot, BNCollaborationUndoEntryGetUrl,
+ BNFreeCollaborationUndoEntry, BNFreeCollaborationUndoEntryList,
+ BNNewCollaborationUndoEntryReference,
+};
+use std::fmt;
+use std::fmt::{Display, Formatter};
+use std::ptr::NonNull;
+
+#[repr(transparent)]
+pub struct RemoteUndoEntry {
+ handle: NonNull<BNCollaborationUndoEntry>,
+}
+
+impl RemoteUndoEntry {
+ pub(crate) unsafe fn from_raw(handle: NonNull<BNCollaborationUndoEntry>) -> Self {
+ Self { handle }
+ }
+
+ pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNCollaborationUndoEntry>) -> Ref<Self> {
+ Ref::new(Self { handle })
+ }
+
+ /// Owning Snapshot
+ pub fn snapshot(&self) -> Result<Ref<RemoteSnapshot>, ()> {
+ let value = unsafe { BNCollaborationUndoEntryGetSnapshot(self.handle.as_ptr()) };
+ let handle = NonNull::new(value).ok_or(())?;
+ Ok(unsafe { RemoteSnapshot::ref_from_raw(handle) })
+ }
+
+ /// Owning File
+ pub fn file(&self) -> Result<Ref<RemoteFile>, ()> {
+ let value = unsafe { BNCollaborationUndoEntryGetFile(self.handle.as_ptr()) };
+ let handle = NonNull::new(value).ok_or(())?;
+ Ok(unsafe { RemoteFile::ref_from_raw(handle) })
+ }
+
+ /// Owning Project
+ pub fn project(&self) -> Result<Ref<RemoteProject>, ()> {
+ let value = unsafe { BNCollaborationUndoEntryGetProject(self.handle.as_ptr()) };
+ let handle = NonNull::new(value).ok_or(())?;
+ Ok(unsafe { RemoteProject::ref_from_raw(handle) })
+ }
+
+ /// Owning Remote
+ pub fn remote(&self) -> Result<Ref<Remote>, ()> {
+ let value = unsafe { BNCollaborationUndoEntryGetRemote(self.handle.as_ptr()) };
+ let handle = NonNull::new(value).ok_or(())?;
+ Ok(unsafe { Remote::ref_from_raw(handle) })
+ }
+
+ /// Web api endpoint url
+ pub fn url(&self) -> BnString {
+ let value = unsafe { BNCollaborationUndoEntryGetUrl(self.handle.as_ptr()) };
+ assert!(!value.is_null());
+ unsafe { BnString::from_raw(value) }
+ }
+
+ /// Unique id
+ pub fn id(&self) -> RemoteUndoEntryId {
+ RemoteUndoEntryId(unsafe { BNCollaborationUndoEntryGetId(self.handle.as_ptr()) })
+ }
+
+ /// Id of parent undo entry
+ pub fn parent_id(&self) -> Option<RemoteUndoEntryId> {
+ let mut value = 0;
+ let success =
+ unsafe { BNCollaborationUndoEntryGetParentId(self.handle.as_ptr(), &mut value) };
+ success.then_some(RemoteUndoEntryId(value))
+ }
+
+ /// Undo entry contents data
+ pub fn data(&self) -> Result<BnString, ()> {
+ let mut value = std::ptr::null_mut();
+ let success = unsafe { BNCollaborationUndoEntryGetData(self.handle.as_ptr(), &mut value) };
+ if !success {
+ return Err(());
+ }
+ assert!(!value.is_null());
+ Ok(unsafe { BnString::from_raw(value) })
+ }
+
+ /// Parent Undo Entry object
+ pub fn parent(&self) -> Option<Ref<RemoteUndoEntry>> {
+ let value = unsafe { BNCollaborationUndoEntryGetParent(self.handle.as_ptr()) };
+ NonNull::new(value).map(|handle| unsafe { RemoteUndoEntry::ref_from_raw(handle) })
+ }
+}
+
+impl PartialEq for RemoteUndoEntry {
+ fn eq(&self, other: &Self) -> bool {
+ self.id() == other.id()
+ }
+}
+impl Eq for RemoteUndoEntry {}
+
+impl ToOwned for RemoteUndoEntry {
+ type Owned = Ref<Self>;
+
+ fn to_owned(&self) -> Self::Owned {
+ unsafe { RefCountable::inc_ref(self) }
+ }
+}
+
+unsafe impl RefCountable for RemoteUndoEntry {
+ unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
+ Ref::new(Self {
+ handle: NonNull::new(BNNewCollaborationUndoEntryReference(handle.handle.as_ptr()))
+ .unwrap(),
+ })
+ }
+
+ unsafe fn dec_ref(handle: &Self) {
+ BNFreeCollaborationUndoEntry(handle.handle.as_ptr());
+ }
+}
+
+impl CoreArrayProvider for RemoteUndoEntry {
+ type Raw = *mut BNCollaborationUndoEntry;
+ type Context = ();
+ type Wrapped<'a> = Guard<'a, Self>;
+}
+
+unsafe impl CoreArrayProviderInner for RemoteUndoEntry {
+ unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
+ BNFreeCollaborationUndoEntryList(raw, count)
+ }
+
+ unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
+ let raw_ptr = NonNull::new(*raw).unwrap();
+ Guard::new(Self::from_raw(raw_ptr), context)
+ }
+}
+
+#[repr(transparent)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct RemoteUndoEntryId(pub u64);
+
+impl Display for RemoteUndoEntryId {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("{}", self.0))
+ }
+}
+
+impl CoreArrayProvider for RemoteUndoEntryId {
+ type Raw = u64;
+ type Context = ();
+ type Wrapped<'a> = RemoteUndoEntryId;
+}
+
+unsafe impl CoreArrayProviderInner for RemoteUndoEntryId {
+ unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
+ BNCollaborationFreeIdList(raw, count)
+ }
+
+ unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
+ RemoteUndoEntryId(*raw)
+ }
+}