Skip to main content

abi_definitions/file_system/
common.rs

1use core::{
2    ffi::{CStr, c_char},
3    num::NonZeroU32,
4};
5use virtual_file_system::Error;
6
7use crate::XilaFileSystemResult;
8
9/// This function is used to convert a function returning a Result into a u32.
10pub fn into_result<F>(function: F) -> XilaFileSystemResult
11where
12    F: FnOnce() -> Result<(), virtual_file_system::Error>,
13{
14    match function() {
15        Ok(()) => 0,
16        Err(error) => {
17            let non_zero: NonZeroU32 = error.into();
18
19            if matches!(
20                error,
21                Error::RessourceBusy | Error::FileSystem(file_system::Error::RessourceBusy)
22            ) {
23                log::debug!(
24                    "File system busy (expected while polling): {:?} ({})",
25                    error,
26                    non_zero
27                );
28            } else {
29                log::error!("File system error: {:?} ({})", error, non_zero);
30            }
31
32            //panic!("File system error: {:?} ({})", error, non_zero.get());
33
34            non_zero.get()
35        }
36    }
37}
38
39/// # Safety
40/// The caller must ensure that the provided pointer is a vlid null-terminated C string.
41#[inline]
42pub unsafe fn parse_c_str(path: *const c_char) -> Result<&'static str, Error> {
43    if path.is_null() {
44        return Err(Error::InvalidParameter);
45    }
46    unsafe {
47        CStr::from_ptr(path)
48            .to_str()
49            .map_err(|_| Error::InvalidParameter)
50    }
51}
52
53#[macro_export]
54macro_rules! abi_unsafe_function {
55    (
56        $(#[$meta:meta])*
57        fn $name:ident ( $($arg:ident : $ty:ty),* $(,)? ) -> XilaFileSystemResult $body:block
58    ) => {
59        $(#[$meta])*
60        #[unsafe(no_mangle)]
61        pub unsafe extern "C" fn $name ( $($arg : $ty),* ) -> $crate::XilaFileSystemResult {
62            log::debug!("Calling function {}", stringify!($name));
63
64            // We use an immediately invoked anonymous closure (|| { ... })()
65            // This captures variables naturally and gives the `?` operator a target scope to return from.
66            #[allow(unused_unsafe)]
67            #[allow(clippy::macro_metavars_in_unsafe)]
68            let f = || unsafe {
69                $body
70            };
71
72            let result: Result<(), virtual_file_system::Error> = f();
73
74            match result {
75                Ok(()) => 0,
76                Err(virtual_file_system::Error::RessourceBusy | virtual_file_system::Error::FileSystem(file_system::Error::RessourceBusy)) => {
77                    log::debug!(
78                        "File system busy (expected while polling) in function {}: {:?}",
79                        stringify!($name),
80                        result
81                    );
82                    1 // Specific code for resource busy, if needed
83                },
84                Err(error) => {
85                    let non_zero: core::num::NonZeroU32 = error.into();
86
87                    log::error!(
88                        "File system error when calling {}: {:?} ({})",
89                        stringify!($name),
90                        error,
91                        non_zero
92                    );
93
94
95                    non_zero.get()
96                }
97            }
98        }
99    };
100}