1
1
use crate :: * ;
2
+ use cidr:: { IpInet , Ipv4Inet , Ipv6Inet } ;
3
+ use mac_address:: MacAddress ;
4
+ use std:: ffi:: c_char;
5
+ use std:: net:: { Ipv4Addr , Ipv6Addr } ;
6
+ use std:: ptr:: read;
2
7
3
8
#[ derive( Debug , Clone , PartialEq ) ]
4
9
pub enum Value < ' a > {
@@ -13,8 +18,8 @@ pub enum Value<'a> {
13
18
String ( & ' a str ) ,
14
19
Binary ( & ' a [ u8 ] ) ,
15
20
Bool ( bool ) ,
16
- Inet ( [ u8 ; 18 ] ) ,
17
- Mac ( [ u8 ; 6 ] ) ,
21
+ Inet ( IpInet ) ,
22
+ Mac ( MacAddress ) ,
18
23
}
19
24
20
25
impl Display for Value < ' _ > {
@@ -38,41 +43,59 @@ impl Display for Value<'_> {
38
43
}
39
44
40
45
impl < ' a > Value < ' a > {
41
- // TODO: If you know the detailed format, you can access the pointer directly
42
- // https://crossdb.org/client/api-c/#xdb_column_int
43
- pub ( crate ) unsafe fn from_result (
44
- meta : u64 ,
45
- row : * mut xdb_row_t ,
46
- col : u16 ,
47
- t : DataType ,
48
- ) -> Value < ' a > {
46
+ pub ( crate ) unsafe fn from_ptr ( ptr : * const c_void , t : DataType ) -> Self {
47
+ if ptr. is_null ( ) {
48
+ return Self :: Null ;
49
+ }
49
50
match t {
50
51
DataType :: Null => Self :: Null ,
51
- DataType :: TinyInt => Self :: I8 ( xdb_column_int ( meta , row , col ) as _ ) ,
52
+ DataType :: TinyInt => Self :: I8 ( read ( ptr as * const i8 ) ) ,
52
53
DataType :: UTinyInt => todo ! ( ) ,
53
- DataType :: SmallInt => Self :: I16 ( xdb_column_int ( meta , row , col ) as _ ) ,
54
+ DataType :: SmallInt => Self :: I16 ( read ( ptr as * const i16 ) ) ,
54
55
DataType :: USmallInt => todo ! ( ) ,
55
- DataType :: Int => Self :: I32 ( xdb_column_int ( meta , row , col ) as _ ) ,
56
+ DataType :: Int => Self :: I32 ( read ( ptr as * const i32 ) ) ,
56
57
DataType :: UInt => todo ! ( ) ,
57
- DataType :: BigInt => Self :: I64 ( xdb_column_int64 ( meta , row , col ) ) ,
58
+ DataType :: BigInt => Self :: I64 ( read ( ptr as * const i64 ) ) ,
58
59
DataType :: UBigInt => todo ! ( ) ,
59
- DataType :: Float => Self :: F32 ( xdb_column_float ( meta , row , col ) ) ,
60
- DataType :: Double => Self :: F64 ( xdb_column_double ( meta , row , col ) ) ,
61
- DataType :: Timestamp => Self :: Timestamp ( xdb_column_int64 ( meta , row , col ) ) ,
60
+ DataType :: Float => Self :: F32 ( read ( ptr as * const f32 ) ) ,
61
+ DataType :: Double => Self :: F64 ( read ( ptr as * const f64 ) ) ,
62
+ DataType :: Timestamp => Self :: Timestamp ( read ( ptr as * const i64 ) ) ,
62
63
DataType :: Char | DataType :: VChar => {
63
- let ptr = xdb_column_str ( meta, row, col) ;
64
- if ptr. is_null ( ) {
65
- return Value :: Null ;
66
- }
67
- Value :: String ( CStr :: from_ptr ( ptr) . to_str ( ) . unwrap ( ) )
64
+ let str = CStr :: from_ptr ( ptr as * const c_char ) . to_str ( ) . unwrap ( ) ;
65
+ Self :: String ( str)
68
66
}
69
67
DataType :: Binary | DataType :: VBinary => {
70
- // xdb_column_blob(meta, row, col, pLen);
71
- todo ! ( )
68
+ let len = read ( ( ptr as * const u8 ) . offset ( -2 ) as * const u16 ) ;
69
+ let data = from_raw_parts ( ptr as * const u8 , len as usize ) ;
70
+ Self :: Binary ( data)
71
+ }
72
+ DataType :: Bool => Self :: Bool ( * ( ptr as * const i8 ) == 1 ) ,
73
+ DataType :: Inet => {
74
+ let bytes = from_raw_parts ( ptr as * const u8 , 18 ) ;
75
+ let mask = bytes[ 0 ] ;
76
+ let family = bytes[ 1 ] ;
77
+ match family {
78
+ 4 => {
79
+ let mut buf = [ 0 ; 4 ] ;
80
+ buf. copy_from_slice ( & bytes[ 2 ..6 ] ) ;
81
+ let net = Ipv4Inet :: new ( Ipv4Addr :: from ( buf) , mask) . unwrap ( ) ;
82
+ Self :: Inet ( IpInet :: V4 ( net) )
83
+ }
84
+ 6 => {
85
+ let mut buf = [ 0 ; 16 ] ;
86
+ buf. copy_from_slice ( & bytes[ 2 ..18 ] ) ;
87
+ let net = Ipv6Inet :: new ( Ipv6Addr :: from ( buf) , mask) . unwrap ( ) ;
88
+ Self :: Inet ( IpInet :: V6 ( net) )
89
+ }
90
+ _ => unreachable ! ( ) ,
91
+ }
92
+ }
93
+ DataType :: Mac => {
94
+ let bytes = from_raw_parts ( ptr as * const u8 , 6 ) ;
95
+ let address =
96
+ MacAddress :: new ( [ bytes[ 0 ] , bytes[ 1 ] , bytes[ 2 ] , bytes[ 3 ] , bytes[ 4 ] , bytes[ 5 ] ] ) ;
97
+ Self :: Mac ( address)
72
98
}
73
- DataType :: Bool => Self :: Bool ( xdb_column_int ( meta, row, col) == 1 ) ,
74
- DataType :: Inet => todo ! ( ) ,
75
- DataType :: Mac => todo ! ( ) ,
76
99
DataType :: Max => todo ! ( ) ,
77
100
}
78
101
}
0 commit comments