diff --git a/Cargo.toml b/Cargo.toml index 0ad56d3..90cbcfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,14 @@ [package] name = "libczirw-sys" -version = "0.2.1" +version = "0.3.0" edition = "2024" rust-version = "1.85.1" authors = ["Wim Pomp "] license = "MIT" description = "Wrapper around libCZIAPI" -homepage = "https://github.com/wimpomp/libczirw-sys" -repository = "https://github.com/wimpomp/libczirw-sys" +homepage = "https://git.wimpomp.nl/wim/libczirw-sys" +repository = "https://git.wimpomp.nl/wim/libczirw-sys" +documentation = "https://docs.rs/libczirw-sys" readme = "README.md" keywords = ["czi", "zeiss", "libczi"] categories = ["multimedia::images", "science"] @@ -15,14 +16,13 @@ links = "libCZIAPI" exclude = ["test-files/*", "**/*UnitTests"] [dependencies] -anyhow = "1.0.98" link-cplusplus = "1.0" +thiserror = "2" [build-dependencies] -anyhow = "1.0.98" -bindgen = "0.72.0" -cmake = "0.1.54" -regex = "1.11.1" +bindgen = "0.72" +cmake = "0.1" +regex = "1" [features] dynamic = [] \ No newline at end of file diff --git a/build.rs b/build.rs index e2ece49..664da9e 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,5 @@ extern crate bindgen; -use anyhow::{Error, Result}; use std::env; use std::path::PathBuf; @@ -10,15 +9,36 @@ use std::fmt::Debug; #[cfg(not(feature = "dynamic"))] use bindgen::callbacks::ItemInfo; -#[cfg(not(feature = "dynamic"))] -use std::collections::HashMap; - #[cfg(not(feature = "dynamic"))] use regex::Regex; +#[cfg(not(feature = "dynamic"))] +use std::collections::HashMap; +use std::fmt::{Display, Formatter}; -fn main() -> Result<()> { +struct Error(String); + +impl Debug for Error { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.0) + } +} + +impl Display for Error { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.0) + } +} + +impl std::error::Error for Error {} + +impl Error { + fn msg(msg: S) -> Box { + Box::new(Error(msg.to_string())) + } +} + +fn main() -> Result<(), Box> { if env::var("DOCS_RS").is_err() { - let out_dir = PathBuf::from(env::var("OUT_DIR")?).canonicalize()?; let libczi_dir = PathBuf::from("libczi"); let libczi_src = libczi_dir.join("Src/libCZI"); let libcziapi_inc = libczi_dir.join("Src/libCZIAPI/inc"); @@ -41,9 +61,9 @@ fn main() -> Result<()> { #[cfg(not(feature = "dynamic"))] let bindings = { - let mut libcziapi_a = out_dir.join("build/Src/libCZIAPI/liblibCZIAPIStatic.a"); + let mut libcziapi_a = dst.join("build/Src/libCZIAPI/liblibCZIAPIStatic.a"); if !libcziapi_a.exists() { - libcziapi_a = out_dir.join("build/Src/libCZIAPI/liblibCZIAPIStatic.lib"); + libcziapi_a = dst.join("build/Src/libCZIAPI/liblibCZIAPIStatic.lib"); } bindgen::Builder::default().parse_callbacks(Box::new(DeMangler::new(libcziapi_a)?)) }; @@ -78,7 +98,7 @@ fn main() -> Result<()> { ) .generate()?; - bindings.write_to_file(out_dir.join("lib_czi_api.rs"))?; + bindings.write_to_file(dst.join("lib_czi_api.rs"))?; #[cfg(not(feature = "dynamic"))] { @@ -131,7 +151,7 @@ struct DeMangler { #[cfg(not(feature = "dynamic"))] impl DeMangler { - fn new(a_file: PathBuf) -> Result { + fn new(a_file: PathBuf) -> Result> { let cmd = std::process::Command::new("nm").arg(&a_file).output()?; let pat = Regex::new(r"^[\da-f]*\s[A-Z]\s(.*_Z(\d+)(libCZI_.*))$")?; let mut map = HashMap::new(); diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..73ef3cd --- /dev/null +++ b/src/error.rs @@ -0,0 +1,36 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Error { + #[error(transparent)] + Utf8(#[from] std::str::Utf8Error), + #[error(transparent)] + FromUtf8(#[from] std::string::FromUtf8Error), + #[error(transparent)] + FromBytesUntilNull(#[from] std::ffi::FromBytesUntilNulError), + #[error(transparent)] + Nul(#[from] std::ffi::NulError), + + #[error("LibCZIAPI Ok")] + LibCziApiOK, + #[error("LibCZIAPI invalid argument")] + LibCziApiInvalidArgument, + #[error("LibCZIAPI invalid handle")] + LibCziApiInvalidHandle, + #[error("LibCZIAPI out of memory")] + LibCziApiOutOfMemory, + #[error("LibCZIAPI index out of range")] + LibCziApiIndexOutOfRange, + #[error("LibCZIAPI lock-unlock semantic violated")] + LibCziApiLockUnlockSemanticViolated, + #[error("LibCZIAPI unspecified error")] + LibCziApiUnspecifiedError, + #[error("LibCZIAPI unknown error code: {0}")] + LibCziApiUnknownError(usize), + #[error("Unknown dimension: {0}")] + UnknownDimension(String), + #[error("Unknown data type: {0}")] + UnknownDataType(i32), + #[error("Unknown pixel type: {0}")] + UnknownPixelType(i32), +} diff --git a/src/functions.rs b/src/functions.rs index 8c93cec..bcc4798 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -1,8 +1,8 @@ +use crate::error::Error; use crate::handle::*; use crate::interop::*; use crate::misc::*; use crate::sys::*; -use anyhow::{Error, Result}; use std::ffi::{CStr, CString, c_char, c_int, c_ulong, c_void}; use std::mem::{ManuallyDrop, MaybeUninit}; use std::ops::Deref; @@ -22,10 +22,10 @@ pub fn free(data: T) { /// \\param \[out\] data If successful, a pointer to the allocated memory is put here. The memory must be freed using 'libCZI_Free'. /// /// \\returns An error-code indicating success or failure of the operation. -pub fn allocate_memory(size: usize) -> Result> { +pub fn allocate_memory(size: usize) -> Result, Error> { let mut data = MaybeUninit::::uninit(); let mut ptr = data.as_mut_ptr() as *mut c_void; - LibCZIApiError::try_from(unsafe { libCZI_AllocateMemory(size as c_ulong, &mut ptr) })?; + lib_czi_error(unsafe { libCZI_AllocateMemory(size as c_ulong, &mut ptr) })?; Ok(data) } @@ -35,10 +35,10 @@ impl LibCZIVersionInfo { /// \\param \[out\] version_info If successful, the version information is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_lib_czi_version_info() -> Result { + pub fn get_lib_czi_version_info() -> Result { let mut version_info = MaybeUninit::uninit(); let ptr = version_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_GetLibCZIVersionInfo(ptr) })?; + lib_czi_error(unsafe { libCZI_GetLibCZIVersionInfo(ptr) })?; Ok(unsafe { LibCZIVersionInfo::assume_init(version_info) }) } } @@ -49,10 +49,10 @@ impl LibCZIBuildInformation { /// \\param \[out\] build_info If successful, the build information is put here. Note that all strings must be freed by the caller (using 'libCZI_Free'). /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get() -> Result { + pub fn get() -> Result { let mut build_info = MaybeUninit::uninit(); let ptr = build_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_GetLibCZIBuildInformation(ptr) })?; + lib_czi_error(unsafe { libCZI_GetLibCZIBuildInformation(ptr) })?; Ok(unsafe { LibCZIBuildInformation::assume_init(build_info) }) } } @@ -63,10 +63,10 @@ impl CziReader { /// \\param \[out\] reader_object If the operation is successful, a handle to the newly created reader object is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn create() -> Result { + pub fn create() -> Result { let mut reader = MaybeUninit::uninit(); let ptr = reader.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_CreateReader(ptr) })?; + lib_czi_error(unsafe { libCZI_CreateReader(ptr) })?; Ok(unsafe { Self::assume_init(reader) }) } @@ -77,8 +77,8 @@ impl CziReader { /// \\param open_info Parameters controlling the operation. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn open(&self, open_info: ReaderOpenInfo) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReaderOpen(**self, open_info.as_ptr()) })?; + pub fn open(&self, open_info: ReaderOpenInfo) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReaderOpen(**self, open_info.as_ptr()) })?; Ok(()) } @@ -89,10 +89,10 @@ impl CziReader { /// \\param \[out\] file_header_info_interop If successful, the retrieved information is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_file_header_info(&self) -> Result { + pub fn get_file_header_info(&self) -> Result { let mut file_header_info = MaybeUninit::uninit(); let ptr = file_header_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_ReaderGetFileHeaderInfo(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_ReaderGetFileHeaderInfo(**self, ptr) })?; Ok(unsafe { FileHeaderInfo::assume_init(file_header_info) }) } @@ -105,12 +105,10 @@ impl CziReader { /// \\param \[out\] sub_block_object If successful, a handle to the sub-block object is put here; otherwise 'kInvalidObjectHandle'. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn read_sub_block(&self, index: i32) -> Result { + pub fn read_sub_block(&self, index: i32) -> Result { let mut sub_block = MaybeUninit::uninit(); let ptr = sub_block.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { - libCZI_ReaderReadSubBlock(**self, index as c_int, ptr) - })?; + lib_czi_error(unsafe { libCZI_ReaderReadSubBlock(**self, index as c_int, ptr) })?; Ok(unsafe { SubBlock::assume_init(sub_block) }) } @@ -121,10 +119,10 @@ impl CziReader { /// \\param \[out\] statistics If non-null, the simple statistics will be put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_statistics_simple(&self) -> Result { + pub fn get_statistics_simple(&self) -> Result { let mut statistics = MaybeUninit::uninit(); let ptr = statistics.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_ReaderGetStatisticsSimple(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_ReaderGetStatisticsSimple(**self, ptr) })?; Ok(unsafe { SubBlockStatistics::assume_init(statistics) }) } @@ -151,12 +149,12 @@ impl CziReader { pub fn get_statistics_ex( &self, number_of_per_channel_bounding_boxes: i32, - ) -> Result<(SubBlockStatisticsEx, i32)> { + ) -> Result<(SubBlockStatisticsEx, i32), Error> { let mut statistics = MaybeUninit::uninit(); let ptr = statistics.as_mut_ptr(); let number_of_per_channel_bounding_boxes = Box::into_raw(Box::new(number_of_per_channel_bounding_boxes)); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_ReaderGetStatisticsEx(**self, ptr, number_of_per_channel_bounding_boxes) })?; Ok(unsafe { @@ -190,11 +188,9 @@ impl CziReader { /// is responsible for freeing this memory (by calling libCZI_Free). /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_pyramid_statistics(&self) -> Result { + pub fn get_pyramid_statistics(&self) -> Result { let mut ptr = MaybeUninit::<*mut c_char>::uninit(); - LibCZIApiError::try_from(unsafe { - libCZI_ReaderGetPyramidStatistics(**self, ptr.as_mut_ptr()) - })?; + lib_czi_error(unsafe { libCZI_ReaderGetPyramidStatistics(**self, ptr.as_mut_ptr()) })?; let ptr = unsafe { ptr.assume_init() }; assert!(!ptr.is_null()); let statistics = unsafe { CStr::from_ptr(ptr) } @@ -210,10 +206,10 @@ impl CziReader { /// \\param \[out\] metadata_segment_object If successful, a handle to the metadata-segment object is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_metadata_segment(&self) -> Result { + pub fn get_metadata_segment(&self) -> Result { let mut metadata_segment = MaybeUninit::uninit(); let ptr = metadata_segment.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_ReaderGetMetadataSegment(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_ReaderGetMetadataSegment(**self, ptr) })?; Ok(unsafe { MetadataSegment::assume_init(metadata_segment) }) } @@ -222,11 +218,9 @@ impl CziReader { /// \\param reader_object The reader object. /// \\param \[out\] count The number of available attachments is put here. /// \\returns An error-code indicating success or failure of the operation. - pub fn get_attachment_count(&self) -> Result { + pub fn get_attachment_count(&self) -> Result { let mut count = MaybeUninit::::uninit(); - LibCZIApiError::try_from(unsafe { - libCZI_ReaderGetAttachmentCount(**self, count.as_mut_ptr()) - })?; + lib_czi_error(unsafe { libCZI_ReaderGetAttachmentCount(**self, count.as_mut_ptr()) })?; Ok(unsafe { count.assume_init() }) } @@ -238,12 +232,10 @@ impl CziReader { /// \\param \[out\] attachment_info_interop If successful, the retrieved information is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_attachment_info_from_directory(&self, index: i32) -> Result { + pub fn get_attachment_info_from_directory(&self, index: i32) -> Result { let mut attachment_info = MaybeUninit::uninit(); let ptr = attachment_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { - libCZI_ReaderGetAttachmentInfoFromDirectory(**self, index, ptr) - })?; + lib_czi_error(unsafe { libCZI_ReaderGetAttachmentInfoFromDirectory(**self, index, ptr) })?; Ok(unsafe { AttachmentInfo::assume_init(attachment_info) }) } @@ -254,10 +246,10 @@ impl CziReader { /// \\param \[out\] attachment_object If successful and index is valid, a handle representing the attachment object is put here. If the index is /// invalid, then the handle will have the value 'kInvalidObjectHandle'. /// \\returns An error-code indicating success or failure of the operation. - pub fn read_attachment(&self, index: i32) -> Result { + pub fn read_attachment(&self, index: i32) -> Result { let mut attachment = MaybeUninit::uninit(); let ptr = attachment.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_ReaderReadAttachment(**self, index, ptr) })?; + lib_czi_error(unsafe { libCZI_ReaderReadAttachment(**self, index, ptr) })?; Ok(unsafe { Attachment::assume_init(attachment) }) } @@ -267,8 +259,8 @@ impl CziReader { /// \\param reader_object The reader object. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseReader(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseReader(**self) })?; Ok(()) } @@ -280,10 +272,10 @@ impl CziReader { /// \\param \[out\] sub_block_info_interop If successful, the retrieved information is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn try_get_sub_block_info_for_index(&self, index: i32) -> Result { + pub fn try_get_sub_block_info_for_index(&self, index: i32) -> Result { let mut sub_block_info = MaybeUninit::uninit(); let ptr = sub_block_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_TryGetSubBlockInfoForIndex(**self, index, ptr) })?; + lib_czi_error(unsafe { libCZI_TryGetSubBlockInfoForIndex(**self, index, ptr) })?; Ok(unsafe { SubBlockInfo::assume_init(sub_block_info) }) } @@ -293,10 +285,12 @@ impl CziReader { /// \\param accessor_object \[out\] If the operation is successful, a handle to the newly created single-channel-scaling-tile-accessor is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn create_single_channel_tile_accessor(&self) -> Result { + pub fn create_single_channel_tile_accessor( + &self, + ) -> Result { let mut accessor = MaybeUninit::uninit(); let ptr = accessor.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_CreateSingleChannelTileAccessor(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_CreateSingleChannelTileAccessor(**self, ptr) })?; Ok(unsafe { SingleChannelScalingTileAccessor::assume_init(accessor) }) } } @@ -314,10 +308,10 @@ impl Drop for CziReader { /// must be freed (by the caller) using 'libCZI_Free'. /// /// \\returns An error-code indicating success or failure of the operation. -pub fn get_stream_classes_count(index: i32) -> Result { +pub fn get_stream_classes_count(index: i32) -> Result { let mut input_stream_class_info = MaybeUninit::uninit(); let ptr = input_stream_class_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_GetStreamClassInfo(index, ptr) })?; + lib_czi_error(unsafe { libCZI_GetStreamClassInfo(index, ptr) })?; Ok(unsafe { InputStreamClassInfo::assume_init(input_stream_class_info) }) } @@ -335,14 +329,14 @@ impl InputStream { stream_class_name: impl AsRef, creation_property_bag: impl AsRef, stream_identifier: impl AsRef, - ) -> Result { + ) -> Result { let mut stream = MaybeUninit::uninit(); let ptr = stream.as_mut_ptr(); let stream_class_name = ManuallyDrop::new(CString::new(stream_class_name.as_ref())?); let creation_property_bag = ManuallyDrop::new(CString::new(creation_property_bag.as_ref())?); let stream_identifier = ManuallyDrop::new(CString::new(stream_identifier.as_ref())?); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CreateInputStream( stream_class_name.as_ptr(), creation_property_bag.as_ptr(), @@ -362,12 +356,10 @@ impl InputStream { /// \\param \[out\] stream_object The output stream object that will hold the created stream. /// \\return An error-code that indicates whether the operation is successful or not. Non-positive values indicates successful, positive values /// indicates unsuccessful operation. - pub fn create_from_file_wide(file_name: Vec) -> Result { + pub fn create_from_file_wide(file_name: Vec) -> Result { let mut stream = MaybeUninit::uninit(); let ptr = stream.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { - libCZI_CreateInputStreamFromFileWide(file_name.as_ptr(), ptr) - })?; + lib_czi_error(unsafe { libCZI_CreateInputStreamFromFileWide(file_name.as_ptr(), ptr) })?; Ok(unsafe { Self::assume_init(stream) }) } @@ -377,12 +369,12 @@ impl InputStream { /// \\param \[out\] stream_object The output stream object that will hold the created stream. /// \\return An error-code that indicates whether the operation is successful or not. Non-positive values indicates successful, positive values /// indicates unsuccessful operation. - pub fn create_from_file_utf8>(file_name: S) -> Result { + pub fn create_from_file_utf8>(file_name: S) -> Result { let mut stream = MaybeUninit::uninit(); let ptr = stream.as_mut_ptr(); let file_name = ManuallyDrop::new(CString::new(file_name.as_ref())?); // let file_name = file_name.as_ref().as_bytes().to_vec(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CreateInputStreamFromFileUTF8(file_name.as_ptr() as *const c_char, ptr) })?; Ok(unsafe { Self::assume_init(stream) }) @@ -396,10 +388,12 @@ impl InputStream { /// \\param \[out\] stream_object If successful, the handle to the newly created input stream object is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn create_from_external(external_input_stream: ExternalInputStreamStruct) -> Result { + pub fn create_from_external( + external_input_stream: ExternalInputStreamStruct, + ) -> Result { let mut stream = MaybeUninit::uninit(); let ptr = stream.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CreateInputStreamFromExternal(external_input_stream.as_ptr(), ptr) })?; Ok(unsafe { Self::assume_init(stream) }) @@ -413,8 +407,8 @@ impl InputStream { /// \\param stream_object The input stream object. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseInputStream(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseInputStream(**self) })?; Ok(()) } } @@ -434,10 +428,10 @@ impl SubBlock { /// \\param \[out\] bitmap_object If successful, the handle to the newly created bitmap object is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn create_bitmap(&self) -> Result { + pub fn create_bitmap(&self) -> Result { let mut bitmap = MaybeUninit::uninit(); let ptr = bitmap.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_SubBlockCreateBitmap(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_SubBlockCreateBitmap(**self, ptr) })?; Ok(unsafe { Bitmap::assume_init(bitmap) }) } @@ -447,10 +441,10 @@ impl SubBlock { /// \\param \[out\] sub_block_info If successful, information about the sub-block object is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_info(&self) -> Result { + pub fn get_info(&self) -> Result { let mut sub_block_info = MaybeUninit::uninit(); let ptr = sub_block_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_SubBlockGetInfo(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_SubBlockGetInfo(**self, ptr) })?; Ok(unsafe { SubBlockInfo::assume_init(sub_block_info) }) } @@ -468,10 +462,10 @@ impl SubBlock { /// \\param \[out\] data Pointer where the data is to be copied to. At most the initial content of 'size' bytes are copied. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_raw_data(&self, tp: RawDataType, size: i32) -> Result<(i32, Vec)> { + pub fn get_raw_data(&self, tp: RawDataType, size: i32) -> Result<(i32, Vec), Error> { let mut data = Vec::::with_capacity(size as usize); let size = Box::into_raw(Box::new(size as c_ulong)); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_SubBlockGetRawData(**self, tp as c_int, size, data.as_mut_ptr() as *mut c_void) })?; Ok((unsafe { *Box::from_raw(size) as i32 }, data)) @@ -482,8 +476,8 @@ impl SubBlock { /// \\param sub_block_object The sub block object to be released. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseSubBlock(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseSubBlock(**self) })?; Ok(()) } } @@ -499,10 +493,10 @@ impl Attachment { /// \\param attachment_object The attachment object. /// \\param \[out\] attachment_info Information about the attachment. /// \\returns An error-code indicating success or failure of the operation. - pub fn get_info(&self) -> Result { + pub fn get_info(&self) -> Result { let mut attachment_info = MaybeUninit::uninit(); let ptr = attachment_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_AttachmentGetInfo(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_AttachmentGetInfo(**self, ptr) })?; Ok(unsafe { AttachmentInfo::assume_init(attachment_info) }) } @@ -515,10 +509,10 @@ impl Attachment { /// \\param \[out\] data Pointer where the data is to be copied to. At most the initial content of 'size' bytes are copied. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_raw_data(&self, size: i32) -> Result<(i32, Vec)> { + pub fn get_raw_data(&self, size: i32) -> Result<(i32, Vec), Error> { let mut data = Vec::::with_capacity(size as usize); let size = Box::into_raw(Box::new(size as c_ulong)); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_AttachmentGetRawData(**self, size, data.as_mut_ptr() as *mut c_void) })?; Ok((unsafe { *Box::from_raw(size) as i32 }, data)) @@ -529,8 +523,8 @@ impl Attachment { /// \\param attachment_object The attachment object to be released. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseAttachment(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseAttachment(**self) })?; Ok(()) } } @@ -548,10 +542,10 @@ impl Bitmap { /// \\param \[out\] bitmap_info If successful, information about the bitmap object is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_info(&self) -> Result { + pub fn get_info(&self) -> Result { let mut bitmap_info = MaybeUninit::uninit(); let ptr = bitmap_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_BitmapGetInfo(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_BitmapGetInfo(**self, ptr) })?; Ok(unsafe { BitmapInfo::assume_init(bitmap_info) }) } @@ -564,10 +558,10 @@ impl Bitmap { /// \\param \[out\] lockInfo If successful, information about how to access the pixel data is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn lock(self) -> Result { + pub fn lock(self) -> Result { let mut bitmap_info = MaybeUninit::uninit(); let ptr = bitmap_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_BitmapLock(*self, ptr) })?; + lib_czi_error(unsafe { libCZI_BitmapLock(*self, ptr) })?; let bitmap_lock_info = unsafe { BitmapLockInfo::assume_init(bitmap_info) }; Ok(LockedBitmap { bitmap: self, @@ -581,8 +575,8 @@ impl Bitmap { /// \\param bitmap_object The bitmap object. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseBitmap(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseBitmap(**self) })?; Ok(()) } } @@ -590,7 +584,7 @@ impl Bitmap { impl TryFrom<&SubBlock> for Bitmap { type Error = Error; - fn try_from(sub_block: &SubBlock) -> Result { + fn try_from(sub_block: &SubBlock) -> Result { sub_block.create_bitmap() } } @@ -627,8 +621,8 @@ impl LockedBitmap { /// \\param bitmap_object The bitmap object. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn unlock(self) -> Result { - LibCZIApiError::try_from(unsafe { libCZI_BitmapUnlock(**self) })?; + pub fn unlock(self) -> Result { + lib_czi_error(unsafe { libCZI_BitmapUnlock(**self) })?; Ok(self.bitmap.clone()) } @@ -649,9 +643,9 @@ impl LockedBitmap { height: u32, pixel_type: PixelType, stride: u32, - ) -> Result { + ) -> Result { let mut data = MaybeUninit::::uninit(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_BitmapCopyTo( ***self, width, @@ -674,10 +668,10 @@ impl MetadataSegment { /// \\param \[out\] metadata_as_xml_interop If successful, the XML-metadata information is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_metadata_as_xml(&self) -> Result { + pub fn get_metadata_as_xml(&self) -> Result { let mut metadata_as_xml_interop = MaybeUninit::uninit(); let ptr = metadata_as_xml_interop.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_MetadataSegmentGetMetadataAsXml(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_MetadataSegmentGetMetadataAsXml(**self, ptr) })?; Ok(unsafe { MetadataAsXml::assume_init(metadata_as_xml_interop) }) } @@ -687,10 +681,10 @@ impl MetadataSegment { /// \\param \[in,out\] czi_document_info If successful, a handle to the newly created CZI-document-info object is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_czi_document_info(&self) -> Result { + pub fn get_czi_document_info(&self) -> Result { let mut czi_document = MaybeUninit::uninit(); let ptr = czi_document.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_MetadataSegmentGetCziDocumentInfo(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_MetadataSegmentGetCziDocumentInfo(**self, ptr) })?; Ok(unsafe { CziDocumentInfo::assume_init(czi_document) }) } @@ -699,8 +693,8 @@ impl MetadataSegment { /// \\param metadata_segment_object The metadata-segment object to be released. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseMetadataSegment(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseMetadataSegment(**self) })?; Ok(()) } } @@ -727,9 +721,9 @@ impl CziDocumentInfo { /// \\param \[out\] general_document_info_json If successful, the general document information is put here. Note that the data must be freed using 'libCZI_Free' by the caller. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_general_document_info(&self) -> Result { + pub fn get_general_document_info(&self) -> Result { let mut ptr = MaybeUninit::<*mut c_char>::uninit(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CziDocumentInfoGetGeneralDocumentInfo( **self, ptr.as_mut_ptr() as *mut *mut c_void, @@ -750,10 +744,10 @@ impl CziDocumentInfo { /// \\param \[out\] scaling_info_interop If successful, the scaling information is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_scaling_info(&self) -> Result { + pub fn get_scaling_info(&self) -> Result { let mut scaling_info_interop = MaybeUninit::uninit(); let ptr = scaling_info_interop.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_CziDocumentInfoGetScalingInfo(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_CziDocumentInfoGetScalingInfo(**self, ptr) })?; Ok(unsafe { ScalingInfo::assume_init(scaling_info_interop) }) } @@ -764,10 +758,10 @@ impl CziDocumentInfo { /// \\param \[in,out\] display_settings_handle If successful, a handle to the display-settings object is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_display_settings(&self) -> Result { + pub fn get_display_settings(&self) -> Result { let mut display_settings = MaybeUninit::uninit(); let ptr = display_settings.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { libCZI_CziDocumentInfoGetDisplaySettings(**self, ptr) })?; + lib_czi_error(unsafe { libCZI_CziDocumentInfoGetDisplaySettings(**self, ptr) })?; Ok(unsafe { DisplaySettings::assume_init(display_settings) }) } @@ -778,9 +772,9 @@ impl CziDocumentInfo { /// \\param \[out\] dimension_info_json If successful, the information is put here as JSON format. Note that the data must be freed using 'libCZI_Free' by the caller. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn get_dimension_info(&self, dimension_index: u32) -> Result { + pub fn get_dimension_info(&self, dimension_index: u32) -> Result { let mut ptr = MaybeUninit::<*mut c_char>::uninit(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CziDocumentInfoGetDimensionInfo( **self, dimension_index, @@ -799,8 +793,8 @@ impl CziDocumentInfo { /// \\param czi_document_info The CZI-document-info object. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseCziDocumentInfo(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseCziDocumentInfo(**self) })?; Ok(()) } } @@ -822,10 +816,10 @@ impl OutputStream { /// /// \\return An error-code that indicates whether the operation is successful or not. Non-positive values indicates successful, positive values /// indicates unsuccessful operation. - pub fn create_for_file_wide(file_name: Vec, overwrite: bool) -> Result { + pub fn create_for_file_wide(file_name: Vec, overwrite: bool) -> Result { let mut output_stream = MaybeUninit::uninit(); let ptr = output_stream.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CreateOutputStreamForFileWide(file_name.as_ptr(), overwrite, ptr) })?; Ok(unsafe { Self::assume_init(output_stream) }) @@ -839,11 +833,14 @@ impl OutputStream { /// /// \\return An error-code that indicates whether the operation is successful or not. Non-positive values indicates successful, positive values /// indicates unsuccessful operation. - pub fn create_for_file_utf8>(file_name: S, overwrite: bool) -> Result { + pub fn create_for_file_utf8>( + file_name: S, + overwrite: bool, + ) -> Result { let mut output_stream = MaybeUninit::uninit(); let ptr = output_stream.as_mut_ptr(); let file_name = ManuallyDrop::new(CString::new(file_name.as_ref())?); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CreateOutputStreamForFileUTF8(file_name.as_ptr(), overwrite, ptr) })?; Ok(unsafe { Self::assume_init(output_stream) }) @@ -857,8 +854,8 @@ impl OutputStream { /// \\param output_stream_object The output stream object. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseOutputStream(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseOutputStream(**self) })?; Ok(()) } @@ -870,10 +867,12 @@ impl OutputStream { /// \\param \[out\] output_stream_object If successful, the handle to the newly created output stream object is put here. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn create_from_external(external_input_stream: ExternalOutputStreamStruct) -> Result { + pub fn create_from_external( + external_input_stream: ExternalOutputStreamStruct, + ) -> Result { let mut stream = MaybeUninit::uninit(); let ptr = stream.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CreateOutputStreamFromExternal(external_input_stream.as_ptr(), ptr) })?; Ok(unsafe { Self::assume_init(stream) }) @@ -899,11 +898,11 @@ impl CziWriter { /// \\param options A JSON-formatted zero-terminated string (in UTF8-encoding) containing options for the writer creation. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn create>(options: S) -> Result { + pub fn create>(options: S) -> Result { let mut writer = MaybeUninit::uninit(); let ptr = writer.as_mut_ptr(); let options = ManuallyDrop::new(CString::new(options.as_ref())?); - LibCZIApiError::try_from(unsafe { libCZI_CreateWriter(ptr, options.as_ptr()) })?; + lib_czi_error(unsafe { libCZI_CreateWriter(ptr, options.as_ptr()) })?; Ok(unsafe { Self::assume_init(writer) }) } @@ -924,9 +923,13 @@ impl CziWriter { /// \\param parameters A JSON-formatted zero-terminated string (in UTF8-encoding) containing options for the writer initialization. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn init>(&self, output_stream: &OutputStream, parameters: S) -> Result<()> { + pub fn init>( + &self, + output_stream: &OutputStream, + parameters: S, + ) -> Result<(), Error> { let parameters = ManuallyDrop::new(CString::new(parameters.as_ref())?); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_WriterCreate(**self, **output_stream, parameters.as_ptr()) })?; Ok(()) @@ -938,10 +941,8 @@ impl CziWriter { /// \\param add_sub_block_info_interop Information describing the sub-block to be added. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn add_sub_block(&self, add_sub_block_info: AddSubBlockInfo) -> Result<()> { - LibCZIApiError::try_from(unsafe { - libCZI_WriterAddSubBlock(**self, add_sub_block_info.as_ptr()) - })?; + pub fn add_sub_block(&self, add_sub_block_info: AddSubBlockInfo) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_WriterAddSubBlock(**self, add_sub_block_info.as_ptr()) })?; Ok(()) } @@ -951,10 +952,8 @@ impl CziWriter { /// \\param add_attachment_info_interop Information describing the attachment to be added. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn add_attachement(&self, add_attachment_info: AddAttachmentInfo) -> Result<()> { - LibCZIApiError::try_from(unsafe { - libCZI_WriterAddAttachment(**self, add_attachment_info.as_ptr()) - })?; + pub fn add_attachement(&self, add_attachment_info: AddAttachmentInfo) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_WriterAddAttachment(**self, add_attachment_info.as_ptr()) })?; Ok(()) } @@ -964,10 +963,8 @@ impl CziWriter { /// \\param write_metadata_info_interop Information describing the metadata to be added. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn write_metadata(&self, write_metadata_info: WriteMetadataInfo) -> Result<()> { - LibCZIApiError::try_from(unsafe { - libCZI_WriterWriteMetadata(**self, write_metadata_info.as_ptr()) - })?; + pub fn write_metadata(&self, write_metadata_info: WriteMetadataInfo) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_WriterWriteMetadata(**self, write_metadata_info.as_ptr()) })?; Ok(()) } @@ -978,8 +975,8 @@ impl CziWriter { /// \\param writer_object Handle to the writer object that is to be closed. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn close(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_WriterClose(**self) })?; + pub fn close(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_WriterClose(**self) })?; Ok(()) } @@ -988,8 +985,8 @@ impl CziWriter { /// \\param writer_object Handle to the writer object that is to be released. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseWriter(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseWriter(**self) })?; Ok(()) } } @@ -1010,10 +1007,10 @@ impl SingleChannelScalingTileAccessor { /// \\param size \[out\] The size of the tile accessor. It contains width and height information. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn calc_size(&self, roi: IntRect, zoom: f32) -> Result { + pub fn calc_size(&self, roi: IntRect, zoom: f32) -> Result { let mut size = MaybeUninit::uninit(); let ptr = size.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_SingleChannelTileAccessorCalcSize(**self, roi.as_ptr(), zoom, ptr) })?; Ok(unsafe { IntSize::assume_init(size) }) @@ -1035,10 +1032,10 @@ impl SingleChannelScalingTileAccessor { roi: IntRect, zoom: f32, options: AccessorOptions, - ) -> Result { + ) -> Result { let mut bitmap = MaybeUninit::uninit(); let ptr = bitmap.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_SingleChannelTileAccessorGet( **self, coordinate.as_ptr(), @@ -1056,8 +1053,8 @@ impl SingleChannelScalingTileAccessor { /// \\param accessor_object The accessor object. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseCreateSingleChannelTileAccessor(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseCreateSingleChannelTileAccessor(**self) })?; Ok(()) } } @@ -1084,10 +1081,10 @@ impl DisplaySettings { &self, channel_index: i32, sixteen_or_eight_bits_lut: bool, - ) -> Result { + ) -> Result { let mut composition_channel_info = MaybeUninit::uninit(); let ptr = composition_channel_info.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CompositorFillOutCompositionChannelInfoInterop( **self, channel_index, @@ -1098,10 +1095,13 @@ impl DisplaySettings { Ok(unsafe { CompositionChannelInfo::assume_init(composition_channel_info) }) } - pub fn get_channel_display_settings(&self, channel_id: i32) -> Result { + pub fn get_channel_display_settings( + &self, + channel_id: i32, + ) -> Result { let mut channel_display_setting = MaybeUninit::uninit(); let ptr = channel_display_setting.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_DisplaySettingsGetChannelDisplaySettings(**self, channel_id, ptr) })?; Ok(unsafe { ChannelDisplaySettings::assume_init(channel_display_setting) }) @@ -1112,8 +1112,8 @@ impl DisplaySettings { /// \\param display_settings_handle The display settings object. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseDisplaySettings(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseDisplaySettings(**self) })?; Ok(()) } } @@ -1138,10 +1138,10 @@ pub fn compositor_do_multi_channel_composition( channel_count: i32, source_bitmaps: Vec, channel_info: CompositionChannelInfo, -) -> Result { +) -> Result { let mut bitmap = MaybeUninit::uninit(); let ptr = bitmap.as_mut_ptr(); - LibCZIApiError::try_from(unsafe { + lib_czi_error(unsafe { libCZI_CompositorDoMultiChannelComposition( channel_count, source_bitmaps.as_ptr() as *const BitmapObjectHandle, @@ -1158,8 +1158,8 @@ impl ChannelDisplaySettings { /// \\param channel_display_settings_handle The channel-display settings object. /// /// \\returns An error-code indicating success or failure of the operation. - pub fn release(&self) -> Result<()> { - LibCZIApiError::try_from(unsafe { libCZI_ReleaseDisplaySettings(**self) })?; + pub fn release(&self) -> Result<(), Error> { + lib_czi_error(unsafe { libCZI_ReleaseDisplaySettings(**self) })?; Ok(()) } } diff --git a/src/interop.rs b/src/interop.rs index 3f7f053..634faf1 100644 --- a/src/interop.rs +++ b/src/interop.rs @@ -1,7 +1,8 @@ +use crate::error::Error; use crate::handle::{InputStream, MemoryAllocation}; use crate::misc::{PixelType, Ptr}; use crate::sys::*; -use anyhow::{Error, Result}; +use std::borrow::Cow; use std::ffi::{CStr, CString, c_char, c_void}; use std::fmt::Debug; use std::mem; @@ -203,17 +204,17 @@ impl LibCZIVersionInfo { } impl LibCZIBuildInformation { - pub fn get_compiler_information(&self) -> Result<&str> { - Ok(unsafe { CStr::from_ptr(self.0.compilerIdentification) }.to_str()?) + pub fn get_compiler_information(&'_ self) -> Cow<'_, str> { + unsafe { CStr::from_ptr(self.0.compilerIdentification) }.to_string_lossy() } - pub fn get_repository_url(&self) -> Result<&str> { - Ok(unsafe { CStr::from_ptr(self.0.repositoryUrl) }.to_str()?) + pub fn get_repository_url(&'_ self) -> Cow<'_, str> { + unsafe { CStr::from_ptr(self.0.repositoryUrl) }.to_string_lossy() } - pub fn get_repository_branch(&self) -> Result<&str> { - Ok(unsafe { CStr::from_ptr(self.0.repositoryBranch) }.to_str()?) + pub fn get_repository_branch(&'_ self) -> Cow<'_, str> { + unsafe { CStr::from_ptr(self.0.repositoryBranch) }.to_string_lossy() } - pub fn get_repository_tag(&self) -> Result<&str> { - Ok(unsafe { CStr::from_ptr(self.0.repositoryTag) }.to_str()?) + pub fn get_repository_tag(&'_ self) -> Cow<'_, str> { + unsafe { CStr::from_ptr(self.0.repositoryTag) }.to_string_lossy() } } @@ -229,11 +230,11 @@ impl Drop for LibCZIBuildInformation { } impl InputStreamClassInfo { - pub fn get_name(&self) -> Result<&str> { - Ok(unsafe { CStr::from_ptr(self.0.name) }.to_str()?) + pub fn get_name(&'_ self) -> Cow<'_, str> { + unsafe { CStr::from_ptr(self.0.name) }.to_string_lossy() } - pub fn get_description(&self) -> Result<&str> { - Ok(unsafe { CStr::from_ptr(self.0.description) }.to_str()?) + pub fn get_description(&'_ self) -> Cow<'_, str> { + unsafe { CStr::from_ptr(self.0.description) }.to_string_lossy() } } @@ -566,7 +567,7 @@ impl SubBlockStatisticsEx { } impl MetadataAsXml { - pub fn get_data(&self) -> Result { + pub fn get_data(&self) -> Result { let xml_data = unsafe { Vec::from_raw_parts( self.0.data as *mut u8, @@ -589,7 +590,7 @@ impl Drop for MetadataAsXml { impl TryFrom<&MetadataAsXml> for String { type Error = Error; - fn try_from(value: &MetadataAsXml) -> std::result::Result { + fn try_from(value: &MetadataAsXml) -> Result { value.get_data() } } @@ -608,7 +609,7 @@ impl BitmapInfo { pub fn get_height(&self) -> u32 { self.0.height } - pub fn get_pixel_type(&self) -> Result { + pub fn get_pixel_type(&self) -> Result { PixelType::try_from(self.0.pixelType) } pub fn set_width(&mut self, width: u32) { @@ -666,7 +667,7 @@ impl SubBlockInfo { pub fn get_compression_mode_raw(&self) -> i32 { self.0.compression_mode_raw } - pub fn get_pixel_type(&self) -> Result { + pub fn get_pixel_type(&self) -> Result { PixelType::try_from(self.0.pixel_type) } pub fn get_coordinate(&self) -> Coordinate { @@ -708,7 +709,7 @@ impl AttachmentInfo { pub fn get_content_file_type(&self) -> [u8; 9] { self.0.content_file_type } - pub fn get_name(&self) -> Result { + pub fn get_name(&self) -> Result { Ok( CStr::from_bytes_until_nul(&self.0.name.iter().map(|&i| i as u8).collect::>())? .to_str()? @@ -718,7 +719,7 @@ impl AttachmentInfo { pub fn get_name_overflow(&self) -> bool { self.0.name_overflow } - pub fn get_name_in_case_of_overflow(&self) -> Result { + pub fn get_name_in_case_of_overflow(&self) -> Result { Ok( unsafe { CString::from_raw(self.0.name_in_case_of_overflow as *mut c_char) } .to_str()? @@ -833,7 +834,7 @@ impl AddSubBlockInfo { pub fn get_physical_height(&self) -> i32 { self.0.physical_height } - pub fn get_pixel_type(&self) -> Result { + pub fn get_pixel_type(&self) -> Result { PixelType::try_from(self.0.pixel_type) } pub fn get_compression_mode_raw(&self) -> i32 { @@ -1013,7 +1014,7 @@ impl AccessorOptions { sort_by_m: bool, use_visibility_check_optimization: bool, additional_parameters: S, - ) -> Result { + ) -> Result { let additional_parameters = ManuallyDrop::new(CString::new(additional_parameters.as_ref())?); Ok(Self(AccessorOptionsInterop { @@ -1040,7 +1041,7 @@ impl AccessorOptions { pub fn get_use_visibility_check_optimization(&self) -> bool { self.0.use_visibility_check_optimization } - pub fn get_additional_parameters(&self) -> Result { + pub fn get_additional_parameters(&self) -> Result { Ok(unsafe { CStr::from_ptr(self.0.additional_parameters) } .to_str()? .to_string()) @@ -1066,7 +1067,7 @@ impl AccessorOptions { pub fn set_additional_parameters>( &mut self, additional_parameters: S, - ) -> Result<()> { + ) -> Result<(), Error> { let additional_parameters = ManuallyDrop::new(CString::new(additional_parameters.as_ref())?); self.0.additional_parameters = additional_parameters.as_ptr(); diff --git a/src/lib.rs b/src/lib.rs index 9ef59a4..a23f09c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ extern crate link_cplusplus; +pub mod error; mod functions; mod handle; mod interop; @@ -9,27 +10,24 @@ pub mod sys; pub use functions::*; pub use handle::*; pub use interop::*; -pub use misc::{Dimension, LibCZIApiError, PixelType, RawDataType}; +pub use misc::{Dimension, PixelType, RawDataType}; #[cfg(test)] mod tests { use crate::handle::{CziReader, InputStream}; use crate::interop::{LibCZIBuildInformation, ReaderOpenInfo}; use crate::misc::Dimension; - use anyhow::{Error, Result}; use std::env; use std::path::PathBuf; #[test] - fn test_read_shape() -> Result<()> { + fn test_read_shape() -> Result<(), Box> { let path = env::home_dir() .unwrap() .join("code/rust/ndbioimage/tests/files/Experiment-2029.czi"); assert!(path.exists()); let czi = CziReader::create()?; - let stream = InputStream::create_from_file_utf8( - path.to_str().ok_or(Error::msg("cannot into str"))?, - )?; + let stream = InputStream::create_from_file_utf8(path.to_string_lossy().as_ref())?; let open_info = ReaderOpenInfo::new(&stream); czi.open(open_info)?; println!("pyramid statistics: {:?}", czi.get_pyramid_statistics()?); @@ -49,15 +47,13 @@ mod tests { } #[test] - fn test_read_bytes() -> Result<()> { + fn test_read_bytes() -> Result<(), Box> { let path = env::home_dir() .unwrap() .join("code/rust/ndbioimage/tests/files/Experiment-2029.czi"); assert!(path.exists()); let czi = CziReader::create()?; - let stream = InputStream::create_from_file_utf8( - path.to_str().ok_or(Error::msg("cannot into str"))?, - )?; + let stream = InputStream::create_from_file_utf8(path.to_string_lossy().as_ref())?; let open_info = ReaderOpenInfo::new(&stream); czi.open(open_info)?; let sub_block = czi.read_sub_block(0)?; @@ -75,15 +71,13 @@ mod tests { } #[test] - fn test_libczi_xml() -> Result<()> { + fn test_libczi_xml() -> Result<(), Box> { let path = env::home_dir() .unwrap() .join("code/rust/ndbioimage/tests/files/Experiment-2029.czi"); assert!(path.exists()); let czi = CziReader::create()?; - let stream = InputStream::create_from_file_utf8( - path.to_str().ok_or(Error::msg("cannot into str"))?, - )?; + let stream = InputStream::create_from_file_utf8(path.to_string_lossy().as_ref())?; let open_info = ReaderOpenInfo::new(&stream); czi.open(open_info)?; let metadata_segment = czi.get_metadata_segment()?; @@ -94,13 +88,11 @@ mod tests { } #[test] - fn test_libczi_pyramid_statistics() -> Result<()> { + fn test_libczi_pyramid_statistics() -> Result<(), Box> { let path = PathBuf::from("test-files/Experiment-2029.czi"); assert!(path.exists()); let czi = CziReader::create()?; - let stream = InputStream::create_from_file_utf8( - path.to_str().ok_or(Error::msg("cannot into str"))?, - )?; + let stream = InputStream::create_from_file_utf8(path.to_string_lossy().as_ref())?; let open_info = ReaderOpenInfo::new(&stream); czi.open(open_info)?; let s = czi.get_pyramid_statistics()?; @@ -109,13 +101,11 @@ mod tests { } #[test] - fn test_libczi_document_info() -> Result<()> { + fn test_libczi_document_info() -> Result<(), Box> { let path = PathBuf::from("test-files/Experiment-2029.czi"); assert!(path.exists()); let czi = CziReader::create()?; - let stream = InputStream::create_from_file_utf8( - path.to_str().ok_or(Error::msg("cannot into str"))?, - )?; + let stream = InputStream::create_from_file_utf8(path.to_string_lossy().as_ref())?; let open_info = ReaderOpenInfo::new(&stream); czi.open(open_info)?; let metadata_segment = czi.get_metadata_segment()?; @@ -129,7 +119,7 @@ mod tests { } #[test] - fn test_lib_czi_build_information() -> Result<()> { + fn test_lib_czi_build_information() -> Result<(), Box> { let build_info = LibCZIBuildInformation::get()?; println!( "compiler information: {:?}", diff --git a/src/misc.rs b/src/misc.rs index c61f117..87dd359 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -1,42 +1,16 @@ -use anyhow::{Error, Result, anyhow}; -use std::fmt; +use crate::error::Error; use std::mem::MaybeUninit; -use std::os::raw::c_int; -/// the error type for libCZIAPI -#[derive(Clone, Debug)] -pub enum LibCZIApiError { - OK, - InvalidArgument, - InvalidHandle, - OutOfMemory, - IndexOutOfRange, - LockUnlockSemanticViolated, - UnspecifiedError, -} - -impl std::error::Error for LibCZIApiError {} - -impl TryFrom for LibCZIApiError { - type Error = Error; - - fn try_from(code: c_int) -> Result { - match code { - 0 => Ok(LibCZIApiError::OK), - 1 => Err(Error::from(LibCZIApiError::InvalidArgument)), - 2 => Err(Error::from(LibCZIApiError::InvalidHandle)), - 3 => Err(Error::from(LibCZIApiError::OutOfMemory)), - 4 => Err(Error::from(LibCZIApiError::IndexOutOfRange)), - 20 => Err(Error::from(LibCZIApiError::LockUnlockSemanticViolated)), - 50 => Err(Error::from(LibCZIApiError::UnspecifiedError)), - _ => Err(anyhow!("Unknown error code {}", code)), - } - } -} - -impl fmt::Display for LibCZIApiError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "LibCZIApi {self:?}") +pub fn lib_czi_error(code: std::ffi::c_int) -> Result<(), Error> { + match code { + 0 => Ok(()), + 1 => Err(Error::LibCziApiInvalidArgument), + 2 => Err(Error::LibCziApiInvalidHandle), + 3 => Err(Error::LibCziApiOutOfMemory), + 4 => Err(Error::LibCziApiIndexOutOfRange), + 20 => Err(Error::LibCziApiLockUnlockSemanticViolated), + 50 => Err(Error::LibCziApiUnspecifiedError), + _ => Err(Error::LibCziApiUnknownError(code as usize)), } } @@ -79,7 +53,7 @@ impl Dimension { impl TryFrom for Dimension { type Error = Error; - fn try_from(dimension: i32) -> Result { + fn try_from(dimension: i32) -> Result { match dimension { 1 => Ok(Dimension::Z), 2 => Ok(Dimension::C), @@ -90,7 +64,7 @@ impl TryFrom for Dimension { 7 => Ok(Dimension::H), 8 => Ok(Dimension::V), 9 => Ok(Dimension::B), - _ => Err(anyhow!("Unknown dimension value {}", dimension)), + _ => Err(Error::UnknownDimension(dimension.to_string())), } } } @@ -105,11 +79,11 @@ pub enum RawDataType { impl TryFrom for RawDataType { type Error = Error; - fn try_from(raw_data_type: i32) -> Result { + fn try_from(raw_data_type: i32) -> Result { match raw_data_type { 0 => Ok(RawDataType::Data), 1 => Ok(RawDataType::Metadata), - _ => Err(anyhow!("Unknown data type {}", raw_data_type)), + _ => Err(Error::UnknownDataType(raw_data_type)), } } } @@ -133,7 +107,7 @@ pub enum PixelType { impl TryFrom for PixelType { type Error = Error; - fn try_from(pixel_type: i32) -> Result { + fn try_from(pixel_type: i32) -> Result { match pixel_type { 0 => Ok(PixelType::Gray8), 1 => Ok(PixelType::Gray16), @@ -146,7 +120,7 @@ impl TryFrom for PixelType { 11 => Ok(PixelType::Bgr192ComplexFloat), 12 => Ok(PixelType::Gray32), 13 => Ok(PixelType::Gray64Float), - _ => Err(anyhow!("Unknown pixel type {}", pixel_type)), + _ => Err(Error::UnknownPixelType(pixel_type)), } } }