diff options
| author | Mason Reed <mason@vector35.com> | 2025-05-07 19:22:21 -0400 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2025-05-12 17:45:24 -0400 |
| commit | 2f214f6c9935e8ce8df4732cde44a540a003258c (patch) | |
| tree | 6fe319433ef0d2ad75fcc58a50eaa632bb627ec9 /rust/src/collaboration | |
| parent | b4cf0be8816182c9efca037e27e9439482f8bf36 (diff) | |
[Rust] Reduce usage of `IntoCStr` in function signatures
This is being done to reduce complexity in function signatures, specifically many of the strings we are passing ultimately should be new types themselves instead of "just strings", things such as type ids.
Another place which was confusing was dealing with filesystem related APIs, this commit turns most of those params into a stricter `Path` type.
This is bringing the rust api more inline with both python and C++, where the wrapper eagerly converts the string into the languages standard string type.
Special consideration must be made for symbols or other possible non utf-8 objects.
This commit will be followed up with one that adds the `IntoCStr` bound on API's we want to keep as invalid utf-8 so we can for example, get section by name on a section with invalid utf-8.
Diffstat (limited to 'rust/src/collaboration')
| -rw-r--r-- | rust/src/collaboration/changeset.rs | 2 | ||||
| -rw-r--r-- | rust/src/collaboration/file.rs | 42 | ||||
| -rw-r--r-- | rust/src/collaboration/folder.rs | 4 | ||||
| -rw-r--r-- | rust/src/collaboration/group.rs | 7 | ||||
| -rw-r--r-- | rust/src/collaboration/merge.rs | 8 | ||||
| -rw-r--r-- | rust/src/collaboration/project.rs | 97 | ||||
| -rw-r--r-- | rust/src/collaboration/remote.rs | 74 | ||||
| -rw-r--r-- | rust/src/collaboration/snapshot.rs | 4 | ||||
| -rw-r--r-- | rust/src/collaboration/sync.rs | 64 | ||||
| -rw-r--r-- | rust/src/collaboration/user.rs | 4 |
10 files changed, 118 insertions, 188 deletions
diff --git a/rust/src/collaboration/changeset.rs b/rust/src/collaboration/changeset.rs index b07f23de..cce750e6 100644 --- a/rust/src/collaboration/changeset.rs +++ b/rust/src/collaboration/changeset.rs @@ -65,7 +65,7 @@ impl Changeset { } /// Set the name of the changeset, e.g. in a name changeset function. - pub fn set_name<S: IntoCStr>(&self, value: S) -> bool { + pub fn set_name(&self, value: &str) -> bool { let value = value.to_cstr(); unsafe { BNCollaborationChangesetSetName(self.handle.as_ptr(), value.as_ptr()) } } diff --git a/rust/src/collaboration/file.rs b/rust/src/collaboration/file.rs index 699b34b8..624a731a 100644 --- a/rust/src/collaboration/file.rs +++ b/rust/src/collaboration/file.rs @@ -1,5 +1,6 @@ use std::ffi::c_void; use std::fmt::{Debug, Formatter}; +use std::path::Path; use std::ptr::NonNull; use std::time::SystemTime; @@ -94,7 +95,7 @@ impl RemoteFile { success.then_some(()).ok_or(()) } - pub fn set_metadata<S: IntoCStr>(&self, folder: S) -> Result<(), ()> { + pub fn set_metadata(&self, folder: &str) -> Result<(), ()> { let folder_raw = folder.to_cstr(); let success = unsafe { BNRemoteFileSetMetadata(self.handle.as_ptr(), folder_raw.as_ptr()) }; success.then_some(()).ok_or(()) @@ -185,7 +186,7 @@ impl RemoteFile { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_name<S: IntoCStr>(&self, name: S) -> Result<(), ()> { + pub fn set_name(&self, name: &str) -> Result<(), ()> { let name = name.to_cstr(); let success = unsafe { BNRemoteFileSetName(self.handle.as_ptr(), name.as_ptr()) }; success.then_some(()).ok_or(()) @@ -199,7 +200,7 @@ impl RemoteFile { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_description<S: IntoCStr>(&self, description: S) -> Result<(), ()> { + pub fn set_description(&self, description: &str) -> Result<(), ()> { let description = description.to_cstr(); let success = unsafe { BNRemoteFileSetDescription(self.handle.as_ptr(), description.as_ptr()) }; @@ -249,7 +250,7 @@ impl RemoteFile { /// Get a specific Snapshot in the File by its id /// /// NOTE: If snapshots have not been pulled, they will be pulled upon calling this. - pub fn snapshot_by_id<S: IntoCStr>(&self, id: S) -> Result<Option<Ref<RemoteSnapshot>>, ()> { + pub fn snapshot_by_id(&self, id: &str) -> Result<Option<Ref<RemoteSnapshot>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_snapshots() { self.pull_snapshots()?; @@ -286,18 +287,16 @@ impl RemoteFile { /// * `analysis_cache_contents` - Contents of analysis cache of snapshot /// * `file` - New file contents (if contents changed) /// * `parent_ids` - List of ids of parent snapshots (or empty if this is a root snapshot) - pub fn create_snapshot<S, I>( + pub fn create_snapshot<I>( &self, - name: S, + name: &str, contents: &mut [u8], analysis_cache_contexts: &mut [u8], file: &mut [u8], parent_ids: I, ) -> Result<Ref<RemoteSnapshot>, ()> where - S: IntoCStr, - I: IntoIterator, - I::Item: IntoCStr, + I: IntoIterator<Item = String>, { self.create_snapshot_with_progress( name, @@ -317,9 +316,9 @@ impl RemoteFile { /// * `file` - New file contents (if contents changed) /// * `parent_ids` - List of ids of parent snapshots (or empty if this is a root snapshot) /// * `progress` - Function to call on progress updates - pub fn create_snapshot_with_progress<S, I, P>( + pub fn create_snapshot_with_progress<I, P>( &self, - name: S, + name: &str, contents: &mut [u8], analysis_cache_contexts: &mut [u8], file: &mut [u8], @@ -327,10 +326,8 @@ impl RemoteFile { mut progress: P, ) -> Result<Ref<RemoteSnapshot>, ()> where - S: IntoCStr, + I: IntoIterator<Item = String>, P: ProgressCallback, - I: IntoIterator, - I::Item: IntoCStr, { let name = name.to_cstr(); let parent_ids: Vec<_> = parent_ids.into_iter().map(|id| id.to_cstr()).collect(); @@ -403,10 +400,7 @@ impl RemoteFile { /// /// * `db_path` - File path for saved database /// * `progress_function` - Function to call for progress updates - pub fn download<S>(&self, db_path: S) -> Result<Ref<FileMetadata>, ()> - where - S: IntoCStr, - { + pub fn download(&self, db_path: &Path) -> Result<Ref<FileMetadata>, ()> { sync::download_file(self, db_path) } @@ -416,20 +410,19 @@ impl RemoteFile { /// /// * `db_path` - File path for saved database /// * `progress_function` - Function to call for progress updates - pub fn download_with_progress<S, F>( + pub fn download_with_progress<F>( &self, - db_path: S, + db_path: &Path, progress_function: F, ) -> Result<Ref<FileMetadata>, ()> where - S: IntoCStr, F: ProgressCallback, { sync::download_file_with_progress(self, db_path, progress_function) } /// Download a remote file and save it to a BNDB at the given `path`, returning the associated [`FileMetadata`]. - pub fn download_database<S: IntoCStr>(&self, path: S) -> Result<Ref<FileMetadata>, ()> { + pub fn download_database(&self, path: &Path) -> Result<Ref<FileMetadata>, ()> { let file = self.download(path)?; let database = file.database().ok_or(())?; self.sync(&database, DatabaseConflictHandlerFail, NoNameChangeset)?; @@ -437,11 +430,10 @@ impl RemoteFile { } // TODO: This might be a bad helper... maybe remove... - // TODO: AsRef<Path> /// Download a remote file and save it to a BNDB at the given `path`. - pub fn download_database_with_progress<S: IntoCStr>( + pub fn download_database_with_progress( &self, - path: S, + path: &Path, progress: impl ProgressCallback, ) -> Result<Ref<FileMetadata>, ()> { let mut progress = progress.split(&[50, 50]); diff --git a/rust/src/collaboration/folder.rs b/rust/src/collaboration/folder.rs index 35ff0788..797bcdd4 100644 --- a/rust/src/collaboration/folder.rs +++ b/rust/src/collaboration/folder.rs @@ -103,7 +103,7 @@ impl RemoteFolder { } /// Set the display name of the folder. You will need to push the folder to update the remote version. - pub fn set_name<S: IntoCStr>(&self, name: S) -> Result<(), ()> { + pub fn set_name(&self, name: &str) -> Result<(), ()> { let name = name.to_cstr(); let success = unsafe { BNRemoteFolderSetName(self.handle.as_ptr(), name.as_ptr()) }; success.then_some(()).ok_or(()) @@ -117,7 +117,7 @@ impl RemoteFolder { } /// Set the description of the folder. You will need to push the folder to update the remote version. - pub fn set_description<S: IntoCStr>(&self, description: S) -> Result<(), ()> { + pub fn set_description(&self, description: &str) -> Result<(), ()> { let description = description.to_cstr(); let success = unsafe { BNRemoteFolderSetDescription(self.handle.as_ptr(), description.as_ptr()) }; diff --git a/rust/src/collaboration/group.rs b/rust/src/collaboration/group.rs index 08efa079..01f92169 100644 --- a/rust/src/collaboration/group.rs +++ b/rust/src/collaboration/group.rs @@ -49,7 +49,7 @@ impl RemoteGroup { /// Set group name /// You will need to push the group to update the Remote. - pub fn set_name<U: IntoCStr>(&self, name: U) { + pub fn set_name(&self, name: &str) { let name = name.to_cstr(); unsafe { BNCollaborationGroupSetName(self.handle.as_ptr(), name.as_ptr()) } } @@ -83,8 +83,7 @@ impl RemoteGroup { /// You will need to push the group to update the Remote. pub fn set_users<I>(&self, usernames: I) -> Result<(), ()> where - I: IntoIterator, - I::Item: IntoCStr, + I: IntoIterator<Item = String>, { let usernames: Vec<_> = usernames.into_iter().map(|u| u.to_cstr()).collect(); let mut usernames_raw: Vec<_> = usernames.iter().map(|s| s.as_ptr()).collect(); @@ -102,7 +101,7 @@ impl RemoteGroup { } /// Test if a group has a user with the given username - pub fn contains_user<U: IntoCStr>(&self, username: U) -> bool { + pub fn contains_user(&self, username: &str) -> bool { let username = username.to_cstr(); unsafe { BNCollaborationGroupContainsUser(self.handle.as_ptr(), username.as_ptr()) } } diff --git a/rust/src/collaboration/merge.rs b/rust/src/collaboration/merge.rs index 9ebf4cda..aea11701 100644 --- a/rust/src/collaboration/merge.rs +++ b/rust/src/collaboration/merge.rs @@ -48,7 +48,7 @@ impl MergeConflict { NonNull::new(result).map(|handle| unsafe { Snapshot::from_raw(handle) }) } - pub fn path_item_string<S: IntoCStr>(&self, path: S) -> Result<BnString, ()> { + pub fn path_item_string(&self, path: &str) -> Result<BnString, ()> { let path = path.to_cstr(); let result = unsafe { BNAnalysisMergeConflictGetPathItemString(self.handle.as_ptr(), path.as_ptr()) @@ -119,7 +119,7 @@ impl MergeConflict { } /// Call this when you've resolved the conflict to save the result - pub fn success<S: IntoCStr>(&self, value: S) -> Result<(), ()> { + pub fn success(&self, value: &str) -> Result<(), ()> { let value = value.to_cstr(); let success = unsafe { BNAnalysisMergeConflictSuccess(self.handle.as_ptr(), value.as_ptr()) }; @@ -127,7 +127,7 @@ impl MergeConflict { } // TODO: Make a safe version of this that checks the path and if it holds a number - pub unsafe fn get_path_item_number<S: IntoCStr>(&self, path_key: S) -> Option<u64> { + pub unsafe fn get_path_item_number(&self, path_key: &str) -> Option<u64> { let path_key = path_key.to_cstr(); let value = unsafe { BNAnalysisMergeConflictGetPathItem(self.handle.as_ptr(), path_key.as_ptr()) }; @@ -138,7 +138,7 @@ impl MergeConflict { } } - pub unsafe fn get_path_item_string<S: IntoCStr>(&self, path_key: S) -> Option<BnString> { + pub unsafe fn get_path_item_string(&self, path_key: &str) -> Option<BnString> { let path_key = path_key.to_cstr(); let value = unsafe { BNAnalysisMergeConflictGetPathItemString(self.handle.as_ptr(), path_key.as_ptr()) diff --git a/rust/src/collaboration/project.rs b/rust/src/collaboration/project.rs index 3d34da9e..fa46e477 100644 --- a/rust/src/collaboration/project.rs +++ b/rust/src/collaboration/project.rs @@ -1,4 +1,5 @@ use std::ffi::c_void; +use std::path::PathBuf; use std::ptr::NonNull; use std::time::SystemTime; @@ -136,7 +137,7 @@ impl RemoteProject { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_name<S: IntoCStr>(&self, name: S) -> Result<(), ()> { + pub fn set_name(&self, name: &str) -> Result<(), ()> { let name = name.to_cstr(); let success = unsafe { BNRemoteProjectSetName(self.handle.as_ptr(), name.as_ptr()) }; success.then_some(()).ok_or(()) @@ -150,7 +151,7 @@ impl RemoteProject { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_description<S: IntoCStr>(&self, description: S) -> Result<(), ()> { + pub fn set_description(&self, description: &str) -> Result<(), ()> { let description = description.to_cstr(); let success = unsafe { BNRemoteProjectSetDescription(self.handle.as_ptr(), description.as_ptr()) }; @@ -169,7 +170,7 @@ impl RemoteProject { /// Get the default directory path for a remote Project. This is based off the Setting for /// collaboration.directory, the project's id, and the project's remote's id. - pub fn default_path(&self) -> Result<BnString, ()> { + pub fn default_path(&self) -> Result<PathBuf, ()> { sync::default_project_path(self) } @@ -221,7 +222,7 @@ 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<S: IntoCStr>(&self, id: S) -> Result<Option<Ref<RemoteFile>>, ()> { + pub fn get_file_by_id(&self, id: &str) -> Result<Option<Ref<RemoteFile>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_files() { self.pull_files()?; @@ -235,7 +236,7 @@ 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<S: IntoCStr>(&self, name: S) -> Result<Option<Ref<RemoteFile>>, ()> { + pub fn get_file_by_name(&self, name: &str) -> Result<Option<Ref<RemoteFile>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_files() { self.pull_files()?; @@ -282,20 +283,15 @@ impl RemoteProject { /// * `description` - File description /// * `parent_folder` - Folder that will contain the file /// * `file_type` - Type of File to create - pub fn create_file<F, N, D>( + pub fn create_file( &self, - filename: F, + filename: &str, contents: &[u8], - name: N, - description: D, + name: &str, + description: &str, parent_folder: Option<&RemoteFolder>, file_type: RemoteFileType, - ) -> Result<Ref<RemoteFile>, ()> - where - F: IntoCStr, - N: IntoCStr, - D: IntoCStr, - { + ) -> Result<Ref<RemoteFile>, ()> { self.create_file_with_progress( filename, contents, @@ -318,20 +314,17 @@ impl RemoteProject { /// * `parent_folder` - Folder that will contain the file /// * `file_type` - Type of File to create /// * `progress` - Function to call on upload progress updates - pub fn create_file_with_progress<F, N, D, P>( + pub fn create_file_with_progress<P>( &self, - filename: F, + filename: &str, contents: &[u8], - name: N, - description: D, + name: &str, + description: &str, parent_folder: Option<&RemoteFolder>, file_type: RemoteFileType, mut progress: P, ) -> Result<Ref<RemoteFile>, ()> where - F: IntoCStr, - N: IntoCStr, - D: IntoCStr, P: ProgressCallback, { // TODO: This sync should be removed? @@ -364,11 +357,9 @@ impl RemoteProject { /// Push an updated File object to the Remote /// /// NOTE: If the project has not been opened, it will be opened upon calling this. - pub fn push_file<I, K, V>(&self, file: &RemoteFile, extra_fields: I) -> Result<(), ()> + pub fn push_file<I>(&self, file: &RemoteFile, extra_fields: I) -> Result<(), ()> where - I: Iterator<Item = (K, V)>, - K: IntoCStr, - V: IntoCStr, + I: IntoIterator<Item = (String, String)>, { // TODO: This sync should be removed? self.open()?; @@ -421,7 +412,7 @@ 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<S: IntoCStr>(&self, id: S) -> Result<Option<Ref<RemoteFolder>>, ()> { + pub fn get_folder_by_id(&self, id: &str) -> Result<Option<Ref<RemoteFolder>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_folders() { self.pull_folders()?; @@ -465,16 +456,12 @@ impl RemoteProject { /// * `name` - Displayed folder name /// * `description` - Folder description /// * `parent` - Parent folder (optional) - pub fn create_folder<N, D>( + pub fn create_folder( &self, - name: N, - description: D, + name: &str, + description: &str, parent_folder: Option<&RemoteFolder>, - ) -> Result<Ref<RemoteFolder>, ()> - where - N: IntoCStr, - D: IntoCStr, - { + ) -> Result<Ref<RemoteFolder>, ()> { self.create_folder_with_progress(name, description, parent_folder, NoProgressCallback) } @@ -486,16 +473,14 @@ impl RemoteProject { /// * `description` - Folder description /// * `parent` - Parent folder (optional) /// * `progress` - Function to call on upload progress updates - pub fn create_folder_with_progress<N, D, P>( + pub fn create_folder_with_progress<P>( &self, - name: N, - description: D, + name: &str, + description: &str, parent_folder: Option<&RemoteFolder>, mut progress: P, ) -> Result<Ref<RemoteFolder>, ()> where - N: IntoCStr, - D: IntoCStr, P: ProgressCallback, { // TODO: This sync should be removed? @@ -526,11 +511,9 @@ impl RemoteProject { /// /// * `folder` - Folder object which has been updated /// * `extra_fields` - Extra HTTP fields to send with the update - pub fn push_folder<I, K, V>(&self, folder: &RemoteFolder, extra_fields: I) -> Result<(), ()> + pub fn push_folder<I>(&self, folder: &RemoteFolder, extra_fields: I) -> Result<(), ()> where - I: Iterator<Item = (K, V)>, - K: IntoCStr, - V: IntoCStr, + I: IntoIterator<Item = (String, String)>, { // TODO: This sync should be removed? self.open()?; @@ -598,7 +581,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<S: IntoCStr>(&self, id: S) -> Result<Option<Ref<Permission>>, ()> { + pub fn get_permission_by_id(&self, id: &str) -> Result<Option<Ref<Permission>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_user_permissions() { self.pull_user_permissions()?; @@ -703,9 +686,9 @@ impl RemoteProject { /// /// * `user_id` - User id /// * `level` - Permission level - pub fn create_user_permission<S: IntoCStr>( + pub fn create_user_permission( &self, - user_id: S, + user_id: &str, level: CollaborationPermissionLevel, ) -> Result<Ref<Permission>, ()> { self.create_user_permission_with_progress(user_id, level, NoProgressCallback) @@ -718,9 +701,9 @@ impl RemoteProject { /// * `user_id` - User id /// * `level` - Permission level /// * `progress` - The progress callback to call - pub fn create_user_permission_with_progress<S: IntoCStr, F: ProgressCallback>( + pub fn create_user_permission_with_progress<F: ProgressCallback>( &self, - user_id: S, + user_id: &str, level: CollaborationPermissionLevel, mut progress: F, ) -> Result<Ref<Permission>, ()> { @@ -746,15 +729,9 @@ impl RemoteProject { /// /// * `permission` - Permission object which has been updated /// * `extra_fields` - Extra HTTP fields to send with the update - pub fn push_permission<I, K, V>( - &self, - permission: &Permission, - extra_fields: I, - ) -> Result<(), ()> + pub fn push_permission<I>(&self, permission: &Permission, extra_fields: I) -> Result<(), ()> where - I: Iterator<Item = (K, V)>, - K: IntoCStr, - V: IntoCStr, + I: IntoIterator<Item = (String, String)>, { let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() @@ -788,7 +765,7 @@ impl RemoteProject { /// # Arguments /// /// * `username` - Username of user to check - pub fn can_user_view<S: IntoCStr>(&self, username: S) -> bool { + pub fn can_user_view(&self, username: &str) -> bool { let username = username.to_cstr(); unsafe { BNRemoteProjectCanUserView(self.handle.as_ptr(), username.as_ptr()) } } @@ -798,7 +775,7 @@ impl RemoteProject { /// # Arguments /// /// * `username` - Username of user to check - pub fn can_user_edit<S: IntoCStr>(&self, username: S) -> bool { + pub fn can_user_edit(&self, username: &str) -> bool { let username = username.to_cstr(); unsafe { BNRemoteProjectCanUserEdit(self.handle.as_ptr(), username.as_ptr()) } } @@ -808,7 +785,7 @@ impl RemoteProject { /// # Arguments /// /// * `username` - Username of user to check - pub fn can_user_admin<S: IntoCStr>(&self, username: S) -> bool { + pub fn can_user_admin(&self, username: &str) -> bool { let username = username.to_cstr(); unsafe { BNRemoteProjectCanUserAdmin(self.handle.as_ptr(), username.as_ptr()) } } diff --git a/rust/src/collaboration/remote.rs b/rust/src/collaboration/remote.rs index baeba412..7b5828ef 100644 --- a/rust/src/collaboration/remote.rs +++ b/rust/src/collaboration/remote.rs @@ -27,7 +27,7 @@ impl Remote { } /// Create a Remote and add it to the list of known remotes (saved to Settings) - pub fn new<N: IntoCStr, A: IntoCStr>(name: N, address: A) -> Ref<Self> { + pub fn new(name: &str, address: &str) -> Ref<Self> { let name = name.to_cstr(); let address = address.to_cstr(); let result = unsafe { BNCollaborationCreateRemote(name.as_ptr(), address.as_ptr()) }; @@ -163,11 +163,7 @@ impl Remote { } /// Requests an authentication token using a username and password. - pub fn request_authentication_token<U: IntoCStr, P: IntoCStr>( - &self, - username: U, - password: P, - ) -> Option<String> { + pub fn request_authentication_token(&self, username: &str, password: &str) -> Option<String> { let username = username.to_cstr(); let password = password.to_cstr(); let token = unsafe { @@ -219,7 +215,7 @@ impl Remote { let password = options .password .expect("No password or token for connection!"); - let token = self.request_authentication_token(&options.username, password); + let token = self.request_authentication_token(&options.username, &password); // TODO: Error if None. token.unwrap().to_string() } @@ -275,7 +271,7 @@ impl Remote { /// Gets a specific project in the Remote by its id. /// /// NOTE: If projects have not been pulled, they will be pulled upon calling this. - pub fn get_project_by_id<S: IntoCStr>(&self, id: S) -> Result<Option<Ref<RemoteProject>>, ()> { + pub fn get_project_by_id(&self, id: &str) -> Result<Option<Ref<RemoteProject>>, ()> { if !self.has_pulled_projects() { self.pull_projects()?; } @@ -288,10 +284,7 @@ impl Remote { /// Gets a specific project in the Remote by its name. /// /// NOTE: If projects have not been pulled, they will be pulled upon calling this. - pub fn get_project_by_name<S: IntoCStr>( - &self, - name: S, - ) -> Result<Option<Ref<RemoteProject>>, ()> { + pub fn get_project_by_name(&self, name: &str) -> Result<Option<Ref<RemoteProject>>, ()> { if !self.has_pulled_projects() { self.pull_projects()?; } @@ -331,11 +324,7 @@ impl Remote { /// /// * `name` - Project name /// * `description` - Project description - pub fn create_project<N: IntoCStr, D: IntoCStr>( - &self, - name: N, - description: D, - ) -> Result<Ref<RemoteProject>, ()> { + pub fn create_project(&self, name: &str, description: &str) -> Result<Ref<RemoteProject>, ()> { // TODO: Do we want this? // TODO: If you have not yet pulled projects you will have never filled the map you will be placing your // TODO: New project in. @@ -380,11 +369,9 @@ impl Remote { /// /// * `project` - Project object which has been updated /// * `extra_fields` - Extra HTTP fields to send with the update - pub fn push_project<I, K, V>(&self, project: &RemoteProject, extra_fields: I) -> Result<(), ()> + pub fn push_project<I>(&self, project: &RemoteProject, extra_fields: I) -> Result<(), ()> where - I: Iterator<Item = (K, V)>, - K: IntoCStr, - V: IntoCStr, + I: IntoIterator<Item = (String, String)>, { let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() @@ -446,7 +433,7 @@ impl Remote { /// /// If groups have not been pulled, they will be pulled upon calling this. /// This function is only available to accounts with admin status on the Remote. - pub fn get_group_by_name<S: IntoCStr>(&self, name: S) -> Result<Option<Ref<RemoteGroup>>, ()> { + pub fn get_group_by_name(&self, name: &str) -> Result<Option<Ref<RemoteGroup>>, ()> { if !self.has_pulled_groups() { self.pull_groups()?; } @@ -462,10 +449,7 @@ impl Remote { /// # Arguments /// /// * `prefix` - Prefix of name for groups - pub fn search_groups<S: IntoCStr>( - &self, - prefix: S, - ) -> Result<(Array<GroupId>, Array<BnString>), ()> { + pub fn search_groups(&self, prefix: &str) -> Result<(Array<GroupId>, Array<BnString>), ()> { let prefix = prefix.to_cstr(); let mut count = 0; let mut group_ids = std::ptr::null_mut(); @@ -524,11 +508,9 @@ impl Remote { /// /// * `name` - Group name /// * `usernames` - List of usernames of users in the group - pub fn create_group<N, I>(&self, name: N, usernames: I) -> Result<Ref<RemoteGroup>, ()> + pub fn create_group<I>(&self, name: &str, usernames: I) -> Result<Ref<RemoteGroup>, ()> where - N: IntoCStr, - I: IntoIterator, - I::Item: IntoCStr, + I: IntoIterator<Item = String>, { let name = name.to_cstr(); let usernames: Vec<_> = usernames.into_iter().map(|s| s.to_cstr()).collect(); @@ -554,11 +536,9 @@ impl Remote { /// /// * `group` - Group object which has been updated /// * `extra_fields` - Extra HTTP fields to send with the update - pub fn push_group<I, K, V>(&self, group: &RemoteGroup, extra_fields: I) -> Result<(), ()> + pub fn push_group<I>(&self, group: &RemoteGroup, extra_fields: I) -> Result<(), ()> where - I: IntoIterator<Item = (K, V)>, - K: IntoCStr, - V: IntoCStr, + I: IntoIterator<Item = (String, String)>, { let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() @@ -617,7 +597,7 @@ impl Remote { /// # Arguments /// /// * `id` - The identifier of the user to retrieve. - pub fn get_user_by_id<S: IntoCStr>(&self, id: S) -> Result<Option<Ref<RemoteUser>>, ()> { + pub fn get_user_by_id(&self, id: &str) -> Result<Option<Ref<RemoteUser>>, ()> { if !self.has_pulled_users() { self.pull_users()?; } @@ -635,10 +615,7 @@ impl Remote { /// # Arguments /// /// * `username` - The username of the user to retrieve. - pub fn get_user_by_username<S: IntoCStr>( - &self, - username: S, - ) -> Result<Option<Ref<RemoteUser>>, ()> { + pub fn get_user_by_username(&self, username: &str) -> Result<Option<Ref<RemoteUser>>, ()> { if !self.has_pulled_users() { self.pull_users()?; } @@ -665,10 +642,7 @@ impl Remote { /// # Arguments /// /// * `prefix` - The prefix to search for in usernames. - pub fn search_users<S: IntoCStr>( - &self, - prefix: S, - ) -> Result<(Array<BnString>, Array<BnString>), ()> { + pub fn search_users(&self, prefix: &str) -> Result<(Array<BnString>, Array<BnString>), ()> { let prefix = prefix.to_cstr(); let mut count = 0; let mut user_ids = std::ptr::null_mut(); @@ -730,12 +704,12 @@ impl Remote { /// # Arguments /// /// * Various details about the new user to be created. - pub fn create_user<U: IntoCStr, E: IntoCStr, P: IntoCStr>( + pub fn create_user( &self, - username: U, - email: E, + username: &str, + email: &str, is_active: bool, - password: P, + password: &str, group_ids: &[u64], user_permission_ids: &[u64], ) -> Result<Ref<RemoteUser>, ()> { @@ -769,11 +743,9 @@ impl Remote { /// /// * `user` - Reference to the `RemoteUser` object to push. /// * `extra_fields` - Optional extra fields to send with the update. - pub fn push_user<I, K, V>(&self, user: &RemoteUser, extra_fields: I) -> Result<(), ()> + pub fn push_user<I>(&self, user: &RemoteUser, extra_fields: I) -> Result<(), ()> where - I: Iterator<Item = (K, V)>, - K: IntoCStr, - V: IntoCStr, + I: IntoIterator<Item = (String, String)>, { let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() diff --git a/rust/src/collaboration/snapshot.rs b/rust/src/collaboration/snapshot.rs index c8256608..203d8677 100644 --- a/rust/src/collaboration/snapshot.rs +++ b/rust/src/collaboration/snapshot.rs @@ -226,10 +226,10 @@ impl RemoteSnapshot { } /// Create a new Undo Entry in this snapshot. - pub fn create_undo_entry<S: IntoCStr>( + pub fn create_undo_entry( &self, parent: Option<u64>, - data: S, + data: &str, ) -> Result<Ref<RemoteUndoEntry>, ()> { let data = data.to_cstr(); let value = unsafe { diff --git a/rust/src/collaboration/sync.rs b/rust/src/collaboration/sync.rs index b1b26982..a8006b8b 100644 --- a/rust/src/collaboration/sync.rs +++ b/rust/src/collaboration/sync.rs @@ -3,6 +3,7 @@ use super::{ }; use binaryninjacore_sys::*; use std::ffi::{c_char, c_void}; +use std::path::{Path, PathBuf}; use std::ptr::NonNull; use crate::binary_view::{BinaryView, BinaryViewExt}; @@ -14,49 +15,45 @@ use crate::rc::Ref; use crate::string::{raw_to_string, BnString, IntoCStr}; use crate::type_archive::{TypeArchive, TypeArchiveMergeConflict}; -// TODO: PathBuf /// Get the default directory path for a remote Project. This is based off the Setting for /// collaboration.directory, the project's id, and the project's remote's id. -pub fn default_project_path(project: &RemoteProject) -> Result<BnString, ()> { +pub fn default_project_path(project: &RemoteProject) -> Result<PathBuf, ()> { let result = unsafe { BNCollaborationDefaultProjectPath(project.handle.as_ptr()) }; let success = !result.is_null(); success - .then(|| unsafe { BnString::from_raw(result) }) + .then(|| PathBuf::from(unsafe { BnString::into_string(result) })) .ok_or(()) } -// TODO: PathBuf // Get the default filepath for a remote File. This is based off the Setting for // collaboration.directory, the file's id, the file's project's id, and the file's // remote's id. -pub fn default_file_path(file: &RemoteFile) -> Result<BnString, ()> { +pub fn default_file_path(file: &RemoteFile) -> Result<PathBuf, ()> { let result = unsafe { BNCollaborationDefaultFilePath(file.handle.as_ptr()) }; let success = !result.is_null(); success - .then(|| unsafe { BnString::from_raw(result) }) + .then(|| PathBuf::from(unsafe { BnString::into_string(result) })) .ok_or(()) } -// TODO: AsRef<Path> /// Download a file from its remote, saving all snapshots to a database in the /// specified location. Returns a FileContext for opening the file later. /// /// * `file` - Remote File to download and open /// * `db_path` - File path for saved database -pub fn download_file<S: IntoCStr>(file: &RemoteFile, db_path: S) -> Result<Ref<FileMetadata>, ()> { +pub fn download_file(file: &RemoteFile, db_path: &Path) -> Result<Ref<FileMetadata>, ()> { download_file_with_progress(file, db_path, NoProgressCallback) } -// TODO: AsRef<Path> /// Download a file from its remote, saving all snapshots to a database in the /// specified location. Returns a FileContext for opening the file later. /// /// * `file` - Remote File to download and open /// * `db_path` - File path for saved database /// * `progress` - Function to call for progress updates -pub fn download_file_with_progress<S: IntoCStr, F: ProgressCallback>( +pub fn download_file_with_progress<F: ProgressCallback>( file: &RemoteFile, - db_path: S, + db_path: &Path, mut progress: F, ) -> Result<Ref<FileMetadata>, ()> { let db_path = db_path.to_cstr(); @@ -218,22 +215,18 @@ pub fn get_local_snapshot_for_remote( .ok_or(()) } -pub fn download_database<S>(file: &RemoteFile, location: S, force: bool) -> Result<(), ()> -where - S: IntoCStr, -{ +pub fn download_database<S>(file: &RemoteFile, location: &Path, force: bool) -> Result<(), ()> { download_database_with_progress(file, location, force, NoProgressCallback) } -pub fn download_database_with_progress<S, F>( +pub fn download_database_with_progress<PC>( file: &RemoteFile, - location: S, + location: &Path, force: bool, - mut progress: F, + mut progress: PC, ) -> Result<(), ()> where - S: IntoCStr, - F: ProgressCallback, + PC: ProgressCallback, { let db_path = location.to_cstr(); let success = unsafe { @@ -241,8 +234,8 @@ where file.handle.as_ptr(), db_path.as_ptr(), force, - Some(F::cb_progress_callback), - &mut progress as *mut _ as *mut c_void, + Some(PC::cb_progress_callback), + &mut progress as *mut PC as *mut c_void, ) }; success.then_some(()).ok_or(()) @@ -475,10 +468,10 @@ pub fn get_snapshot_author( /// * `database` - Parent database /// * `snapshot` - Snapshot to edit /// * `author` - Target author -pub fn set_snapshot_author<S: IntoCStr>( +pub fn set_snapshot_author( database: &Database, snapshot: &Snapshot, - author: S, + author: &str, ) -> Result<(), ()> { let author = author.to_cstr(); let success = unsafe { @@ -650,9 +643,9 @@ pub fn get_remote_file_for_local_type_archive(database: &TypeArchive) -> Option< } /// Get the remote snapshot associated with a local snapshot (if it exists) in a Type Archive -pub fn get_remote_snapshot_from_local_type_archive<S: IntoCStr>( +pub fn get_remote_snapshot_from_local_type_archive( type_archive: &TypeArchive, - snapshot_id: S, + snapshot_id: &str, ) -> Option<Ref<RemoteSnapshot>> { let snapshot_id = snapshot_id.to_cstr(); let value = unsafe { @@ -679,10 +672,7 @@ pub fn get_local_snapshot_from_remote_type_archive( } /// Test if a snapshot is ignored from the archive -pub fn is_type_archive_snapshot_ignored<S: IntoCStr>( - type_archive: &TypeArchive, - snapshot_id: S, -) -> bool { +pub fn is_type_archive_snapshot_ignored(type_archive: &TypeArchive, snapshot_id: &str) -> bool { let snapshot_id = snapshot_id.to_cstr(); unsafe { BNCollaborationIsTypeArchiveSnapshotIgnored( @@ -694,19 +684,19 @@ pub fn is_type_archive_snapshot_ignored<S: IntoCStr>( /// Download a type archive from its remote, saving all snapshots to an archive in the /// specified `location`. Returns a [`TypeArchive`] for using later. -pub fn download_type_archive<S: IntoCStr>( +pub fn download_type_archive( file: &RemoteFile, - location: S, + location: &Path, ) -> Result<Option<Ref<TypeArchive>>, ()> { download_type_archive_with_progress(file, location, NoProgressCallback) } /// Download a type archive from its remote, saving all snapshots to an archive in the /// specified `location`. Returns a [`TypeArchive`] for using later. -pub fn download_type_archive_with_progress<S: IntoCStr, F: ProgressCallback>( +pub fn download_type_archive_with_progress<PC: ProgressCallback>( file: &RemoteFile, - location: S, - mut progress: F, + location: &Path, + mut progress: PC, ) -> Result<Option<Ref<TypeArchive>>, ()> { let mut value = std::ptr::null_mut(); let db_path = location.to_cstr(); @@ -714,8 +704,8 @@ pub fn download_type_archive_with_progress<S: IntoCStr, F: ProgressCallback>( BNCollaborationDownloadTypeArchive( file.handle.as_ptr(), db_path.as_ptr(), - Some(F::cb_progress_callback), - &mut progress as *mut F as *mut c_void, + Some(PC::cb_progress_callback), + &mut progress as *mut PC as *mut c_void, &mut value, ) }; diff --git a/rust/src/collaboration/user.rs b/rust/src/collaboration/user.rs index 6b490942..51bdebb5 100644 --- a/rust/src/collaboration/user.rs +++ b/rust/src/collaboration/user.rs @@ -48,7 +48,7 @@ impl RemoteUser { } /// Set user's username. You will need to push the user to update the Remote - pub fn set_username<U: IntoCStr>(&self, username: U) -> Result<(), ()> { + pub fn set_username(&self, username: &str) -> Result<(), ()> { let username = username.to_cstr(); let result = unsafe { BNCollaborationUserSetUsername(self.handle.as_ptr(), username.as_ptr()) }; @@ -67,7 +67,7 @@ impl RemoteUser { } /// Set user's email. You will need to push the user to update the Remote - pub fn set_email<U: IntoCStr>(&self, email: U) -> Result<(), ()> { + pub fn set_email(&self, email: &str) -> Result<(), ()> { let username = email.to_cstr(); let result = unsafe { BNCollaborationUserSetEmail(self.handle.as_ptr(), username.as_ptr()) }; |
