use std::marker::PhantomData;
use std::net::Ipv4Addr;
use std::net::Ipv6Addr;
use std::sync::Arc;
use super::column_data::ColumnData;
use super::ColumnFrom;
use crate::binary::Encoder;
use crate::binary::ReadEx;
use crate::errors::Result;
use crate::types::column::column_data::BoxColumnData;
use crate::types::column::nullable::NullableColumnData;
use crate::types::column::ColumnWrapper;
use crate::types::SqlType;
use crate::types::Value;
use crate::types::ValueRef;
pub(crate) trait IpVersion: Copy + Sync + Send + 'static {
fn sql_type() -> SqlType;
fn size() -> usize;
fn push(inner: &mut Vec<u8>, value: Value);
fn get(inner: &[u8], index: usize) -> ValueRef;
}
#[derive(Copy, Clone)]
pub(crate) struct Ipv4;
#[derive(Copy, Clone)]
pub(crate) struct Ipv6;
#[derive(Copy, Clone)]
pub(crate) struct Uuid;
impl IpVersion for Ipv4 {
#[inline(always)]
fn sql_type() -> SqlType {
SqlType::Ipv4
}
#[inline(always)]
fn size() -> usize {
4
}
#[inline(always)]
fn push(inner: &mut Vec<u8>, value: Value) {
if let Value::Ipv4(v) = value {
inner.extend(v);
} else {
panic!();
}
}
#[inline(always)]
fn get(inner: &[u8], index: usize) -> ValueRef {
let mut v: [u8; 4] = Default::default();
v.copy_from_slice(&inner[index * 4..(index + 1) * 4]);
ValueRef::Ipv4(v)
}
}
impl IpVersion for Ipv6 {
#[inline(always)]
fn sql_type() -> SqlType {
SqlType::Ipv6
}
#[inline(always)]
fn size() -> usize {
16
}
#[inline(always)]
fn push(inner: &mut Vec<u8>, value: Value) {
if let Value::Ipv6(v) = value {
inner.extend(v);
} else {
panic!();
}
}
#[inline(always)]
fn get(inner: &[u8], index: usize) -> ValueRef {
let mut v: [u8; 16] = Default::default();
v.copy_from_slice(&inner[index * 16..(index + 1) * 16]);
ValueRef::Ipv6(v)
}
}
impl IpVersion for Uuid {
#[inline(always)]
fn sql_type() -> SqlType {
SqlType::Uuid
}
#[inline(always)]
fn size() -> usize {
16
}
#[inline(always)]
fn push(inner: &mut Vec<u8>, value: Value) {
if let Value::Uuid(v) = value {
inner.extend(v);
} else {
panic!();
}
}
#[inline(always)]
fn get(inner: &[u8], index: usize) -> ValueRef {
let mut v: [u8; 16] = Default::default();
v.copy_from_slice(&inner[index * 16..(index + 1) * 16]);
ValueRef::Uuid(v)
}
}
impl ColumnFrom for Vec<Ipv4Addr> {
fn column_from<W: ColumnWrapper>(data: Self) -> W::Wrapper {
let mut inner = Vec::with_capacity(data.len());
for ip in data {
let mut buffer = ip.octets();
buffer.reverse();
inner.extend(buffer);
}
W::wrap(IpColumnData::<Ipv4> {
inner,
phantom: PhantomData,
})
}
}
impl ColumnFrom for Vec<Ipv6Addr> {
fn column_from<W: ColumnWrapper>(data: Self) -> W::Wrapper {
let mut inner = Vec::with_capacity(data.len());
for ip in data {
inner.extend(ip.octets());
}
W::wrap(IpColumnData::<Ipv6> {
inner,
phantom: PhantomData,
})
}
}
impl ColumnFrom for Vec<uuid::Uuid> {
fn column_from<W: ColumnWrapper>(data: Self) -> W::Wrapper {
let mut inner = Vec::with_capacity(data.len());
for uuid in data {
let mut buffer = *uuid.as_bytes();
buffer[..8].reverse();
buffer[8..].reverse();
inner.extend(buffer);
}
W::wrap(IpColumnData::<Uuid> {
inner,
phantom: PhantomData,
})
}
}
impl ColumnFrom for Vec<Option<Ipv4Addr>> {
fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
let n = source.len();
let mut inner: Vec<u8> = Vec::with_capacity(n * 4);
let mut nulls: Vec<u8> = Vec::with_capacity(n);
for ip in source {
match ip {
None => {
inner.extend([0; 4]);
nulls.push(1);
}
Some(ip) => {
let mut buffer = ip.octets();
buffer.reverse();
inner.extend(buffer);
nulls.push(0);
}
}
}
let inner = Arc::new(IpColumnData::<Ipv4> {
inner,
phantom: PhantomData,
});
let data = NullableColumnData { inner, nulls };
W::wrap(data)
}
}
impl ColumnFrom for Vec<Option<Ipv6Addr>> {
fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
let n = source.len();
let mut inner: Vec<u8> = Vec::with_capacity(n * 16);
let mut nulls: Vec<u8> = Vec::with_capacity(n);
for ip in source {
match ip {
None => {
inner.extend([0; 16]);
nulls.push(1);
}
Some(ip) => {
inner.extend(ip.octets());
nulls.push(0);
}
}
}
let inner = Arc::new(IpColumnData::<Ipv6> {
inner,
phantom: PhantomData,
});
let data = NullableColumnData { inner, nulls };
W::wrap(data)
}
}
impl ColumnFrom for Vec<Option<uuid::Uuid>> {
fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
let n = source.len();
let mut inner: Vec<u8> = Vec::with_capacity(n * 16);
let mut nulls: Vec<u8> = Vec::with_capacity(n);
for uuid in source {
match uuid {
None => {
inner.extend([0; 16]);
nulls.push(1);
}
Some(uuid) => {
let mut buffer = *uuid.as_bytes();
buffer[..8].reverse();
buffer[8..].reverse();
inner.extend(buffer);
nulls.push(0);
}
}
}
let inner = Arc::new(IpColumnData::<Uuid> {
inner,
phantom: PhantomData,
});
let data = NullableColumnData { inner, nulls };
W::wrap(data)
}
}
pub(crate) struct IpColumnData<V: IpVersion> {
pub(crate) inner: Vec<u8>,
pub(crate) phantom: PhantomData<V>,
}
impl<V: IpVersion> IpColumnData<V> {
pub fn with_capacity(capacity: usize) -> Self {
Self {
inner: vec![0; capacity * V::size()],
phantom: PhantomData,
}
}
pub(crate) fn load<R: ReadEx>(reader: &mut R, size: usize) -> Result<Self> {
let mut inner = vec![0; size * V::size()];
reader.read_bytes(inner.as_mut())?;
Ok(Self {
inner,
phantom: PhantomData,
})
}
}
impl<V: IpVersion> ColumnData for IpColumnData<V> {
fn sql_type(&self) -> SqlType {
V::sql_type()
}
fn save(&self, encoder: &mut Encoder, start: usize, end: usize) {
let start_index = start * V::size();
let end_index = end * V::size();
let slice: &[u8] = self.inner.as_ref();
encoder.write_bytes(&slice[start_index..end_index]);
}
fn len(&self) -> usize {
self.inner.len() / V::size()
}
fn push(&mut self, value: Value) {
V::push(&mut self.inner, value)
}
fn at(&self, index: usize) -> ValueRef {
V::get(&self.inner, index)
}
fn clone_instance(&self) -> BoxColumnData {
Box::new(Self {
inner: self.inner.clone(),
phantom: PhantomData,
})
}
unsafe fn get_internal(&self, pointers: &[*mut *const u8], level: u8) -> Result<()> {
assert_eq!(level, 0);
*pointers[0] = &self.inner as *const Vec<u8> as *const u8;
Ok(())
}
}