#![allow(dead_code)]
use anyhow::anyhow;
use indexmap::IndexMap;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use serde::Deserialize;
use serde::Serialize;
use std::fmt;
#[cfg(test)]
use log::{trace, warn};
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, FromPrimitive)]
#[repr(i16)]
#[serde(into = "i16", from = "i16")] pub enum VariantTypeId {
Null = 0,
Bit = 1,
Byte = 2,
SByte = 3,
Int16 = 4,
UInt16 = 5,
Int32 = 6,
UInt32 = 7,
Int64 = 8,
UInt64 = 9,
Real32 = 10,
Real64 = 11,
String = 12,
Array = 13,
Object = 14,
}
impl From<VariantTypeId> for i16 {
fn from(variant: VariantTypeId) -> Self {
variant as i16
}
}
impl From<i16> for VariantTypeId {
fn from(value: i16) -> Self {
VariantTypeId::from_i16(value).unwrap()
}
}
impl fmt::Display for VariantTypeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let type_str = match self {
VariantTypeId::Null => "Null",
VariantTypeId::Bit => "Bit",
VariantTypeId::Byte => "Byte",
VariantTypeId::SByte => "SByte",
VariantTypeId::Int16 => "Int16",
VariantTypeId::UInt16 => "UInt16",
VariantTypeId::Int32 => "Int32",
VariantTypeId::UInt32 => "UInt32",
VariantTypeId::Int64 => "Int64",
VariantTypeId::UInt64 => "UInt64",
VariantTypeId::Real32 => "Real32",
VariantTypeId::Real64 => "Real64",
VariantTypeId::String => "String",
VariantTypeId::Array => "Array",
VariantTypeId::Object => "Object",
};
write!(f, "{}", type_str)
}
}
#[derive(Clone, Debug, Default, Serialize, PartialEq, Deserialize)]
pub enum VariantValue {
#[default]
Null,
Bit(bool),
Byte(u8),
SByte(i8),
Int16(i16),
UInt16(u16),
Int32(i32),
UInt32(u32),
Int64(i64),
UInt64(u64),
Real32(f32),
Real64(f64),
String(String),
Array(Vec<VariantValue>),
Object(Box<IndexMap<String, VariantValue>>),
}
impl VariantValue {
pub fn from_json(value: &serde_json::Value) -> Result<Self, anyhow::Error> {
match value {
serde_json::Value::Null => Ok(VariantValue::Null),
serde_json::Value::Bool(b) => Ok(VariantValue::Bit(*b)),
serde_json::Value::Number(num) => {
if let Some(int) = num.as_i64() {
match int {
i if i >= i8::MIN as i64 && i <= i8::MAX as i64 => {
Ok(VariantValue::SByte(int as i8))
}
i if i >= i16::MIN as i64 && i <= i16::MAX as i64 => {
Ok(VariantValue::Int16(int as i16))
}
i if i >= i32::MIN as i64 && i <= i32::MAX as i64 => {
Ok(VariantValue::Int32(int as i32))
}
_i => Ok(VariantValue::Int64(int)),
}
} else if let Some(uint) = num.as_u64() {
match uint {
u if u <= u8::MAX as u64 => Ok(VariantValue::Byte(uint as u8)),
u if u <= u16::MAX as u64 => Ok(VariantValue::UInt16(uint as u16)),
u if u <= u32::MAX as u64 => Ok(VariantValue::UInt32(uint as u32)),
_u => Ok(VariantValue::UInt64(uint)),
}
} else if let Some(float) = num.as_f64() {
Ok(VariantValue::Real64(float))
} else {
Err(anyhow!("Unsupported number type"))
}
}
serde_json::Value::String(s) => Ok(VariantValue::String(s.clone())),
serde_json::Value::Array(arr) => {
let mut elements = vec![];
for item in arr {
elements.push(VariantValue::from_json(item)?);
}
Ok(VariantValue::Array(elements))
}
serde_json::Value::Object(obj) => {
let mut map = IndexMap::new();
for (key, value) in obj {
map.insert(key.clone(), VariantValue::from_json(value)?);
}
Ok(VariantValue::Object(Box::new(map)))
}
}
}
pub fn is_null(&self) -> bool {
match *self {
VariantValue::Null => {
return true;
}
_ => {
return false;
}
}
}
pub fn get_type_id(&self) -> VariantTypeId {
match self {
VariantValue::Null => VariantTypeId::Null,
VariantValue::Bit(_) => VariantTypeId::Bit,
VariantValue::Byte(_) => VariantTypeId::Byte,
VariantValue::SByte(_) => VariantTypeId::SByte,
VariantValue::Int16(_) => VariantTypeId::Int16,
VariantValue::UInt16(_) => VariantTypeId::UInt16,
VariantValue::Int32(_) => VariantTypeId::Int32,
VariantValue::UInt32(_) => VariantTypeId::UInt32,
VariantValue::Int64(_) => VariantTypeId::Int64,
VariantValue::UInt64(_) => VariantTypeId::UInt64,
VariantValue::Real32(_) => VariantTypeId::Real32,
VariantValue::Real64(_) => VariantTypeId::Real64,
VariantValue::String(_) => VariantTypeId::String,
VariantValue::Array(_) => VariantTypeId::Array,
VariantValue::Object(_) => VariantTypeId::Object,
}
}
pub fn to_bool(&self) -> Result<bool, anyhow::Error> {
match *self {
VariantValue::Bit(my_bit) => {
return Ok(my_bit);
}
_ => {
return Err(anyhow!("Cannot convert {} to bool!", *self));
}
}
}
pub fn to_byte(&self) -> Result<u8, anyhow::Error> {
match *self {
VariantValue::Byte(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to byte!", *self));
}
}
}
pub fn to_sbyte(&self) -> Result<i8, anyhow::Error> {
match *self {
VariantValue::SByte(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to sbyte!", *self));
}
}
}
pub fn to_int16(&self) -> Result<i16, anyhow::Error> {
match *self {
VariantValue::Int16(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to int16!", *self));
}
}
}
pub fn to_uint16(&self) -> Result<u16, anyhow::Error> {
match *self {
VariantValue::UInt16(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to uint16!", *self));
}
}
}
pub fn to_int32(&self) -> Result<i32, anyhow::Error> {
match *self {
VariantValue::Int32(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to int32!", *self));
}
}
}
pub fn to_uint32(&self) -> Result<u32, anyhow::Error> {
match *self {
VariantValue::UInt32(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to uint32!", *self));
}
}
}
pub fn to_int64(&self) -> Result<i64, anyhow::Error> {
match *self {
VariantValue::Int64(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to int64!", *self));
}
}
}
pub fn to_uint64(&self) -> Result<u64, anyhow::Error> {
match *self {
VariantValue::UInt64(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to uint64!", *self));
}
}
}
pub fn to_real32(&self) -> Result<f32, anyhow::Error> {
match *self {
VariantValue::Real32(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to real32!", *self));
}
}
}
pub fn to_real64(&self) -> Result<f64, anyhow::Error> {
match *self {
VariantValue::Real64(item) => {
return Ok(item);
}
_ => {
return Err(anyhow!("Cannot convert {} to real64!", *self));
}
}
}
pub fn to_json(&self) -> Result<serde_json::Value, anyhow::Error> {
match &*self {
VariantValue::Null => {
return Err(anyhow!("Cannot serialize a NULL value!"));
}
VariantValue::Bit(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::Byte(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::SByte(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::Int16(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::UInt16(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::Int32(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::UInt32(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::Int64(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::UInt64(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::Real32(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::Real64(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::String(s) => {
return Ok(serde_json::json!(s));
}
VariantValue::Array(elements) => {
let json_elements: Result<Vec<_>, _> =
elements.iter().map(|elem| elem.to_json()).collect();
json_elements.map(serde_json::Value::Array)
}
VariantValue::Object(map) => {
let mut json_map = serde_json::Map::new();
for (key, value) in map.iter() {
json_map.insert(key.clone(), value.to_json()?);
}
Ok(serde_json::Value::Object(json_map))
}
}
}
pub fn to_array(&self) -> Result<&Vec<VariantValue>, anyhow::Error> {
if let VariantValue::Array(vec) = self {
Ok(vec)
} else {
return Err(anyhow!("Cannot convert to array."));
}
}
pub fn convert_to_bool(&self) -> Result<bool, anyhow::Error> {
match self {
VariantValue::Bit(v) => Ok(*v),
VariantValue::Int32(v) => Ok(*v != 0),
VariantValue::Int16(v) => Ok(*v != 0),
VariantValue::UInt16(v) => Ok(*v != 0),
VariantValue::Byte(v) => Ok(*v != 0),
VariantValue::SByte(v) => Ok(*v != 0),
VariantValue::Int64(v) => Ok(*v != 0),
VariantValue::UInt32(v) => Ok(*v != 0),
VariantValue::UInt64(v) => Ok(*v != 0),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to bool!",
self.get_type_id()
)),
}
}
pub fn convert_to_byte(&self) -> Result<u8, anyhow::Error> {
match self {
VariantValue::Bit(v) => Ok(*v as u8),
VariantValue::Byte(v) => Ok(*v),
VariantValue::SByte(v) => Ok(*v as u8),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to Byte!",
self.get_type_id()
)),
}
}
pub fn convert_to_sbyte(&self) -> Result<i8, anyhow::Error> {
match self {
VariantValue::Bit(v) => Ok(*v as i8),
VariantValue::Byte(v) => Ok(*v as i8),
VariantValue::SByte(v) => Ok(*v),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to SByte!",
self.get_type_id()
)),
}
}
pub fn convert_to_int16(&self) -> Result<i16, anyhow::Error> {
match self {
VariantValue::Int16(v) => Ok(*v),
VariantValue::UInt16(v) => Ok(*v as i16),
VariantValue::Byte(v) => Ok(*v as i16),
VariantValue::SByte(v) => Ok(*v as i16),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to Int16!",
self.get_type_id()
)),
}
}
pub fn convert_to_uint16(&self) -> Result<u16, anyhow::Error> {
match self {
VariantValue::Int16(v) => Ok(*v as u16),
VariantValue::UInt16(v) => Ok(*v),
VariantValue::Byte(v) => Ok(*v as u16),
VariantValue::SByte(v) => Ok(*v as u16),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to UInt16!",
self.get_type_id()
)),
}
}
pub fn convert_to_int32(&self) -> Result<i32, anyhow::Error> {
match self {
VariantValue::Int32(v) => Ok(*v),
VariantValue::Int16(v) => Ok(*v as i32),
VariantValue::UInt16(v) => Ok(*v as i32),
VariantValue::Byte(v) => Ok(*v as i32),
VariantValue::SByte(v) => Ok(*v as i32),
VariantValue::UInt32(v) => Ok(*v as i32),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to Int32!",
self.get_type_id()
)),
}
}
pub fn convert_to_uint32(&self) -> Result<u32, anyhow::Error> {
match self {
VariantValue::Int32(v) => Ok(*v as u32),
VariantValue::Int16(v) => Ok(*v as u32),
VariantValue::UInt16(v) => Ok(*v as u32),
VariantValue::Byte(v) => Ok(*v as u32),
VariantValue::SByte(v) => Ok(*v as u32),
VariantValue::UInt32(v) => Ok(*v),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to UInt32!",
self.get_type_id()
)),
}
}
pub fn convert_to_int64(&self) -> Result<i64, anyhow::Error> {
match self {
VariantValue::Int32(v) => Ok(*v as i64),
VariantValue::Int16(v) => Ok(*v as i64),
VariantValue::UInt16(v) => Ok(*v as i64),
VariantValue::Byte(v) => Ok(*v as i64),
VariantValue::SByte(v) => Ok(*v as i64),
VariantValue::UInt32(v) => Ok(*v as i64),
VariantValue::Int64(v) => Ok(*v),
VariantValue::UInt64(v) => Ok(*v as i64),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to Int64!",
self.get_type_id()
)),
}
}
pub fn convert_to_uint64(&self) -> Result<u64, anyhow::Error> {
match self {
VariantValue::Int32(v) => Ok(*v as u64),
VariantValue::Int16(v) => Ok(*v as u64),
VariantValue::UInt16(v) => Ok(*v as u64),
VariantValue::Byte(v) => Ok(*v as u64),
VariantValue::SByte(v) => Ok(*v as u64),
VariantValue::UInt32(v) => Ok(*v as u64),
VariantValue::Int64(v) => Ok(*v as u64),
VariantValue::UInt64(v) => Ok(*v),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to UInt64!",
self.get_type_id()
)),
}
}
pub fn convert_to_real32(&self) -> Result<f32, anyhow::Error> {
match self {
VariantValue::Int32(v) => Ok(*v as f32),
VariantValue::Int16(v) => Ok(*v as f32),
VariantValue::UInt16(v) => Ok(*v as f32),
VariantValue::Byte(v) => Ok(*v as f32),
VariantValue::SByte(v) => Ok(*v as f32),
VariantValue::UInt32(v) => Ok(*v as f32),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to Real32!",
self.get_type_id()
)),
}
}
pub fn convert_to_real64(&self) -> Result<f64, anyhow::Error> {
match self {
VariantValue::Int32(v) => Ok(*v as f64),
VariantValue::Int16(v) => Ok(*v as f64),
VariantValue::UInt16(v) => Ok(*v as f64),
VariantValue::Byte(v) => Ok(*v as f64),
VariantValue::SByte(v) => Ok(*v as f64),
VariantValue::UInt32(v) => Ok(*v as f64),
VariantValue::Int64(v) => Ok(*v as f64),
VariantValue::UInt64(v) => Ok(*v as f64),
VariantValue::Real32(v) => Ok(*v as f64),
VariantValue::Real64(v) => Ok(*v),
_ => Err(anyhow::anyhow!(
"Cannot convert {} to Real64!",
self.get_type_id()
)),
}
}
pub fn is_numeric(&self) -> bool {
return matches!(
self,
VariantValue::Byte(_)
| VariantValue::SByte(_)
| VariantValue::Int16(_)
| VariantValue::UInt16(_)
| VariantValue::Int32(_)
| VariantValue::UInt32(_)
| VariantValue::Int64(_)
| VariantValue::UInt64(_)
| VariantValue::Real32(_)
| VariantValue::Real64(_)
);
}
fn serialize<T>(value: &T) -> Result<Vec<u8>, anyhow::Error>
where
T: Serialize,
{
match postcard::to_allocvec(&value) {
Ok(bytes) => {
return Ok(bytes);
}
Err(err) => {
return Err(anyhow!("Error serializing: {}", err));
}
}
}
pub fn get_bytes(&self) -> Result<Vec<u8>, anyhow::Error> {
match &*self {
VariantValue::Null => {
return Err(anyhow!("Cannot serialize a NULL value!"));
}
VariantValue::Bit(s) => {
return Self::serialize(&s);
}
VariantValue::Byte(s) => {
return Self::serialize(&s);
}
VariantValue::SByte(s) => {
return Self::serialize(&s);
}
VariantValue::Int16(s) => {
return Self::serialize(&s);
}
VariantValue::UInt16(s) => {
return Self::serialize(&s);
}
VariantValue::Int32(s) => {
return Self::serialize(&s);
}
VariantValue::UInt32(s) => {
return Self::serialize(&s);
}
VariantValue::Int64(s) => {
return Self::serialize(&s);
}
VariantValue::UInt64(s) => {
return Self::serialize(&s);
}
VariantValue::Real32(s) => {
return Self::serialize(&s);
}
VariantValue::Real64(s) => {
return Self::serialize(&s);
}
VariantValue::String(s) => {
return Self::serialize(&s);
}
VariantValue::Array(elements) => {
return Self::serialize(elements);
}
VariantValue::Object(map) => {
return Self::serialize(map);
}
}
}
}
impl From<()> for VariantValue {
fn from(_: ()) -> Self {
VariantValue::Null
}
}
impl From<bool> for VariantValue {
fn from(v: bool) -> Self {
VariantValue::Bit(v)
}
}
impl From<u8> for VariantValue {
fn from(v: u8) -> Self {
VariantValue::Byte(v)
}
}
impl From<i8> for VariantValue {
fn from(v: i8) -> Self {
VariantValue::SByte(v)
}
}
impl From<i16> for VariantValue {
fn from(v: i16) -> Self {
VariantValue::Int16(v)
}
}
impl From<u16> for VariantValue {
fn from(v: u16) -> Self {
VariantValue::UInt16(v)
}
}
impl From<i32> for VariantValue {
fn from(v: i32) -> Self {
VariantValue::Int32(v)
}
}
impl From<u32> for VariantValue {
fn from(v: u32) -> Self {
VariantValue::UInt32(v)
}
}
impl From<i64> for VariantValue {
fn from(v: i64) -> Self {
VariantValue::Int64(v)
}
}
impl From<u64> for VariantValue {
fn from(v: u64) -> Self {
VariantValue::UInt64(v)
}
}
impl From<f32> for VariantValue {
fn from(v: f32) -> Self {
VariantValue::Real32(v)
}
}
impl From<f64> for VariantValue {
fn from(v: f64) -> Self {
VariantValue::Real64(v)
}
}
impl<'a> From<&'a str> for VariantValue {
fn from(v: &'a str) -> Self {
VariantValue::String(String::from(v))
}
}
impl From<String> for VariantValue {
fn from(v: String) -> Self {
VariantValue::String(String::from(v))
}
}
impl From<Vec<i32>> for VariantValue {
fn from(v: Vec<i32>) -> Self {
let mut ret = Vec::<VariantValue>::new();
for item in v {
ret.push(VariantValue::from(item));
}
return VariantValue::Array(ret);
}
}
impl From<&[i32]> for VariantValue {
fn from(v: &[i32]) -> Self {
let mut ret = Vec::<VariantValue>::new();
for item in v {
ret.push(VariantValue::from(*item));
}
return VariantValue::Array(ret);
}
}
fn deserialize_primative<'a, T>(stream: &'a Vec<u8>) -> Result<T, anyhow::Error>
where
T: Deserialize<'a>,
{
match postcard::from_bytes::<T>(stream) {
Ok(ret) => {
return Ok(ret);
}
Err(err) => {
return Err(anyhow!("deserialize_primative failed: {}", err));
}
}
}
pub fn from_bytes(type_id: VariantTypeId, bytes: &Vec<u8>) -> Result<VariantValue, anyhow::Error> {
match &type_id {
VariantTypeId::Null => {
return Ok(VariantValue::Null);
}
VariantTypeId::Bit => match deserialize_primative::<bool>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::Bit(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::Byte => match deserialize_primative::<u8>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::Byte(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::SByte => match deserialize_primative::<i8>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::SByte(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::Int16 => match deserialize_primative::<i16>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::Int16(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::UInt16 => match deserialize_primative::<u16>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::UInt16(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::Int32 => match deserialize_primative::<i32>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::Int32(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::UInt32 => match deserialize_primative::<u32>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::UInt32(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::Int64 => match deserialize_primative::<i64>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::Int64(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::UInt64 => match deserialize_primative::<u64>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::UInt64(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::Real32 => match deserialize_primative::<f32>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::Real32(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::Real64 => match deserialize_primative::<f64>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::Real64(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::String => match deserialize_primative::<String>(&bytes) {
Ok(ret) => {
return Ok(VariantValue::String(ret));
}
Err(err) => {
return Err(anyhow!("from_bytes failed: {}", err));
}
},
VariantTypeId::Array => deserialize_primative::<Vec<VariantValue>>(bytes)
.map(VariantValue::Array)
.map_err(|e| e.context("Deserializing an Array failed")),
VariantTypeId::Object => deserialize_primative::<IndexMap<String, VariantValue>>(bytes)
.map(|obj_map| VariantValue::Object(Box::new(obj_map)))
.map_err(|e| e.context("Deserializing an Object failed")),
}
}
impl fmt::Display for VariantValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
VariantValue::Null => write!(f, "<NULL>"),
VariantValue::Bit(v) => write!(f, "{}", v),
VariantValue::Byte(v) => write!(f, "{}", v),
VariantValue::SByte(v) => write!(f, "{}", v),
VariantValue::Int16(v) => write!(f, "{}", v),
VariantValue::UInt16(v) => write!(f, "{}", v),
VariantValue::Int32(v) => write!(f, "{}", v),
VariantValue::UInt32(v) => write!(f, "{}", v),
VariantValue::Int64(v) => write!(f, "{}", v),
VariantValue::UInt64(v) => write!(f, "{}", v),
VariantValue::Real32(v) => write!(f, "{}", v),
VariantValue::Real64(v) => write!(f, "{}", v),
VariantValue::String(v) => write!(f, "{}", v),
VariantValue::Array(elements) => {
let elems_str = elements
.iter()
.map(|elem| format!("{}", elem))
.collect::<Vec<String>>()
.join(", ");
write!(f, "[{}]", elems_str)
}
VariantValue::Object(map) => {
let mut pairs = vec![];
for (key, value) in map.iter() {
let pair = format!("\"{}\": {}", key, value);
pairs.push(pair);
}
let obj_str = pairs.join(", ");
write!(f, "{{{}}}", obj_str)
}
}
}
}
#[test]
pub fn test_variant() {
let mut tst = VariantValue::Bit(true);
assert_ne!(tst.is_null(), true);
assert!(matches!(tst.to_bool(), Ok(true)));
assert!(matches!(tst.to_real32(), Err(_err)));
trace!("tst is awesome {:?}", tst);
tst = VariantValue::from(12);
trace!("Updated tst using from: {:?}", tst);
assert!(matches!(tst.to_int32(), Ok(12)));
assert!(!matches!(tst.to_int16(), Ok(12)));
match tst.get_bytes() {
Ok(bytes) => {
for item in &bytes {
trace!("\t byte [{}]", item);
}
assert_eq!(bytes[0], 12);
let new_var = from_bytes(VariantTypeId::Int32, &bytes).unwrap();
assert!(matches!(new_var.to_int32(), Ok(12)));
}
_ => {
warn!("Failed to serialize bytes!");
panic!();
}
}
let mut map: IndexMap<String, VariantValue> = IndexMap::new();
map.insert(
"key1".to_string(),
VariantValue::String("value1".to_string()),
);
map.insert("key2".to_string(), VariantValue::Int32(42));
let mut var_obj = VariantValue::Object(Box::new(map));
if let VariantValue::Object(ref mut boxed_map) = var_obj {
boxed_map.insert("key3".to_string(), VariantValue::Real64(3.14));
}
let obj_out = format!("{}", var_obj);
assert_eq!(obj_out, "{\"key1\": value1, \"key2\": 42, \"key3\": 3.14}");
}