From a826c589dfc10c542deba7ca3343a462e02d6bde Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Sun, 4 May 2025 19:10:56 -0400 Subject: [Rust] Simplify `BnStrCompatible` trait Followup to https://github.com/Vector35/binaryninja-api/pull/5897/ This simplifies usage of the trait in user code, should just be able to `to_cstr` to get the cstr repr and then call `as_ptr`. Co-authored-by: Michael Krasnitski --- rust/src/collaboration/project.rs | 101 +++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 55 deletions(-) (limited to 'rust/src/collaboration/project.rs') diff --git a/rust/src/collaboration/project.rs b/rust/src/collaboration/project.rs index b3c6513d..8c04080b 100644 --- a/rust/src/collaboration/project.rs +++ b/rust/src/collaboration/project.rs @@ -15,7 +15,7 @@ use crate::file_metadata::FileMetadata; use crate::progress::{NoProgressCallback, ProgressCallback}; use crate::project::Project; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; #[repr(transparent)] pub struct RemoteProject { @@ -136,8 +136,8 @@ impl RemoteProject { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_name(&self, name: S) -> Result<(), ()> { - let name = name.into_bytes_with_nul(); + pub fn set_name(&self, name: S) -> Result<(), ()> { + let name = name.to_cstr(); let success = unsafe { BNRemoteProjectSetName( self.handle.as_ptr(), @@ -155,8 +155,8 @@ impl RemoteProject { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_description(&self, description: S) -> Result<(), ()> { - let description = description.into_bytes_with_nul(); + pub fn set_description(&self, description: S) -> Result<(), ()> { + let description = description.to_cstr(); let success = unsafe { BNRemoteProjectSetDescription( self.handle.as_ptr(), @@ -230,12 +230,12 @@ impl RemoteProject { /// /// NOTE: If the project has not been opened, it will be opened upon calling this. /// NOTE: If files have not been pulled, they will be pulled upon calling this. - pub fn get_file_by_id(&self, id: S) -> Result>, ()> { + pub fn get_file_by_id(&self, id: S) -> Result>, ()> { // TODO: This sync should be removed? if !self.has_pulled_files() { self.pull_files()?; } - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let result = unsafe { BNRemoteProjectGetFileById(self.handle.as_ptr(), id.as_ref().as_ptr() as *const c_char) }; @@ -246,15 +246,12 @@ impl RemoteProject { /// /// NOTE: If the project has not been opened, it will be opened upon calling this. /// NOTE: If files have not been pulled, they will be pulled upon calling this. - pub fn get_file_by_name( - &self, - name: S, - ) -> Result>, ()> { + pub fn get_file_by_name(&self, name: S) -> Result>, ()> { // TODO: This sync should be removed? if !self.has_pulled_files() { self.pull_files()?; } - let id = name.into_bytes_with_nul(); + let id = name.to_cstr(); let result = unsafe { BNRemoteProjectGetFileByName( self.handle.as_ptr(), @@ -311,9 +308,9 @@ impl RemoteProject { file_type: RemoteFileType, ) -> Result, ()> where - F: BnStrCompatible, - N: BnStrCompatible, - D: BnStrCompatible, + F: AsCStr, + N: AsCStr, + D: AsCStr, { self.create_file_with_progress( filename, @@ -348,17 +345,17 @@ impl RemoteProject { mut progress: P, ) -> Result, ()> where - F: BnStrCompatible, - N: BnStrCompatible, - D: BnStrCompatible, + F: AsCStr, + N: AsCStr, + D: AsCStr, P: ProgressCallback, { // TODO: This sync should be removed? self.open()?; - let filename = filename.into_bytes_with_nul(); - let name = name.into_bytes_with_nul(); - let description = description.into_bytes_with_nul(); + let filename = filename.to_cstr(); + let name = name.to_cstr(); + let description = description.to_cstr(); let folder_handle = parent_folder.map_or(std::ptr::null_mut(), |f| f.handle.as_ptr()); let file_ptr = unsafe { BNRemoteProjectCreateFile( @@ -386,15 +383,15 @@ impl RemoteProject { pub fn push_file(&self, file: &RemoteFile, extra_fields: I) -> Result<(), ()> where I: Iterator, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, { // TODO: This sync should be removed? self.open()?; let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let mut keys_raw = keys .iter() @@ -446,15 +443,12 @@ impl RemoteProject { /// /// NOTE: If the project has not been opened, it will be opened upon calling this. /// NOTE: If folders have not been pulled, they will be pulled upon calling this. - pub fn get_folder_by_id( - &self, - id: S, - ) -> Result>, ()> { + pub fn get_folder_by_id(&self, id: S) -> Result>, ()> { // TODO: This sync should be removed? if !self.has_pulled_folders() { self.pull_folders()?; } - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let result = unsafe { BNRemoteProjectGetFolderById( self.handle.as_ptr(), @@ -505,8 +499,8 @@ impl RemoteProject { parent_folder: Option<&RemoteFolder>, ) -> Result, ()> where - N: BnStrCompatible, - D: BnStrCompatible, + N: AsCStr, + D: AsCStr, { self.create_folder_with_progress(name, description, parent_folder, NoProgressCallback) } @@ -527,15 +521,15 @@ impl RemoteProject { mut progress: P, ) -> Result, ()> where - N: BnStrCompatible, - D: BnStrCompatible, + N: AsCStr, + D: AsCStr, P: ProgressCallback, { // TODO: This sync should be removed? self.open()?; - let name = name.into_bytes_with_nul(); - let description = description.into_bytes_with_nul(); + let name = name.to_cstr(); + let description = description.to_cstr(); let folder_handle = parent_folder.map_or(std::ptr::null_mut(), |f| f.handle.as_ptr()); let file_ptr = unsafe { BNRemoteProjectCreateFolder( @@ -562,15 +556,15 @@ impl RemoteProject { pub fn push_folder(&self, folder: &RemoteFolder, extra_fields: I) -> Result<(), ()> where I: Iterator, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, { // TODO: This sync should be removed? self.open()?; let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let mut keys_raw = keys .iter() @@ -637,10 +631,7 @@ impl RemoteProject { /// Get a specific permission in the Project by its id. /// /// NOTE: If group or user permissions have not been pulled, they will be pulled upon calling this. - pub fn get_permission_by_id( - &self, - id: S, - ) -> Result>, ()> { + pub fn get_permission_by_id(&self, id: S) -> Result>, ()> { // TODO: This sync should be removed? if !self.has_pulled_user_permissions() { self.pull_user_permissions()?; @@ -650,7 +641,7 @@ impl RemoteProject { self.pull_group_permissions()?; } - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let value = unsafe { BNRemoteProjectGetPermissionById(self.handle.as_ptr(), id.as_ref().as_ptr() as *const _) }; @@ -745,7 +736,7 @@ impl RemoteProject { /// /// * `user_id` - User id /// * `level` - Permission level - pub fn create_user_permission( + pub fn create_user_permission( &self, user_id: S, level: CollaborationPermissionLevel, @@ -760,13 +751,13 @@ impl RemoteProject { /// * `user_id` - User id /// * `level` - Permission level /// * `progress` - The progress callback to call - pub fn create_user_permission_with_progress( + pub fn create_user_permission_with_progress( &self, user_id: S, level: CollaborationPermissionLevel, mut progress: F, ) -> Result, ()> { - let user_id = user_id.into_bytes_with_nul(); + let user_id = user_id.to_cstr(); let value = unsafe { BNRemoteProjectCreateUserPermission( self.handle.as_ptr(), @@ -795,12 +786,12 @@ impl RemoteProject { ) -> Result<(), ()> where I: Iterator, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, { let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let mut keys_raw = keys .iter() @@ -836,8 +827,8 @@ impl RemoteProject { /// # Arguments /// /// * `username` - Username of user to check - pub fn can_user_view(&self, username: S) -> bool { - let username = username.into_bytes_with_nul(); + pub fn can_user_view(&self, username: S) -> bool { + let username = username.to_cstr(); unsafe { BNRemoteProjectCanUserView( self.handle.as_ptr(), @@ -851,8 +842,8 @@ impl RemoteProject { /// # Arguments /// /// * `username` - Username of user to check - pub fn can_user_edit(&self, username: S) -> bool { - let username = username.into_bytes_with_nul(); + pub fn can_user_edit(&self, username: S) -> bool { + let username = username.to_cstr(); unsafe { BNRemoteProjectCanUserEdit( self.handle.as_ptr(), @@ -866,8 +857,8 @@ impl RemoteProject { /// # Arguments /// /// * `username` - Username of user to check - pub fn can_user_admin(&self, username: S) -> bool { - let username = username.into_bytes_with_nul(); + pub fn can_user_admin(&self, username: S) -> bool { + let username = username.to_cstr(); unsafe { BNRemoteProjectCanUserAdmin( self.handle.as_ptr(), -- cgit v1.3.1