use super::number::Number;
use super::value_ref::ValueRef;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use messagepack_core::extension::{ExtensionOwned, ExtensionRef};
use serde::{de::Visitor, ser::SerializeMap};
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Value {
Nil,
Bool(bool),
Bin(Vec<u8>),
Extension(ExtensionOwned),
Number(Number),
String(String),
Array(Vec<Value>),
Map(Vec<(Value, Value)>),
}
impl Value {
pub fn is_nil(&self) -> bool {
matches!(self, Value::Nil)
}
pub fn as_bool(&self) -> Option<bool> {
match self {
Value::Bool(v) => Some(*v),
_ => None,
}
}
pub fn as_bin(&self) -> Option<&[u8]> {
match self {
Value::Bin(v) => Some(v.as_slice()),
_ => None,
}
}
pub fn as_extension(&self) -> Option<ExtensionRef<'_>> {
match self {
Value::Extension(ext) => Some(ext.as_ref()),
_ => None,
}
}
pub fn as_number(&self) -> Option<Number> {
match self {
Value::Number(v) => Some(*v),
_ => None,
}
}
pub fn as_string(&self) -> Option<&str> {
match self {
Value::String(v) => Some(v.as_str()),
_ => None,
}
}
pub fn as_array(&self) -> Option<&[Value]> {
match self {
Value::Array(v) => Some(v.as_slice()),
_ => None,
}
}
pub fn as_map(&self) -> Option<&[(Value, Value)]> {
match self {
Value::Map(v) => Some(v.as_slice()),
_ => None,
}
}
}
impl serde::Serialize for Value {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
Value::Nil => serializer.serialize_none(),
Value::Bool(v) => serializer.serialize_bool(*v),
Value::Bin(b) => serializer.serialize_bytes(b),
Value::Extension(ext) => {
crate::extension::ext_ref::serialize(&ext.as_ref(), serializer)
}
Value::Number(n) => n.serialize(serializer),
Value::String(s) => serializer.serialize_str(s),
Value::Array(vs) => vs.serialize(serializer),
Value::Map(items) => {
let mut map = serializer.serialize_map(Some(items.len()))?;
for (k, v) in items.iter() {
map.serialize_entry(k, v)?;
}
map.end()
}
}
}
}
impl<'de> serde::Deserialize<'de> for Value {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = Value;
fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.write_str("expect valid messagepack")
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Bool(v))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::from(v))
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::from(v))
}
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::from(v))
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::from(v))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::from(v))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::from(v))
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Nil)
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Nil)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Bin(v.to_vec()))
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Bin(v))
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let ext = crate::extension::ext_owned::deserialize(deserializer)?;
Ok(Value::Extension(ext))
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut buf =
Vec::with_capacity(super::cautiously_size_hint::<Value>(seq.size_hint()));
while let Some(v) = seq.next_element::<Value>()? {
buf.push(v);
}
Ok(Value::Array(buf))
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let mut buf = Vec::with_capacity(super::cautiously_size_hint::<(Value, Value)>(
map.size_hint(),
));
while let Some(v) = map.next_entry::<Value, Value>()? {
buf.push(v);
}
Ok(Value::Map(buf))
}
}
deserializer.deserialize_any(ValueVisitor)
}
}
impl From<()> for Value {
fn from(_: ()) -> Self {
Value::Nil
}
}
impl From<bool> for Value {
fn from(v: bool) -> Self {
Value::Bool(v)
}
}
impl From<u8> for Value {
fn from(v: u8) -> Self {
Value::Number(Number::from(v))
}
}
impl From<u16> for Value {
fn from(v: u16) -> Self {
Value::Number(Number::from(v))
}
}
impl From<u32> for Value {
fn from(v: u32) -> Self {
Value::Number(Number::from(v))
}
}
impl From<u64> for Value {
fn from(v: u64) -> Self {
Value::Number(Number::from(v))
}
}
impl From<i8> for Value {
fn from(v: i8) -> Self {
Value::Number(Number::from(v))
}
}
impl From<i16> for Value {
fn from(v: i16) -> Self {
Value::Number(Number::from(v))
}
}
impl From<i32> for Value {
fn from(v: i32) -> Self {
Value::Number(Number::from(v))
}
}
impl From<i64> for Value {
fn from(v: i64) -> Self {
Value::Number(Number::from(v))
}
}
impl From<f32> for Value {
fn from(v: f32) -> Self {
Value::Number(Number::Float(v.into()))
}
}
impl From<f64> for Value {
fn from(v: f64) -> Self {
Value::Number(Number::Float(v))
}
}
impl From<Number> for Value {
fn from(v: Number) -> Self {
Value::Number(v)
}
}
impl TryFrom<usize> for Value {
type Error = core::num::TryFromIntError;
fn try_from(value: usize) -> Result<Self, Self::Error> {
Number::try_from(value).map(Self::from)
}
}
impl TryFrom<isize> for Value {
type Error = core::num::TryFromIntError;
fn try_from(value: isize) -> Result<Self, Self::Error> {
Number::try_from(value).map(Self::from)
}
}
impl From<&str> for Value {
fn from(v: &str) -> Self {
Value::String(v.to_string())
}
}
impl From<String> for Value {
fn from(v: String) -> Self {
Value::String(v)
}
}
impl From<&[u8]> for Value {
fn from(v: &[u8]) -> Self {
Value::Bin(v.to_vec())
}
}
impl From<Vec<u8>> for Value {
fn from(v: Vec<u8>) -> Self {
Value::Bin(v)
}
}
impl From<ExtensionOwned> for Value {
fn from(v: ExtensionOwned) -> Self {
Value::Extension(v)
}
}
impl From<ValueRef<'_>> for Value {
fn from(v: ValueRef<'_>) -> Self {
match v {
ValueRef::Nil => Value::Nil,
ValueRef::Bool(b) => Value::Bool(b),
ValueRef::Bin(b) => Value::Bin(b.to_vec()),
ValueRef::Extension(ext) => Value::Extension(ext.into()),
ValueRef::Number(n) => Value::Number(n),
ValueRef::String(s) => Value::String(s.to_string()),
ValueRef::Array(items) => Value::Array(items.into_iter().map(Value::from).collect()),
ValueRef::Map(items) => Value::Map(
items
.into_iter()
.map(|(k, v)| (Value::from(k), Value::from(v)))
.collect(),
),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{from_slice, to_slice};
#[test]
fn owned_roundtrip_primitives() {
let cases = [
Value::Nil,
Value::Bool(true),
Value::Number(Number::from(7u64)),
Value::Number(Number::from(-3i64)),
Value::Number(Number::Float(1.25)),
Value::String("hi".to_string()),
Value::Bin(vec![0x01, 0x02]),
];
for v in cases.iter() {
let mut buf = [0u8; 32];
let len = to_slice(v, &mut buf).unwrap();
let decoded = from_slice::<Value>(&buf[..len]).unwrap();
assert_eq!(&decoded, v);
}
}
#[test]
fn owned_nested_roundtrip() {
let v = Value::Array(vec![
Value::Map(vec![
(Value::String("k".into()), Value::Bool(false)),
(Value::Number(1u64.into()), Value::String("v".into())),
]),
Value::Extension(ExtensionOwned {
r#type: 1,
data: vec![0x12, 0x34],
}),
]);
let mut buf = [0u8; 128];
let len = to_slice(&v, &mut buf).unwrap();
let decoded = from_slice::<Value>(&buf[..len]).unwrap();
assert_eq!(decoded, v);
}
}
#[cfg(all(test, feature = "std"))]
mod reader_tests {
use super::*;
use crate::from_reader;
#[test]
fn value_owned_from_reader_str_and_bin() {
let mut r1 = std::io::Cursor::new([0xa2, 0x68, 0x69]);
let v1: Value = from_reader(&mut r1).unwrap();
assert_eq!(v1.as_string(), Some("hi"));
let mut r2 = std::io::Cursor::new([0xc4, 0x03, 0x01, 0x02, 0x03]);
let v2: Value = from_reader(&mut r2).unwrap();
assert_eq!(v2.as_bin(), Some(&[1u8, 2, 3][..]));
}
}