use crate::Scalar;
use std::borrow::Cow;
use std::fmt::{self, Display, Formatter};
#[cfg(test)]
mod tests;
#[derive(Debug, PartialEq)]
#[non_exhaustive]
pub enum ScalarContents<'a> {
String(Cow<'a, str>),
Bytes(Cow<'a, [u8]>),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
F32(f32),
F64(f64),
Boolean(bool),
Nothing,
Unknown,
}
impl Display for ScalarContents<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
ScalarContents::String(s) => write!(f, "\"{}\"", s.escape_debug()),
ScalarContents::Bytes(b) => {
write!(f, "b\"")?;
for &byte in b.iter().take(64) {
write!(f, "\\x{:02x}", byte)?;
}
if b.len() > 64 {
write!(f, "...")?;
}
write!(f, "\"")
}
ScalarContents::I8(v) => write!(f, "{}", v),
ScalarContents::I16(v) => write!(f, "{}", v),
ScalarContents::I32(v) => write!(f, "{}", v),
ScalarContents::I64(v) => write!(f, "{}", v),
ScalarContents::I128(v) => write!(f, "{}", v),
ScalarContents::U8(v) => write!(f, "{}", v),
ScalarContents::U16(v) => write!(f, "{}", v),
ScalarContents::U32(v) => write!(f, "{}", v),
ScalarContents::U64(v) => write!(f, "{}", v),
ScalarContents::U128(v) => write!(f, "{}", v),
ScalarContents::F32(v) => write!(f, "{}", v),
ScalarContents::F64(v) => write!(f, "{}", v),
ScalarContents::Boolean(v) => write!(f, "{}", v),
ScalarContents::Nothing => write!(f, "()"),
ScalarContents::Unknown => write!(f, "<unknown>"),
}
}
}
impl Scalar {
pub unsafe fn get_contents<'a>(&self, ptr: *const u8) -> ScalarContents<'a> {
unsafe {
match self {
Scalar::String => {
let string_ref = &*(ptr as *const String);
ScalarContents::String(Cow::Borrowed(string_ref.as_str()))
}
Scalar::Bytes => {
let bytes_ref = &*(ptr as *const Vec<u8>);
ScalarContents::Bytes(Cow::Borrowed(bytes_ref.as_slice()))
}
Scalar::I8 => ScalarContents::I8(*(ptr as *const i8)),
Scalar::I16 => ScalarContents::I16(*(ptr as *const i16)),
Scalar::I32 => ScalarContents::I32(*(ptr as *const i32)),
Scalar::I64 => ScalarContents::I64(*(ptr as *const i64)),
Scalar::I128 => ScalarContents::I128(*(ptr as *const i128)),
Scalar::U8 => ScalarContents::U8(*ptr),
Scalar::U16 => ScalarContents::U16(*(ptr as *const u16)),
Scalar::U32 => ScalarContents::U32(*(ptr as *const u32)),
Scalar::U64 => ScalarContents::U64(*(ptr as *const u64)),
Scalar::U128 => ScalarContents::U128(*(ptr as *const u128)),
Scalar::F32 => ScalarContents::F32(*(ptr as *const f32)),
Scalar::F64 => ScalarContents::F64(*(ptr as *const f64)),
Scalar::Boolean => ScalarContents::Boolean(*(ptr as *const bool)),
Scalar::Nothing => ScalarContents::Nothing,
}
}
}
}