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")]
23pub enum EventCreateDestinationFile<'a> {
24    /// The destination file already exist at the time of the event.
25    ExistingFile(File<'a>),
26    /// The destination doesn't exist at the time of the event.
27    NewPath {
28        /// The directory into which the file will be renamed.
29        directory: File<'a>,
30        /// The name of the new file that will be created.
31        filename: &'a OsStr,
32        /// The mode of the new file that will be created.
33        mode: mode_t,
34    },
35}
36
37impl<'a> EventCreate<'a> {
38    /// Information about the destination of the new file
39    #[inline(always)]
40    pub fn destination(&self) -> Option<EventCreateDestinationFile<'a>> {
41        match self.raw.destination_type {
42            es_destination_type_t::ES_DESTINATION_TYPE_EXISTING_FILE => {
43                Some(EventCreateDestinationFile::ExistingFile(
44                    // Safety: Safe as we select the union field corresponding to that type.
45                    File::new(unsafe { self.raw.destination.existing_file.as_ref() }),
46                ))
47            },
48            es_destination_type_t::ES_DESTINATION_TYPE_NEW_PATH => {
49                // Safety: Safe as we select the union fields corresponding to that type.
50                let new_path = unsafe { &self.raw.destination.new_path };
51                Some(EventCreateDestinationFile::NewPath {
52                    // Safety: 'a tied to self, object obtained through ES
53                    directory: File::new(unsafe { new_path.dir() }),
54                    // Safety: 'a tied to self, object obtained through ES
55                    filename: unsafe { new_path.filename.as_os_str() },
56                    mode: new_path.mode,
57                })
58            },
59            _ => None,
60        }
61    }
62
63    /// The ACL that the new file system object got or gets created with.
64    ///
65    /// May be `None` if the file system object gets created without ACL.
66    #[inline(always)]
67    #[cfg(feature = "macos_10_15_1")]
68    pub fn acl(&self) -> Option<Acl<'a>> {
69        if self.version < 2 {
70            return None;
71        }
72
73        // Safety: we checked the version is >= 2
74        Acl::from_raw(unsafe { self.raw.anon_1.anon_0.acl })
75    }
76}
77
78// Safety: safe to send across threads: does not contain any interior mutability nor depend on current thread state
79unsafe impl Send for EventCreate<'_> {}
80// Safety: safe to share across threads: does not contain any interior mutability nor depend on current thread state
81unsafe impl Sync for EventCreate<'_> {}
82
83impl_debug_eq_hash_with_functions!(EventCreate<'a> with version; destination, #[cfg(feature = "macos_10_15_1")] acl);