use std::{
collections::{BTreeMap, HashMap},
net::{IpAddr, Ipv6Addr, SocketAddrV6},
num::{NonZeroU32, NonZeroU64},
};
use arrayvec::{ArrayString, ArrayVec};
#[cfg(feature = "std")]
use bytes::Bytes;
#[cfg(feature = "rust_decimal")]
use rust_decimal::Decimal;
#[cfg(feature = "std")]
use serde_json::Value;
#[cfg(feature = "smallvec")]
use smallvec::SmallVec;
use uuid::Uuid;
use crate::scalar::ScalarTyp;
use crate::typ::{EnumType, Fields, StructType, Typ};
pub trait GetType {
const TYPE: Typ;
}
impl GetType for bool {
const TYPE: Typ = Typ::Scalar(ScalarTyp::Bool);
}
impl GetType for u8 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::U8);
}
impl GetType for u16 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::U16);
}
impl GetType for u32 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::U32);
}
impl GetType for u64 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::U64);
}
impl GetType for usize {
const TYPE: Typ = Typ::Scalar(ScalarTyp::U32);
}
impl GetType for i32 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::I32);
}
impl GetType for i64 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::I64);
}
impl GetType for f32 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::F32);
}
impl GetType for f64 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::F64);
}
impl GetType for NonZeroU32 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::U32);
}
impl GetType for NonZeroU64 {
const TYPE: Typ = Typ::Scalar(ScalarTyp::U64);
}
impl GetType for String {
const TYPE: Typ = Typ::Scalar(ScalarTyp::Str);
}
impl GetType for time::Duration {
const TYPE: Typ = Typ::Scalar(ScalarTyp::I64);
}
impl GetType for time::OffsetDateTime {
const TYPE: Typ = Typ::Scalar(ScalarTyp::Datetime);
}
impl GetType for time::PrimitiveDateTime {
const TYPE: Typ = Typ::Scalar(ScalarTyp::Datetime);
}
impl GetType for time::Date {
const TYPE: Typ = Typ::Scalar(ScalarTyp::I32);
}
impl GetType for time::Time {
const TYPE: Typ = Typ::Scalar(ScalarTyp::U32);
}
impl<T: GetType> GetType for Vec<T> {
const TYPE: Typ = Typ::Vec(&T::TYPE);
}
impl<T: GetType, const CAP: usize> GetType for ArrayVec<T, CAP> {
const TYPE: Typ = Typ::Vec(&T::TYPE);
}
impl<const CAP: usize> GetType for ArrayString<CAP> {
const TYPE: Typ = Typ::Scalar(ScalarTyp::Str);
}
#[cfg(feature = "smallvec")]
impl<T: GetType, const CAP: usize> GetType for SmallVec<[T; CAP]> {
const TYPE: Typ = Typ::Vec(&T::TYPE);
}
#[cfg(feature = "rust_decimal")]
impl GetType for Decimal {
const TYPE: Typ = Typ::Scalar(ScalarTyp::Decimal);
}
impl<T: GetType> GetType for Option<T> {
const TYPE: Typ = Typ::Optional(&T::TYPE);
}
impl<T: GetType> GetType for Box<T> {
const TYPE: Typ = T::TYPE;
}
impl<T1: GetType, T2: GetType> GetType for (T1, T2) {
const TYPE: Typ = {
let fields = &[T1::TYPE, T2::TYPE];
Typ::Struct(StructType {
name: "",
fields: Fields::Unnamed(fields),
})
};
}
impl<T1: GetType, T2: GetType, T3: GetType> GetType for (T1, T2, T3) {
const TYPE: Typ = {
let fields = &[T1::TYPE, T2::TYPE, T3::TYPE];
Typ::Struct(StructType {
name: "",
fields: Fields::Unnamed(fields),
})
};
}
impl<T1: GetType, T2: GetType, T3: GetType, T4: GetType> GetType for (T1, T2, T3, T4) {
const TYPE: Typ = {
let fields = &[T1::TYPE, T2::TYPE, T3::TYPE, T4::TYPE];
Typ::Struct(StructType {
name: "",
fields: Fields::Unnamed(fields),
})
};
}
impl<K: GetType, V: GetType> GetType for HashMap<K, V> {
const TYPE: Typ = Typ::Vec(&<(K, V)>::TYPE);
}
impl<K: GetType, V: GetType> GetType for BTreeMap<K, V> {
const TYPE: Typ = Typ::Vec(&<(K, V)>::TYPE);
}
impl<const CAP: usize> GetType for [u8; CAP] {
const TYPE: Typ = Typ::Scalar(ScalarTyp::ArrayBytes(CAP as u32));
}
impl GetType for Ipv6Addr {
const TYPE: Typ = Typ::Scalar(ScalarTyp::ArrayBytes(16));
}
impl GetType for IpAddr {
const TYPE: Typ = {
let variants = &[
(0, ("Ipv4Addr", Typ::Scalar(ScalarTyp::ArrayBytes(4)))),
(1, ("Ipv6Addr", Ipv6Addr::TYPE)),
];
Typ::Enum(EnumType {
name: "IpAddr",
variants,
})
};
}
impl GetType for SocketAddrV6 {
const TYPE: Typ = {
let fields = Fields::Unnamed(&[Ipv6Addr::TYPE, u16::TYPE]);
let socket_addr_v6 = StructType {
name: "SocketAddrV6",
fields,
};
Typ::Struct(socket_addr_v6)
};
}
#[cfg(feature = "std")]
impl GetType for Bytes {
const TYPE: Typ = Typ::Scalar(ScalarTyp::Bytes);
}
#[cfg(feature = "std")]
impl GetType for Value {
const TYPE: Typ = Typ::Scalar(ScalarTyp::RustJson);
}
impl GetType for Uuid {
const TYPE: Typ = Typ::Scalar(ScalarTyp::ArrayBytes(16));
}
#[cfg(feature = "solana")]
impl GetType for solana_pubkey::Pubkey {
const TYPE: Typ = Typ::Scalar(ScalarTyp::ArrayBytes(32));
}
#[cfg(feature = "solana")]
impl GetType for solana_signature::Signature {
const TYPE: Typ = Typ::Scalar(ScalarTyp::ArrayBytes(64));
}
#[cfg(feature = "compact_str")]
impl GetType for compact_str::CompactString {
const TYPE: Typ = Typ::Scalar(ScalarTyp::Str);
}
#[cfg(feature = "smol_str")]
impl GetType for smol_str::SmolStr {
const TYPE: Typ = Typ::Scalar(ScalarTyp::Str);
}