Skip to main content

endpoint_sec/event/
event_create.rs

1//! [`EventCreate`]
2
3use std::ffi::OsStr;
4
5use endpoint_sec_sys::{es_destination_type_t, es_event_create_t, mode_t};
6
7#[cfg(feature = "macos_10_15_1")]
8use crate::Acl;
9use crate::File;
10
11/// Create a file system object event.
12#[doc(alias = "es_event_create_t")]
13pub struct EventCreate<'a> {
14    /// Raw message
15    pub(crate) raw: &'a es_event_create_t,
16    /// Message version
17    pub(crate) version: u32,
18}
19
20/// Represent a destination file for [`EventCreate`].
21#[derive(Debug, PartialEq, Eq, Hash)]
22#[doc(alias = "es_destination_type_t")]
23#[non_exhaustive]
24pub enum EventCreateDestinationFile<'a> {
25    /// The destination file already exist at the time of the event.
26    #[non_exhaustive]
27    ExistingFile {
28        /// The file that will be overwritten by the file creation.
29        file: File<'a>,
30    },
31    /// The destination doesn't exist at the time of the event.
32    #[non_exhaustive]
33    NewPath {
34        /// The directory into which the file will be created.
35        directory: File<'a>,
36        /// The name of the new file that will be created.
37        filename: &'a OsStr,
38        /// The mode of the new file that will be created.
39        mode: mode_t,
40    },
41}
42
43impl<'a> EventCreate<'a> {
44    /// Information about the destination of the new file
45    #[inline(always)]
46    pub fn destination(&self) -> Option<EventCreateDestinationFile<'a>> {
47        match self.raw.destination_type {
48            es_destination_type_t::ES_DESTINATION_TYPE_EXISTING_FILE => {
49                Some(EventCreateDestinationFile::ExistingFile {
50                    // Safety: Safe as we select the union field corresponding to that type.
51                    file: File::new(unsafe { self.raw.destination.existing_file.as_ref() }),
52                })
53            },
54            es_destination_type_t::ES_DESTINATION_TYPE_NEW_PATH => {
55                // Safety: Safe as we select the union fields corresponding to that type.
56                let new_path = unsafe { &self.raw.destination.new_path };
57                Some(EventCreateDestinationFile::NewPath {
58                    // Safety: 'a tied to self, object obtained through ES
59                    directory: File::new(unsafe { new_path.dir() }),
60                    // Safety: 'a tied to self, object obtained through ES
61                    filename: unsafe { new_path.filename.as_os_str() },
62                    mode: new_path.mode,
63                })
64            },
65            _ => None,
66        }
67    }
68
69    /// The ACL that the new file system object got or gets created with.
70    ///
71    /// May be `None` if the file system object gets created without ACL.
72    #[inline(always)]
73    #[cfg(feature = "macos_10_15_1")]
74    pub fn acl(&self) -> Option<Acl<'a>> {
75        if self.version < 2 {
76            return None;
77        }
78
79        // Safety: we checked the version is >= 2
80        Acl::from_raw(unsafe { self.raw.anon_1.anon_0.acl })
81    }
82}
83
84// Safety: safe to send across threads: does not contain any interior mutability nor depend on current thread state
85unsafe impl Send for EventCreate<'_> {}
86// Safety: safe to share across threads: does not contain any interior mutability nor depend on current thread state
87unsafe impl Sync for EventCreate<'_> {}
88
89impl_debug_eq_hash_with_functions!(EventCreate<'a> with version; destination, #[cfg(feature = "macos_10_15_1")] acl);