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