11use 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;
27
38#[ derive( Debug , Clone , PartialEq ) ]
49pub enum Value < ' a > {
@@ -13,8 +18,8 @@ pub enum Value<'a> {
1318 String ( & ' a str ) ,
1419 Binary ( & ' a [ u8 ] ) ,
1520 Bool ( bool ) ,
16- Inet ( [ u8 ; 18 ] ) ,
17- Mac ( [ u8 ; 6 ] ) ,
21+ Inet ( IpInet ) ,
22+ Mac ( MacAddress ) ,
1823}
1924
2025impl Display for Value < ' _ > {
@@ -38,41 +43,59 @@ impl Display for Value<'_> {
3843}
3944
4045impl < ' 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+ }
4950 match t {
5051 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 ) ) ,
5253 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 ) ) ,
5455 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 ) ) ,
5657 DataType :: UInt => todo ! ( ) ,
57- DataType :: BigInt => Self :: I64 ( xdb_column_int64 ( meta , row , col ) ) ,
58+ DataType :: BigInt => Self :: I64 ( read ( ptr as * const i64 ) ) ,
5859 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 ) ) ,
6263 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)
6866 }
6967 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)
7298 }
73- DataType :: Bool => Self :: Bool ( xdb_column_int ( meta, row, col) == 1 ) ,
74- DataType :: Inet => todo ! ( ) ,
75- DataType :: Mac => todo ! ( ) ,
7699 DataType :: Max => todo ! ( ) ,
77100 }
78101 }
0 commit comments