1use crate::Scalar;
2use std::borrow::Cow;
3use std::fmt::{self, Display, Formatter};
4
5#[derive(Debug, PartialEq)]
8#[non_exhaustive]
9pub enum ScalarContents<'a> {
10 String(Cow<'a, str>),
12
13 Bytes(Cow<'a, [u8]>),
15
16 I8(i8),
18
19 I16(i16),
21
22 I32(i32),
24
25 I64(i64),
27
28 I128(i128),
30
31 U8(u8),
33
34 U16(u16),
36
37 U32(u32),
39
40 U64(u64),
42
43 U128(u128),
45
46 F32(f32),
48
49 F64(f64),
51
52 Boolean(bool),
54
55 Nothing,
57
58 Unknown,
60}
61
62impl Display for ScalarContents<'_> {
63 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
64 match self {
65 ScalarContents::String(s) => write!(f, "\"{}\"", s.escape_debug()),
66 ScalarContents::Bytes(b) => {
67 write!(f, "b\"")?;
68 for &byte in b.iter().take(64) {
69 write!(f, "\\x{:02x}", byte)?;
70 }
71 if b.len() > 64 {
72 write!(f, "...")?;
73 }
74 write!(f, "\"")
75 }
76 ScalarContents::I8(v) => write!(f, "{}", v),
77 ScalarContents::I16(v) => write!(f, "{}", v),
78 ScalarContents::I32(v) => write!(f, "{}", v),
79 ScalarContents::I64(v) => write!(f, "{}", v),
80 ScalarContents::I128(v) => write!(f, "{}", v),
81 ScalarContents::U8(v) => write!(f, "{}", v),
82 ScalarContents::U16(v) => write!(f, "{}", v),
83 ScalarContents::U32(v) => write!(f, "{}", v),
84 ScalarContents::U64(v) => write!(f, "{}", v),
85 ScalarContents::U128(v) => write!(f, "{}", v),
86 ScalarContents::F32(v) => write!(f, "{}", v),
87 ScalarContents::F64(v) => write!(f, "{}", v),
88 ScalarContents::Boolean(v) => write!(f, "{}", v),
89 ScalarContents::Nothing => write!(f, "()"),
90 ScalarContents::Unknown => write!(f, "<unknown>"),
91 }
92 }
93}
94
95impl Scalar {
96 pub unsafe fn get_contents<'a>(&self, ptr: *const u8) -> ScalarContents<'a> {
106 unsafe {
109 match self {
110 Scalar::String => {
111 let string_ref = &*(ptr as *const String);
113 ScalarContents::String(Cow::Borrowed(string_ref.as_str()))
114 }
115 Scalar::Bytes => {
116 let bytes_ref = &*(ptr as *const Vec<u8>);
118 ScalarContents::Bytes(Cow::Borrowed(bytes_ref.as_slice()))
119 }
120 Scalar::I8 => ScalarContents::I8(*(ptr as *const i8)),
121 Scalar::I16 => ScalarContents::I16(*(ptr as *const i16)),
122 Scalar::I32 => ScalarContents::I32(*(ptr as *const i32)),
123 Scalar::I64 => ScalarContents::I64(*(ptr as *const i64)),
124 Scalar::I128 => ScalarContents::I128(*(ptr as *const i128)),
125 Scalar::U8 => ScalarContents::U8(*ptr),
126 Scalar::U16 => ScalarContents::U16(*(ptr as *const u16)),
127 Scalar::U32 => ScalarContents::U32(*(ptr as *const u32)),
128 Scalar::U64 => ScalarContents::U64(*(ptr as *const u64)),
129 Scalar::U128 => ScalarContents::U128(*(ptr as *const u128)),
130 Scalar::F32 => ScalarContents::F32(*(ptr as *const f32)),
131 Scalar::F64 => ScalarContents::F64(*(ptr as *const f64)),
132 Scalar::Boolean => ScalarContents::Boolean(*(ptr as *const bool)),
133 Scalar::Nothing => ScalarContents::Nothing,
134 }
135 }
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142
143 #[test]
144 fn test_scalar_contents_display() {
145 assert_eq!(
146 format!("{}", ScalarContents::String(Cow::Borrowed("hello"))),
147 "\"hello\""
148 );
149 assert_eq!(format!("{}", ScalarContents::I32(42)), "42");
150 assert_eq!(format!("{}", ScalarContents::Boolean(true)), "true");
151 assert_eq!(format!("{}", ScalarContents::Nothing), "()");
152 }
153}