1
1
use gio_sys;
2
+ use glib:: object:: IsA ;
2
3
use glib:: translate:: * ;
3
4
use InetAddress ;
5
+ use InetAddressExt ;
4
6
use SocketFamily ;
5
7
8
+ use std:: net:: { IpAddr , Ipv4Addr , Ipv6Addr } ;
9
+
6
10
#[ derive( Debug ) ]
7
11
pub enum InetAddressBytes < ' a > {
8
12
V4 ( & ' a [ u8 ; 4 ] ) ,
@@ -22,13 +26,11 @@ impl<'a> InetAddressBytes<'a> {
22
26
23
27
impl InetAddress {
24
28
pub fn from_bytes ( inet_address_bytes : InetAddressBytes ) -> Self {
25
- use self :: InetAddressBytes :: * ;
26
-
27
29
let bytes = inet_address_bytes. deref ( ) ;
28
30
29
31
let family = match inet_address_bytes {
30
- V4 ( _) => SocketFamily :: Ipv4 ,
31
- V6 ( _) => SocketFamily :: Ipv6 ,
32
+ InetAddressBytes :: V4 ( _) => SocketFamily :: Ipv4 ,
33
+ InetAddressBytes :: V6 ( _) => SocketFamily :: Ipv6 ,
32
34
} ;
33
35
unsafe {
34
36
from_glib_full ( gio_sys:: g_inet_address_new_from_bytes (
@@ -38,3 +40,49 @@ impl InetAddress {
38
40
}
39
41
}
40
42
}
43
+
44
+ pub trait InetAddressExtManual {
45
+ fn to_bytes < ' a > ( & ' a self ) -> Option < InetAddressBytes < ' a > > ;
46
+ }
47
+
48
+ impl < O : IsA < InetAddress > > InetAddressExtManual for O {
49
+ /// Returns `None` in case the address has a native size different than 4 and 16.
50
+ fn to_bytes < ' a > ( & ' a self ) -> Option < InetAddressBytes < ' a > > {
51
+ let size = self . get_native_size ( ) ;
52
+ unsafe {
53
+ let bytes = gio_sys:: g_inet_address_to_bytes ( self . as_ref ( ) . to_glib_none ( ) . 0 ) ;
54
+ if size == 4 {
55
+ Some ( InetAddressBytes :: V4 ( & * ( bytes as * const [ u8 ; 4 ] ) ) )
56
+ } else if size == 16 {
57
+ Some ( InetAddressBytes :: V6 ( & * ( bytes as * const [ u8 ; 16 ] ) ) )
58
+ } else {
59
+ None
60
+ }
61
+ }
62
+ }
63
+ }
64
+
65
+ impl From < IpAddr > for InetAddress {
66
+ fn from ( addr : IpAddr ) -> Self {
67
+ match addr {
68
+ IpAddr :: V4 ( v4) => InetAddress :: from_bytes ( InetAddressBytes :: V4 ( & v4. octets ( ) ) ) ,
69
+ IpAddr :: V6 ( v6) => InetAddress :: from_bytes ( InetAddressBytes :: V6 ( & v6. octets ( ) ) ) ,
70
+ }
71
+ }
72
+ }
73
+
74
+ impl Into < IpAddr > for InetAddress {
75
+ fn into ( self ) -> IpAddr {
76
+ let size = self . get_native_size ( ) ;
77
+ unsafe {
78
+ let bytes = gio_sys:: g_inet_address_to_bytes ( self . to_glib_none ( ) . 0 ) ;
79
+ if size == 4 {
80
+ IpAddr :: V4 ( Ipv4Addr :: from ( * ( bytes as * const [ u8 ; 4 ] ) ) )
81
+ } else if size == 16 {
82
+ IpAddr :: V6 ( Ipv6Addr :: from ( * ( bytes as * const [ u16 ; 8 ] ) ) )
83
+ } else {
84
+ panic ! ( "Unknown IP kind" ) ;
85
+ }
86
+ }
87
+ }
88
+ }
0 commit comments