1 // Take a look at the license at the top of the repository in the LICENSE file. 2 3 use crate::prelude::*; 4 use crate::SocketAddress; 5 use crate::UnixSocketAddress; 6 use crate::UnixSocketAddressType; 7 use glib::translate::*; 8 #[cfg(not(feature = "dox"))] 9 use std::ffi::OsStr; 10 #[cfg(unix)] 11 #[cfg(not(feature = "dox"))] 12 use std::os::unix::ffi::OsStrExt; 13 use std::path; 14 use std::ptr; 15 use std::slice; 16 17 #[derive(Debug)] 18 pub enum UnixSocketAddressPath<'a> { 19 Path(&'a path::Path), 20 Anonymous, 21 Abstract(&'a [u8]), 22 AbstractPadded(&'a [u8]), 23 } 24 25 impl<'a> UnixSocketAddressPath<'a> { to_type(&self) -> UnixSocketAddressType26 fn to_type(&self) -> UnixSocketAddressType { 27 use self::UnixSocketAddressPath::*; 28 29 match *self { 30 Path(_) => UnixSocketAddressType::Path, 31 Anonymous => UnixSocketAddressType::Anonymous, 32 Abstract(_) => UnixSocketAddressType::Abstract, 33 AbstractPadded(_) => UnixSocketAddressType::AbstractPadded, 34 } 35 } 36 } 37 38 impl UnixSocketAddress { 39 #[doc(alias = "g_unix_socket_address_new")] new(path: &path::Path) -> UnixSocketAddress40 pub fn new(path: &path::Path) -> UnixSocketAddress { 41 unsafe { 42 SocketAddress::from_glib_full(ffi::g_unix_socket_address_new(path.to_glib_none().0)) 43 .unsafe_cast() 44 } 45 } 46 47 #[doc(alias = "g_unix_socket_address_new_with_type")] with_type(address_type: UnixSocketAddressPath) -> Self48 pub fn with_type(address_type: UnixSocketAddressPath) -> Self { 49 use self::UnixSocketAddressPath::*; 50 51 let type_ = address_type.to_type(); 52 let (path, len) = match address_type { 53 Path(path) => (path.to_glib_none().0, path.as_os_str().len()), 54 Abstract(path) | AbstractPadded(path) => { 55 (path.to_glib_none().0 as *mut libc::c_char, path.len()) 56 } 57 Anonymous => (ptr::null_mut(), 0), 58 }; 59 unsafe { 60 SocketAddress::from_glib_full(ffi::g_unix_socket_address_new_with_type( 61 path, 62 len as i32, 63 type_.into_glib(), 64 )) 65 .unsafe_cast() 66 } 67 } 68 } 69 70 pub trait UnixSocketAddressExtManual { 71 #[doc(alias = "g_unix_socket_address_get_path")] 72 #[doc(alias = "get_path")] path(&self) -> Option<UnixSocketAddressPath>73 fn path(&self) -> Option<UnixSocketAddressPath>; 74 } 75 76 impl<O: IsA<UnixSocketAddress>> UnixSocketAddressExtManual for O { path(&self) -> Option<UnixSocketAddressPath>77 fn path(&self) -> Option<UnixSocketAddressPath> { 78 use self::UnixSocketAddressPath::*; 79 80 let path = unsafe { 81 let path = ffi::g_unix_socket_address_get_path(self.as_ref().to_glib_none().0); 82 if path.is_null() { 83 &[] 84 } else { 85 slice::from_raw_parts(path as *const u8, self.path_len()) 86 } 87 }; 88 match self.address_type() { 89 UnixSocketAddressType::Anonymous => Some(Anonymous), 90 #[cfg(not(feature = "dox"))] 91 UnixSocketAddressType::Path => Some(Path(path::Path::new(OsStr::from_bytes(path)))), 92 #[cfg(feature = "dox")] 93 UnixSocketAddressType::Path => unreachable!(), 94 UnixSocketAddressType::Abstract => Some(Abstract(path)), 95 UnixSocketAddressType::AbstractPadded => Some(AbstractPadded(path)), 96 UnixSocketAddressType::Invalid | UnixSocketAddressType::__Unknown(_) => None, 97 } 98 } 99 } 100