use zerocopy::byteorder::little_endian::{U16 as U16LE, U32 as U32LE};
use zerocopy::{FromBytes, Immutable, KnownLayout};
#[derive(Debug, Clone, Copy)]
pub enum Value<'a> {
Null,
SignedInt(i64),
UnsignedInt(u64),
Float(f32),
Double(f64),
Date0,
Date4(&'a Timestamp4),
Datetime0,
Datetime4(&'a Timestamp4),
Datetime7(&'a Timestamp7),
Datetime11(&'a Timestamp11),
Time0,
Time8(&'a Time8),
Time12(&'a Time12),
Byte(&'a [u8]),
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable)]
pub struct Timestamp4 {
pub year: U16LE,
pub month: u8,
pub day: u8,
}
impl Timestamp4 {
pub fn year(&self) -> u16 {
self.year.get()
}
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable)]
pub struct Timestamp7 {
pub year: U16LE,
pub month: u8,
pub day: u8,
pub hour: u8,
pub minute: u8,
pub second: u8,
}
impl Timestamp7 {
pub fn year(&self) -> u16 {
self.year.get()
}
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable)]
pub struct Timestamp11 {
pub year: U16LE,
pub month: u8,
pub day: u8,
pub hour: u8,
pub minute: u8,
pub second: u8,
pub microsecond: U32LE,
}
impl Timestamp11 {
pub fn year(&self) -> u16 {
self.year.get()
}
pub fn microsecond(&self) -> u32 {
self.microsecond.get()
}
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable)]
pub struct Time8 {
pub is_negative: u8,
pub days: U32LE,
pub hour: u8,
pub minute: u8,
pub second: u8,
}
impl Time8 {
pub fn is_negative(&self) -> bool {
self.is_negative != 0
}
pub fn days(&self) -> u32 {
self.days.get()
}
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable)]
pub struct Time12 {
pub is_negative: u8,
pub days: U32LE,
pub hour: u8,
pub minute: u8,
pub second: u8,
pub microsecond: U32LE,
}
impl Time12 {
pub fn is_negative(&self) -> bool {
self.is_negative != 0
}
pub fn days(&self) -> u32 {
self.days.get()
}
pub fn microsecond(&self) -> u32 {
self.microsecond.get()
}
}
#[derive(Debug, Clone, Copy)]
pub struct NullBitmap<'a> {
bitmap: &'a [u8],
offset: usize,
}
impl<'a> NullBitmap<'a> {
pub fn for_result_set(bitmap: &'a [u8]) -> Self {
Self { bitmap, offset: 2 }
}
pub fn for_parameters(bitmap: &'a [u8]) -> Self {
Self { bitmap, offset: 0 }
}
pub fn is_null(&self, idx: usize) -> bool {
let bit_pos = idx + self.offset;
let byte_pos = bit_pos >> 3;
let bit_offset = bit_pos & 7;
if byte_pos >= self.bitmap.len() {
return false;
}
(self.bitmap[byte_pos] & (1 << bit_offset)) != 0
}
pub fn as_bytes(&self) -> &'a [u8] {
self.bitmap
}
}