rmpv-1.3.0/.cargo_vcs_info.json0000644000000001420000000000100120160ustar { "git": { "sha1": "52de9be5a3c9117261bd3e6edffe29aa2eb1f936" }, "path_in_vcs": "rmpv" }rmpv-1.3.0/CHANGELOG.md000064400000000000000000000052131046102023000124230ustar 00000000000000# Change Log All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased ## 0.4.1 - 2017-06-27 ### Added - Add `as_ref()` to `Value` and `Utf8String` (#139). ### Changed - (Breaking) Serialize newtype structs by serializing its inner type without wrapping into a tuple. (#146). ## 0.4.0 - 2017-04-24 ### Added - Implement `Deserialize` for `ValueRef<'de>`. - Implement `Deserializer` for `ValueRef<'de>`. - Implement `Deserializer` for `&'de ValueRef<'de>`. - Zero-copy deserialization from `ValueRef`. ### Changed - Adapt with serde 1.0. ## 0.3.4 - 2017-03-26 ### Fixed - Fix compilation on rustc 1.13. ## 0.3.3 - 2017-03-26 ### Changed - Enum deserializer can now deserialize newtype variants with more than one element nested. ## 0.3.2 - 2017-03-13 ### Fixed - Fixed double-quoting for strings when formatting a `ValueRef` using `Display` trait. ## 0.3.1 - 2017-03-11 ### Added - Implement `From` for `std::io::Error`. ## 0.3.0 - 2017-03-09 ### Added - Implement `Deserializer` and `Serializer` for `Value`. - Add `kind()` method for `rmpv::decode::Error`. - Implement `Error` and `Display` traits for `rmpv::decode::Error`. - Implement `From` trait for `Value` and `ValueRef` from all integral types, strings, slices and other more. ### Changed - Reserved markers are now decoded as nil instead of raising `Error::TypeMismatch`. - Integer representation for `Value` and `ValueRef` has been changed and hidden from the user to be able to fully match the spec and to fix round-trip cases. - Invalid UTF-8 strings can now be properly decoded into `Value` and `ValueRef` to match the spec. An untouched bytes can also be returned on demand as like as `Utf8Error` with description where invalid byte-sequence happened. - Error enums for decoding `Value` and `ValueRef` has been merged into the single one, which is located at `rmpv::decode::Error`. ### Removed - Remove `TypeMismatch` variant from `value::decode::Error`, because there is no way to obtain it. - Remove `FromUtf8Error` variant from `value::decode::Error`, because there invalid UTF-8 sequences are now supported. ## 0.2.0 - 2017-02-09 ### Added - `Serde` 0.9 support. - `ValueRef` can now be displayed. - `ValueRef` can be indexed using special `index(..)` method. Implementing `Index` trait is not possible due to conflicting signature - `ValueRef` requires explicit lifetime. - It's now possible to obtain `ErrorKind` for Errors. ## 0.1.0 - 2017-01-05 ### Removed - Value now saves integer and floating point numbers directly without intermediate `Integer` and `Float` enums. As a result, they were removed. rmpv-1.3.0/Cargo.toml0000644000000024200000000000100100150ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.70" name = "rmpv" version = "1.3.0" authors = ["Evgeny Safronov "] description = "Value variant for RMP" documentation = "https://docs.rs/rmpv" readme = "README.md" keywords = [ "msgpack", "MessagePack", "serialization", ] categories = ["encoding"] license = "MIT" repository = "https://github.com/3Hren/msgpack-rust" [package.metadata.release] tag-prefix = "{{crate_name}}/" [dependencies.num-traits] version = "0.2.14" [dependencies.rmp] version = "0.8.14" [dependencies.serde] version = "1.0.197" optional = true [dependencies.serde_bytes] version = "0.11.5" optional = true [dev-dependencies.quickcheck] version = "1.0.2" [features] with-serde = [ "serde", "serde_bytes", ] [badges.maintenance] status = "looking-for-maintainer" rmpv-1.3.0/Cargo.toml.orig000064400000000000000000000014161046102023000135020ustar 00000000000000[package] name = "rmpv" version = "1.3.0" authors = ["Evgeny Safronov "] license = "MIT" description = "Value variant for RMP" repository = "https://github.com/3Hren/msgpack-rust" documentation = "https://docs.rs/rmpv" readme = "README.md" keywords = ["msgpack", "MessagePack", "serialization"] categories = ["encoding"] edition = "2021" rust-version = "1.70" [features] with-serde = ["serde", "serde_bytes"] [dependencies] serde_bytes = { version = "0.11.5", optional = true } rmp = { version = "0.8.14", path = "../rmp" } num-traits = "0.2.14" serde = { version = "1.0.197", optional = true } [dev-dependencies] quickcheck = "1.0.2" [package.metadata.release] tag-prefix = "{{crate_name}}/" [badges] maintenance = { status = "looking-for-maintainer" } rmpv-1.3.0/LICENSE000064400000000000000000000020601046102023000116140ustar 00000000000000MIT License Copyright (c) 2017 Evgeny Safronov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. rmpv-1.3.0/README.md000064400000000000000000000053541046102023000120770ustar 00000000000000# RMP - Rust MessagePack RMP is a complete pure-Rust [MessagePack](http://msgpack.org) implementation. MessagePack a compact self-describing binary serialization format. This project consists of three crates: * [RMP-Serde][crates-rmps-url] ([Documentation][rmps-docs-url]) — easy serializing/deserializing via [Serde](https://serde.rs). * [RMP-Value][crates-rmpv-url] ([Documentation][rmpv-docs-url]) — a universal `Value` enum that can hold any MessagePack type. Allows deserializing arbitrary messages without a known schema. * [RMP][crates-rmp-url] ([Documentation][rmp-docs-url]) — low-level functions for reading/writing encoded data. ## Features - **Convenient and powerful APIs** RMP is designed to be lightweight and straightforward. There is a high-level API with support for Serde, which provides you convenient interface for encode/decode Rust's data structures using `derive` attribute. There are also low-level APIs, which give you full control over data encoding/decoding process, with no-std support and without heap allocations. - **Zero-copy value decoding** RMP allows to decode bytes from a buffer in a zero-copy manner. Parsing is implemented in safe Rust. - **Robust, stable and tested** This project is developed using TDD and CI, so any found bugs will be fixed without breaking existing functionality. ## Why MessagePack? It's smaller and much simpler to parse than JSON. The encoded data is self-describing and extensible, without using any schema definitions. It supports the same data types as JSON, plus binary data, non-string map keys, all float values, and 64-bit numbers. Msgpack values use `` encoding, so they can be safely concatenated and read from a stream. MessagePack is similar to CBOR, but has simpler data types (no bignums, decimal floats, dates, or indefinite-length sets, etc.) ## Requirements - An up-to-date stable version of [Rust](https://www.rust-lang.org), preferably from [rustup](https://rustup.rs). [rustc-serialize]: https://github.com/rust-lang-nursery/rustc-serialize [serde]: https://github.com/serde-rs/serde [ci-img]: https://github.com/3Hren/msgpack-rust/actions/workflows/ci.yml/badge.svg [ci-url]: https://github.com/3Hren/msgpack-rust/actions/workflows/ci.yml [coveralls-img]: https://coveralls.io/repos/3Hren/msgpack-rust/badge.svg?branch=master&service=github [coveralls-url]: https://coveralls.io/github/3Hren/msgpack-rust?branch=master [rmp-docs-url]: https://docs.rs/rmp [rmps-docs-url]: https://docs.rs/rmp-serde [rmpv-docs-url]: https://docs.rs/rmpv [crates-rmp-url]: https://lib.rs/crates/rmp [crates-rmps-url]: https://lib.rs/crates/rmp-serde [crates-rmpv-url]: https://lib.rs/crates/rmpv [![Build][ci-img]][ci-url] [![Coverage Status][coveralls-img]][coveralls-url] rmpv-1.3.0/benches/value.rs000064400000000000000000000144301046102023000137040ustar 00000000000000#![feature(test)] extern crate test; use test::Bencher; use rmpv::decode::*; // Encoded value: [1, 0, [[["127.0.0.1", 59074]], 1, {0: ["read", {}, {0: ["value", {}], 1: ["error", {}]}], 1: ["write", {}, {0: ["value", {}], 1: ["error", {}]}], 2: ["remove", {}, {0: ["value", {}], 1: ["error", {}]}], 3: ["find", {}, {0: ["value", {}], 1: ["error", {}]}]}], [[80, 81, 82]]]. const COMPLEX: [u8; 137] = [ 0x94, 0x01, 0x00, 0x93, 0x91, 0x92, 0xa9, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0xcd, 0xe6, 0xc2, 0x01, 0x84, 0x00, 0x93, 0xa4, 0x72, 0x65, 0x61, 0x64, 0x80, 0x82, 0x00, 0x92, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x80, 0x01, 0x92, 0xa5, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x80, 0x01, 0x93, 0xa5, 0x77, 0x72, 0x69, 0x74, 0x65, 0x80, 0x82, 0x00, 0x92, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x80, 0x01, 0x92, 0xa5, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x80, 0x02, 0x93, 0xa6, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x80, 0x82, 0x00, 0x92, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x80, 0x01, 0x92, 0xa5, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x80, 0x03, 0x93, 0xa4, 0x66, 0x69, 0x6e, 0x64, 0x80, 0x82, 0x00, 0x92, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x80, 0x01, 0x92, 0xa5, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x80, 0x91, 0x93, 0x50, 0x51, 0x52, ]; #[bench] fn from_string_read_value(b: &mut Bencher) { // Lorem ipsum dolor sit amet. let buf = [ 0xbb, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6d, 0x65, 0x74, 0x2e ]; b.iter(|| { let res = read_value(&mut &buf[..]).unwrap(); test::black_box(res); }); } #[bench] fn from_string_read_value_ref(b: &mut Bencher) { // Lorem ipsum dolor sit amet. let buf = [ 0xbb, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6d, 0x65, 0x74, 0x2e ]; b.iter(|| { let res = read_value_ref(&mut &buf[..]).unwrap(); test::black_box(res); }); } #[bench] fn from_complex_read_value(b: &mut Bencher) { b.iter(|| { let res = read_value(&mut &COMPLEX[..]).unwrap(); test::black_box(res); }); b.bytes = COMPLEX.len() as u64; } #[bench] fn from_complex_read_value_ref(b: &mut Bencher) { b.iter(|| { let res = read_value_ref(&mut &COMPLEX[..]).unwrap(); test::black_box(res); }); b.bytes = COMPLEX.len() as u64; } #[bench] fn from_complex_write_value_ref(b: &mut Bencher) { use rmpv::encode::write_value_ref; use rmpv::ValueRef::*; let val = Array(vec![ Nil, Integer(42.into()), F64(3.1415), String("Lorem ipsum dolor sit amet.".into()), Map(vec![ (String("key".into()), String("value".into())), ]), ]); let mut buf = [0u8; 64]; b.iter(|| { write_value_ref(&mut &mut buf[..], &val).unwrap(); }); b.bytes = buf.len() as u64; } #[bench] fn from_complex_read_value_ref_to_owned(b: &mut Bencher) { let buf = [ 0x95, // Fixed array with 5 len. 0xc0, // Nil. 0x2a, // 42. 0xcb, 0x40, 0x9, 0x21, 0xca, 0xc0, 0x83, 0x12, 0x6f, // 3.1415 // Fixed string with "Lorem ipsum dolor sit amet." content. 0xbb, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6d, 0x65, 0x74, 0x2e, 0x81, // Fixed map with 1 len. 0xa3, 0x6b, 0x65, 0x79, // Key "key". 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65 // Value: "value". ]; b.iter(|| { let res = read_value_ref(&mut &buf[..]).unwrap().to_owned(); test::black_box(res); }); b.bytes = buf.len() as u64; } /// Read a single large bin32 value. fn read_large_bin32(b: &mut Bencher, size: u32) { // Creat buffer, fill it with bytes let mut buf = Vec::with_capacity(size as usize); buf.resize(size as usize, 42); // Write header (bin32 format family containing size-5 bytes) let size_bytes: [u8; 4] = (size - 5).to_be_bytes(); buf[0] = 0xc6; buf[1] = size_bytes[0]; buf[2] = size_bytes[1]; buf[3] = size_bytes[2]; buf[4] = size_bytes[3]; // Read value b.iter(|| { let res = read_value(&mut &buf[..]).unwrap(); test::black_box(res); }); b.bytes = u64::from(size); } #[bench] fn read_bin32_50kib(b: &mut Bencher) { read_large_bin32(b, 50 * 1024); } #[bench] fn read_bin32_100kib(b: &mut Bencher) { read_large_bin32(b, 100 * 1024); } #[bench] fn read_bin32_1mib(b: &mut Bencher) { read_large_bin32(b, 1024 * 1024); } #[bench] fn read_bin32_20mib(b: &mut Bencher) { read_large_bin32(b, 20 * 1024 * 1024); } #[bench] fn read_bin32_100mib(b: &mut Bencher) { read_large_bin32(b, 100 * 1024 * 1024); } /// Read a flat array containing positive 32-bit unsigned integers. fn read_large_array(b: &mut Bencher, element_count: usize) { // Creat buffer, fill it with bytes let size = element_count * 5 /* uint32 size */ + 5 /* array overhead */; let mut buf = Vec::with_capacity(size); buf.resize(size, 0); // Write header let size_bytes: [u8; 4] = (size as u32 - 5).to_be_bytes(); buf[0] = 0xc6; buf[1] = size_bytes[0]; buf[2] = size_bytes[1]; buf[3] = size_bytes[2]; buf[4] = size_bytes[3]; // Write elements let elements = &mut buf[5..]; for i in 0..element_count { let offset = i * 5; let value_bytes = 42u32.to_be_bytes(); elements[offset] = 0xce; // u32 elements[offset + 1] = value_bytes[0]; elements[offset + 2] = value_bytes[1]; elements[offset + 3] = value_bytes[2]; elements[offset + 4] = value_bytes[3]; } // Read value b.iter(|| { let res = read_value(&mut &buf[..]).unwrap(); test::black_box(res); }); b.bytes = size as u64; } #[bench] fn read_array_50kib(b: &mut Bencher) { read_large_array(b, 50 * 1024); } #[bench] fn read_array_100kib(b: &mut Bencher) { read_large_array(b, 100 * 1024); } #[bench] fn read_array_1mib(b: &mut Bencher) { read_large_array(b, 1024 * 1024); } #[bench] fn read_array_20mib(b: &mut Bencher) { read_large_array(b, 20 * 1024 * 1024); } rmpv-1.3.0/src/decode/mod.rs000064400000000000000000000055711046102023000137600ustar 00000000000000use std::error; use std::fmt::{self, Display, Formatter}; use std::io::{self, ErrorKind}; use rmp::decode::{MarkerReadError, ValueReadError}; pub mod value; pub mod value_ref; pub use self::value::{read_value, read_value_with_max_depth}; pub use self::value_ref::{read_value_ref, read_value_ref_with_max_depth}; /// The maximum recursion depth before [`Error::DepthLimitExceeded`] is returned. pub const MAX_DEPTH: usize = 1024; /// This type represents all possible errors that can occur when deserializing a value. #[derive(Debug)] pub enum Error { /// Error while reading marker byte. InvalidMarkerRead(io::Error), /// Error while reading data. InvalidDataRead(io::Error), /// The depth limit [`MAX_DEPTH`] was exceeded. DepthLimitExceeded, } #[inline] fn decrement_depth(depth: u16) -> Result { depth.checked_sub(1).ok_or(Error::DepthLimitExceeded) } impl Error { #[cold] #[must_use] pub fn kind(&self) -> ErrorKind { match *self { Error::InvalidMarkerRead(ref err) => err.kind(), Error::InvalidDataRead(ref err) => err.kind(), Error::DepthLimitExceeded => ErrorKind::Unsupported, } } } impl error::Error for Error { #[cold] fn source(&self) -> Option<&(dyn error::Error + 'static)> { match *self { Error::InvalidMarkerRead(ref err) => Some(err), Error::InvalidDataRead(ref err) => Some(err), Error::DepthLimitExceeded => None, } } } impl Display for Error { #[cold] fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> { match *self { Error::InvalidMarkerRead(ref err) => { write!(fmt, "I/O error while reading marker byte: {err}") } Error::InvalidDataRead(ref err) => { write!(fmt, "I/O error while reading non-marker bytes: {err}") } Error::DepthLimitExceeded => { write!(fmt, "depth limit exceeded") } } } } impl From for Error { #[cold] fn from(err: MarkerReadError) -> Error { Error::InvalidMarkerRead(err.0) } } impl From for Error { #[cold] fn from(err: ValueReadError) -> Error { match err { ValueReadError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err), ValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err), ValueReadError::TypeMismatch(..) => { Error::InvalidMarkerRead(io::Error::new(ErrorKind::Other, "type mismatch")) } } } } impl From for io::Error { #[cold] fn from(val: Error) -> Self { match val { Error::InvalidMarkerRead(err) | Error::InvalidDataRead(err) => err, Error::DepthLimitExceeded => io::Error::new(val.kind(), val), } } } rmpv-1.3.0/src/decode/value.rs000064400000000000000000000202351046102023000143070ustar 00000000000000use std::cmp::min; use std::io::{self, Read}; use rmp::decode::{read_marker, RmpRead}; use rmp::Marker; use super::Error; use crate::{Utf8String, Value}; // See https://github.com/3Hren/msgpack-rust/issues/151 const PREALLOC_MAX: usize = 64 * 1024; // 64 KiB fn read_array_data(rd: &mut R, mut len: usize, depth: u16) -> Result, Error> { let depth = super::decrement_depth(depth)?; // Note: Do not preallocate a Vec of size `len`. // See https://github.com/3Hren/msgpack-rust/issues/151 let mut vec = Vec::new(); while len > 0 { vec.push(read_value_inner(rd, depth)?); len -= 1; } Ok(vec) } fn read_map_data(rd: &mut R, mut len: usize, depth: u16) -> Result, Error> { let depth = super::decrement_depth(depth)?; // Note: Do not preallocate a Vec of size `len`. // See https://github.com/3Hren/msgpack-rust/issues/151 let mut vec = Vec::new(); while len > 0 { vec.push((read_value_inner(rd, depth)?, read_value_inner(rd, depth)?)); len -= 1; } Ok(vec) } fn read_str_data(rd: &mut R, len: usize, depth: u16) -> Result { let depth = super::decrement_depth(depth)?; match String::from_utf8(read_bin_data(rd, len, depth)?) { Ok(s) => Ok(Utf8String::from(s)), Err(err) => { let e = err.utf8_error(); let s = Utf8String { s: Err((err.into_bytes(), e)), }; Ok(s) } } } fn read_bin_data(rd: &mut R, len: usize, depth: u16) -> Result, Error> { let _depth = super::decrement_depth(depth)?; let mut buf = Vec::with_capacity(min(len, PREALLOC_MAX)); let bytes_read = rd.take(len as u64).read_to_end(&mut buf).map_err(Error::InvalidDataRead)?; if bytes_read != len { return Err(Error::InvalidDataRead(io::Error::new( io::ErrorKind::UnexpectedEof, format!("Expected {len} bytes, read {bytes_read} bytes"), ))); } Ok(buf) } fn read_ext_body(rd: &mut R, len: usize, depth: u16) -> Result<(i8, Vec), Error> { let depth = super::decrement_depth(depth)?; let ty = rd.read_data_i8()?; let vec = read_bin_data(rd, len, depth)?; Ok((ty, vec)) } #[inline(never)] fn read_value_inner(rd: &mut R, depth: u16) -> Result where R: Read { let depth = super::decrement_depth(depth)?; let val = match read_marker(rd)? { Marker::Null => Value::Nil, Marker::True => Value::Boolean(true), Marker::False => Value::Boolean(false), Marker::FixPos(val) => Value::from(val), Marker::FixNeg(val) => Value::from(val), Marker::U8 => Value::from(rd.read_data_u8()?), Marker::U16 => Value::from(rd.read_data_u16()?), Marker::U32 => Value::from(rd.read_data_u32()?), Marker::U64 => Value::from(rd.read_data_u64()?), Marker::I8 => Value::from(rd.read_data_i8()?), Marker::I16 => Value::from(rd.read_data_i16()?), Marker::I32 => Value::from(rd.read_data_i32()?), Marker::I64 => Value::from(rd.read_data_i64()?), Marker::F32 => Value::F32(rd.read_data_f32()?), Marker::F64 => Value::F64(rd.read_data_f64()?), Marker::FixStr(len) => { let res = read_str_data(rd, len as usize, depth)?; Value::String(res) } Marker::Str8 => { let len = rd.read_data_u8()?; let res = read_str_data(rd, len as usize, depth)?; Value::String(res) } Marker::Str16 => { let len = rd.read_data_u16()?; let res = read_str_data(rd, len as usize, depth)?; Value::String(res) } Marker::Str32 => { let len = rd.read_data_u32()?; let res = read_str_data(rd, len as usize, depth)?; Value::String(res) } Marker::FixArray(len) => { let vec = read_array_data(rd, len as usize, depth)?; Value::Array(vec) } Marker::Array16 => { let len = rd.read_data_u16()?; let vec = read_array_data(rd, len as usize, depth)?; Value::Array(vec) } Marker::Array32 => { let len = rd.read_data_u32()?; let vec = read_array_data(rd, len as usize, depth)?; Value::Array(vec) } Marker::FixMap(len) => { let map = read_map_data(rd, len as usize, depth)?; Value::Map(map) } Marker::Map16 => { let len = rd.read_data_u16()?; let map = read_map_data(rd, len as usize, depth)?; Value::Map(map) } Marker::Map32 => { let len = rd.read_data_u32()?; let map = read_map_data(rd, len as usize, depth)?; Value::Map(map) } Marker::Bin8 => { let len = rd.read_data_u8()?; let vec = read_bin_data(rd, len as usize, depth)?; Value::Binary(vec) } Marker::Bin16 => { let len = rd.read_data_u16()?; let vec = read_bin_data(rd, len as usize, depth)?; Value::Binary(vec) } Marker::Bin32 => { let len = rd.read_data_u32()?; let vec = read_bin_data(rd, len as usize, depth)?; Value::Binary(vec) } Marker::FixExt1 => { let len = 1_usize; let (ty, vec) = read_ext_body(rd, len, depth)?; Value::Ext(ty, vec) } Marker::FixExt2 => { let len = 2_usize; let (ty, vec) = read_ext_body(rd, len, depth)?; Value::Ext(ty, vec) } Marker::FixExt4 => { let len = 4_usize; let (ty, vec) = read_ext_body(rd, len, depth)?; Value::Ext(ty, vec) } Marker::FixExt8 => { let len = 8_usize; let (ty, vec) = read_ext_body(rd, len, depth)?; Value::Ext(ty, vec) } Marker::FixExt16 => { let len = 16_usize; let (ty, vec) = read_ext_body(rd, len, depth)?; Value::Ext(ty, vec) } Marker::Ext8 => { let len = rd.read_data_u8()? as usize; let (ty, vec) = read_ext_body(rd, len, depth)?; Value::Ext(ty, vec) } Marker::Ext16 => { let len = rd.read_data_u16()? as usize; let (ty, vec) = read_ext_body(rd, len, depth)?; Value::Ext(ty, vec) } Marker::Ext32 => { let len = rd.read_data_u32()? as usize; let (ty, vec) = read_ext_body(rd, len, depth)?; Value::Ext(ty, vec) } Marker::Reserved => Value::Nil, }; Ok(val) } /// Attempts to read bytes from the given reader and interpret them as a [`Value`]. /// /// # Errors /// /// This function will return [`Error`] on any I/O error while either reading or decoding a [`Value`]. /// All instances of [`ErrorKind::Interrupted`](io::ErrorKind) are handled by this function and the /// underlying operation is retried. /// /// [`Error::DepthLimitExceeded`] is returned if this function recurses /// [`MAX_DEPTH`](super::MAX_DEPTH) times. To configure the maximum recursion depth, use /// [`read_value_with_max_depth`] instead. #[inline] pub fn read_value(rd: &mut R) -> Result where R: Read { read_value_inner(rd, super::MAX_DEPTH as _) } /// Attempts to read bytes from the given reader and interpret them as a [`Value`]. /// /// # Errors /// /// This function will return [`Error`] on any I/O error while either reading or decoding a [`Value`]. /// All instances of [`ErrorKind::Interrupted`](io::ErrorKind) are handled by this function and the /// underlying operation is retried. /// /// [`Error::DepthLimitExceeded`] is returned if this function recurses /// `max_depth` times. If the default [`MAX_DEPTH`](super::MAX_DEPTH) is sufficient or you do not /// need recursion depth checking for your data, consider using [`read_value`] instead. #[inline] pub fn read_value_with_max_depth(rd: &mut R, max_depth: usize) -> Result where R: Read { read_value_inner(rd, max_depth.min(u16::MAX as usize) as u16) } rmpv-1.3.0/src/decode/value_ref.rs000064400000000000000000000261461046102023000151520ustar 00000000000000use std; use std::io::{self, Cursor, ErrorKind, Read}; use std::str; use rmp::decode::{read_marker, RmpRead}; use rmp::Marker; use super::Error; use crate::{Utf8StringRef, ValueRef}; fn read_str_data<'a, R>(rd: &mut R, len: usize, depth: u16) -> Result, Error> where R: BorrowRead<'a> { let depth = super::decrement_depth(depth)?; let buf = read_bin_data(rd, len, depth)?; match str::from_utf8(buf) { Ok(s) => Ok(Utf8StringRef::from(s)), Err(err) => { let s = Utf8StringRef { s: Err((buf, err)), }; Ok(s) } } } fn read_bin_data<'a, R>(rd: &mut R, len: usize, depth: u16) -> Result<&'a [u8], Error> where R: BorrowRead<'a> { let _depth = super::decrement_depth(depth)?; let buf = rd.fill_buf(); if len > buf.len() { return Err(Error::InvalidDataRead(io::Error::new(ErrorKind::UnexpectedEof, "unexpected EOF"))); } // Take a slice. let buf = &buf[..len]; rd.consume(len); Ok(buf) } fn read_ext_body<'a, R>(rd: &mut R, len: usize, depth: u16) -> Result<(i8, &'a [u8]), Error> where R: BorrowRead<'a> { let depth = super::decrement_depth(depth)?; let ty = rd.read_data_i8()?; let buf = read_bin_data(rd, len, depth)?; Ok((ty, buf)) } fn read_array_data<'a, R>(rd: &mut R, mut len: usize, depth: u16) -> Result>, Error> where R: BorrowRead<'a> { let depth = super::decrement_depth(depth)?; // Note: Do not preallocate a Vec of size `len`. // See https://github.com/3Hren/msgpack-rust/issues/151 let mut vec = Vec::new(); while len > 0 { vec.push(read_value_ref_inner(rd, depth)?); len -= 1; } Ok(vec) } fn read_map_data<'a, R>(rd: &mut R, mut len: usize, depth: u16) -> Result, ValueRef<'a>)>, Error> where R: BorrowRead<'a> { let depth = super::decrement_depth(depth)?; // Note: Do not preallocate a Vec of size `len`. // See https://github.com/3Hren/msgpack-rust/issues/151 let mut vec = Vec::new(); while len > 0 { vec.push((read_value_ref_inner(rd, depth)?, read_value_ref_inner(rd, depth)?)); len -= 1; } Ok(vec) } /// A `BorrowRead` is a type of Reader which has an internal buffer. /// /// This magic trait acts like a standard `BufRead` but unlike the standard this has an explicit /// internal buffer lifetime, which allows to borrow from underlying buffer while consuming bytes. pub trait BorrowRead<'a>: Read { /// Returns the buffer contents. /// /// This function is a lower-level call. It needs to be paired with the consume method to /// function properly. When calling this method, none of the contents will be "read" in the /// sense that later calling read may return the same contents. As such, consume must be called /// with the number of bytes that are consumed from this buffer to ensure that the bytes are /// never returned twice. /// /// An empty buffer returned indicates that the stream has reached EOF. fn fill_buf(&self) -> &'a [u8]; /// Tells this buffer that len bytes have been consumed from the buffer, so they should no /// longer be returned in calls to read. fn consume(&mut self, len: usize); } impl<'a> BorrowRead<'a> for &'a [u8] { fn fill_buf(&self) -> &'a [u8] { self } fn consume(&mut self, len: usize) { *self = &(*self)[len..]; } } /// Useful when you want to know how much bytes has been consumed during `ValueRef` decoding. impl<'a> BorrowRead<'a> for Cursor<&'a [u8]> { fn fill_buf(&self) -> &'a [u8] { let len = std::cmp::min(self.position(), self.get_ref().len() as u64); &self.get_ref()[len as usize..] } fn consume(&mut self, len: usize) { let pos = self.position(); self.set_position(pos + len as u64); } } fn read_value_ref_inner<'a, R>(rd: &mut R, depth: u16) -> Result, Error> where R: BorrowRead<'a> { let depth = super::decrement_depth(depth)?; // Reading the marker involves either 1 byte read or nothing. On success consumes strictly // 1 byte from the `rd`. let val = match read_marker(rd)? { Marker::Null => ValueRef::Nil, Marker::True => ValueRef::Boolean(true), Marker::False => ValueRef::Boolean(false), Marker::FixPos(val) => ValueRef::from(val), Marker::FixNeg(val) => ValueRef::from(val), Marker::U8 => ValueRef::from(rd.read_data_u8()?), Marker::U16 => ValueRef::from(rd.read_data_u16()?), Marker::U32 => ValueRef::from(rd.read_data_u32()?), Marker::U64 => ValueRef::from(rd.read_data_u64()?), Marker::I8 => ValueRef::from(rd.read_data_i8()?), Marker::I16 => ValueRef::from(rd.read_data_i16()?), Marker::I32 => ValueRef::from(rd.read_data_i32()?), Marker::I64 => ValueRef::from(rd.read_data_i64()?), Marker::F32 => ValueRef::F32(rd.read_data_f32()?), Marker::F64 => ValueRef::F64(rd.read_data_f64()?), Marker::FixStr(len) => { let res = read_str_data(rd, len as usize, depth)?; ValueRef::String(res) } Marker::Str8 => { let len = rd.read_data_u8()?; let res = read_str_data(rd, len as usize, depth)?; ValueRef::String(res) } Marker::Str16 => { let len = rd.read_data_u16()?; let res = read_str_data(rd, len as usize, depth)?; ValueRef::String(res) } Marker::Str32 => { let len = rd.read_data_u32()?; let res = read_str_data(rd, len as usize, depth)?; ValueRef::String(res) } Marker::Bin8 => { let len = rd.read_data_u8()?; let res = read_bin_data(rd, len as usize, depth)?; ValueRef::Binary(res) } Marker::Bin16 => { let len = rd.read_data_u16()?; let res = read_bin_data(rd, len as usize, depth)?; ValueRef::Binary(res) } Marker::Bin32 => { let len = rd.read_data_u32()?; let res = read_bin_data(rd, len as usize, depth)?; ValueRef::Binary(res) } Marker::FixArray(len) => { let vec = read_array_data(rd, len as usize, depth)?; ValueRef::Array(vec) } Marker::Array16 => { let len = rd.read_data_u16()?; let vec = read_array_data(rd, len as usize, depth)?; ValueRef::Array(vec) } Marker::Array32 => { let len = rd.read_data_u32()?; let vec = read_array_data(rd, len as usize, depth)?; ValueRef::Array(vec) } Marker::FixMap(len) => { let map = read_map_data(rd, len as usize, depth)?; ValueRef::Map(map) } Marker::Map16 => { let len = rd.read_data_u16()?; let map = read_map_data(rd, len as usize, depth)?; ValueRef::Map(map) } Marker::Map32 => { let len = rd.read_data_u32()?; let map = read_map_data(rd, len as usize, depth)?; ValueRef::Map(map) } Marker::FixExt1 => { let len = 1; let (ty, vec) = read_ext_body(rd, len as usize, depth)?; ValueRef::Ext(ty, vec) } Marker::FixExt2 => { let len = 2; let (ty, vec) = read_ext_body(rd, len as usize, depth)?; ValueRef::Ext(ty, vec) } Marker::FixExt4 => { let len = 4; let (ty, vec) = read_ext_body(rd, len as usize, depth)?; ValueRef::Ext(ty, vec) } Marker::FixExt8 => { let len = 8; let (ty, vec) = read_ext_body(rd, len as usize, depth)?; ValueRef::Ext(ty, vec) } Marker::FixExt16 => { let len = 16; let (ty, vec) = read_ext_body(rd, len as usize, depth)?; ValueRef::Ext(ty, vec) } Marker::Ext8 => { let len = rd.read_data_u8()?; let (ty, vec) = read_ext_body(rd, len as usize, depth)?; ValueRef::Ext(ty, vec) } Marker::Ext16 => { let len = rd.read_data_u16()?; let (ty, vec) = read_ext_body(rd, len as usize, depth)?; ValueRef::Ext(ty, vec) } Marker::Ext32 => { let len = rd.read_data_u32()?; let (ty, vec) = read_ext_body(rd, len as usize, depth)?; ValueRef::Ext(ty, vec) } Marker::Reserved => ValueRef::Nil, }; Ok(val) } /// Attempts to read the data from the given reader until either a complete MessagePack value /// decoded or an error detected. /// /// Returns either a non-owning `ValueRef`, which borrows the buffer from the given reader or an /// error. /// /// The reader should meet the requirement of a special `BorrowRead` trait, which allows to mutate /// itself but permits to mutate the buffer it contains. It allows to perform a completely /// zero-copy reading without a data loss fear in case of an error. /// /// Currently only two types fit in this requirement: `&[u8]` and `Cursor<&[u8]>`. Using Cursor is /// helpful, when you need to know how exactly many bytes the decoded `ValueRef` consumes. A `Vec` /// type doesn't fit in the `BorrowRead` requirement, because its mut reference can mutate the /// underlying buffer - use `Vec::as_slice()` if you need to decode a value from the vector. /// /// # Errors /// /// Returns an `Error` value if unable to continue the decoding operation either because of read /// failure or any other circumstances. See `Error` documentation for more information. /// /// This function enforces a maximum recursion depth of [`MAX_DEPTH`](super::MAX_DEPTH) and returns /// [`Error::DepthLimitExceeded`] if the maximum is hit. If you run into stack overflows despite /// this, use [`read_value_ref_with_max_depth`] with a custom maximum depth. /// /// # Examples /// ``` /// use rmpv::ValueRef; /// use rmpv::decode::read_value_ref; /// /// let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65]; /// let mut rd = &buf[..]; /// /// assert_eq!(ValueRef::from("le message"), read_value_ref(&mut rd).unwrap()); /// ``` #[inline(never)] pub fn read_value_ref<'a, R>(rd: &mut R) -> Result, Error> where R: BorrowRead<'a> { read_value_ref_inner(rd, super::MAX_DEPTH as _) } /// Attempts to read the data from the given reader until either a complete MessagePack value /// decoded or an error detected. /// /// Returns either a non-owning `ValueRef`, which borrows the buffer from the given reader or an /// error. /// /// See [`read_value_ref`] for more information on how to use this function. This variant allows /// you to specify the maximum recursion depth, if [`MAX_DEPTH`](super::MAX_DEPTH) is too high. /// /// # Errors /// /// Same as [`read_value_ref`], using the `max_depth` parameter in place of /// [`MAX_DEPTH`](super::MAX_DEPTH). #[inline(never)] pub fn read_value_ref_with_max_depth<'a, R>(rd: &mut R, max_depth: usize) -> Result, Error> where R: BorrowRead<'a> { read_value_ref_inner(rd, max_depth.min(u16::MAX as _) as u16) } rmpv-1.3.0/src/encode/mod.rs000064400000000000000000000002271046102023000137630ustar 00000000000000pub use rmp::encode::ValueWriteError as Error; mod value; mod value_ref; pub use self::value::write_value; pub use self::value_ref::write_value_ref; rmpv-1.3.0/src/encode/value.rs000064400000000000000000000040211046102023000143140ustar 00000000000000use std::io::Write; use rmp::encode::{ write_array_len, write_bin, write_bool, write_ext_meta, write_f32, write_f64, write_map_len, write_nil, write_sint, write_str, write_uint, }; use super::Error; use crate::{IntPriv, Integer, Utf8String, Value}; /// Encodes and attempts to write the most efficient representation of the given Value. /// /// # Note /// /// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying /// operation is retried. pub fn write_value(wr: &mut W, val: &Value) -> Result<(), Error> where W: Write { match *val { Value::Nil => { write_nil(wr).map_err(Error::InvalidMarkerWrite)?; } Value::Boolean(val) => { write_bool(wr, val).map_err(Error::InvalidMarkerWrite)?; } Value::Integer(Integer { n }) => { match n { IntPriv::PosInt(n) => { write_uint(wr, n)?; } IntPriv::NegInt(n) => { write_sint(wr, n)?; } } } Value::F32(val) => { write_f32(wr, val)?; } Value::F64(val) => { write_f64(wr, val)?; } Value::String(Utf8String { ref s }) => match *s { Ok(ref val) => write_str(wr, val)?, Err(ref err) => write_bin(wr, &err.0)?, }, Value::Binary(ref val) => { write_bin(wr, val)?; } Value::Array(ref vec) => { write_array_len(wr, vec.len() as u32)?; for v in vec { write_value(wr, v)?; } } Value::Map(ref map) => { write_map_len(wr, map.len() as u32)?; for (key, val) in map { write_value(wr, key)?; write_value(wr, val)?; } } Value::Ext(ty, ref data) => { write_ext_meta(wr, data.len() as u32, ty)?; wr.write_all(data).map_err(Error::InvalidDataWrite)?; } } Ok(()) } rmpv-1.3.0/src/encode/value_ref.rs000064400000000000000000000046621046102023000151630ustar 00000000000000use std::io::Write; use rmp::encode::{ write_array_len, write_bin, write_bool, write_ext_meta, write_f32, write_f64, write_map_len, write_nil, write_sint, write_str, write_uint, }; use super::Error; use crate::{IntPriv, Integer, Utf8StringRef, ValueRef}; /// Encodes and attempts to write the given non-owning `ValueRef` into the Write. /// /// # Errors /// /// This function returns Error with an underlying I/O error if unable to properly write entire /// value. Interruption errors are handled internally by silent operation restarting. /// /// # Examples /// ``` /// use rmpv::ValueRef; /// use rmpv::encode::write_value_ref; /// /// let mut buf = Vec::new(); /// let val = ValueRef::from("le message"); /// /// write_value_ref(&mut buf, &val).unwrap(); /// assert_eq!(vec![0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65], buf); /// ``` pub fn write_value_ref(wr: &mut W, val: &ValueRef<'_>) -> Result<(), Error> where W: Write { match *val { ValueRef::Nil => { write_nil(wr).map_err(Error::InvalidMarkerWrite)?; } ValueRef::Boolean(val) => { write_bool(wr, val).map_err(Error::InvalidMarkerWrite)?; } ValueRef::Integer(Integer { n }) => { match n { IntPriv::PosInt(n) => { write_uint(wr, n)?; } IntPriv::NegInt(n) => { write_sint(wr, n)?; } } } ValueRef::F32(val) => { write_f32(wr, val)?; } ValueRef::F64(val) => { write_f64(wr, val)?; } ValueRef::String(Utf8StringRef { s }) => match s { Ok(val) => write_str(wr, val)?, Err(err) => write_bin(wr, err.0)?, }, ValueRef::Binary(val) => { write_bin(wr, val)?; } ValueRef::Array(ref vec) => { write_array_len(wr, vec.len() as u32)?; for v in vec { write_value_ref(wr, v)?; } } ValueRef::Map(ref map) => { write_map_len(wr, map.len() as u32)?; for (key, val) in map { write_value_ref(wr, key)?; write_value_ref(wr, val)?; } } ValueRef::Ext(ty, data) => { write_ext_meta(wr, data.len() as u32, ty)?; wr.write_all(data).map_err(Error::InvalidDataWrite)?; } } Ok(()) } rmpv-1.3.0/src/ext/de.rs000064400000000000000000001140401046102023000131360ustar 00000000000000use std::borrow::Cow; use std::fmt::{self, Display, Formatter}; use std::iter::ExactSizeIterator; use std::slice::Iter; use std::vec::IntoIter; use serde::de::{self, DeserializeSeed, IntoDeserializer, SeqAccess, Unexpected, Visitor}; use serde::forward_to_deserialize_any; use serde::{self, Deserialize, Deserializer}; use crate::{IntPriv, Integer, Utf8String, Utf8StringRef, Value, ValueRef}; use super::{Error, ValueExt}; use crate::MSGPACK_EXT_STRUCT_NAME; #[inline] pub fn from_value(val: Value) -> Result where T: for<'de> Deserialize<'de> { deserialize_from(val) } #[inline] pub fn deserialize_from<'de, T, D>(val: D) -> Result where T: Deserialize<'de>, D: Deserializer<'de, Error = Error> { Deserialize::deserialize(val) } impl de::Error for Error { #[cold] fn custom(msg: T) -> Self { Error::Syntax(format!("{msg}")) } } impl<'de> Deserialize<'de> for Value { #[inline] fn deserialize(de: D) -> Result where D: de::Deserializer<'de> { struct ValueVisitor; impl<'de> serde::de::Visitor<'de> for ValueVisitor { type Value = Value; #[cold] fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> { "any valid MessagePack value".fmt(fmt) } #[inline] fn visit_some(self, de: D) -> Result where D: de::Deserializer<'de> { Deserialize::deserialize(de) } #[inline] fn visit_none(self) -> Result { Ok(Value::Nil) } #[inline] fn visit_unit(self) -> Result { Ok(Value::Nil) } #[inline] fn visit_bool(self, value: bool) -> Result { Ok(Value::Boolean(value)) } #[inline] fn visit_u64(self, value: u64) -> Result { Ok(Value::from(value)) } #[inline] fn visit_i64(self, value: i64) -> Result { Ok(Value::from(value)) } #[inline] fn visit_f32(self, value: f32) -> Result { Ok(Value::F32(value)) } #[inline] fn visit_f64(self, value: f64) -> Result { Ok(Value::F64(value)) } #[inline] fn visit_string(self, value: String) -> Result { Ok(Value::String(Utf8String::from(value))) } #[inline] fn visit_str(self, value: &str) -> Result where E: de::Error { self.visit_string(String::from(value)) } #[inline] fn visit_seq(self, mut visitor: V) -> Result where V: SeqAccess<'de> { let mut vec = Vec::new(); while let Some(elem) = visitor.next_element()? { vec.push(elem); } Ok(Value::Array(vec)) } #[inline] fn visit_bytes(self, v: &[u8]) -> Result where E: de::Error { Ok(Value::Binary(v.to_owned())) } #[inline] fn visit_byte_buf(self, v: Vec) -> Result where E: de::Error { Ok(Value::Binary(v)) } #[inline] fn visit_map(self, mut visitor: V) -> Result where V: de::MapAccess<'de> { let mut pairs = vec![]; while let Some(key) = visitor.next_key()? { let val = visitor.next_value()?; pairs.push((key, val)); } Ok(Value::Map(pairs)) } fn visit_newtype_struct(self, deserializer: D) -> Result where D: Deserializer<'de>, { struct ExtValueVisitor; impl<'de> serde::de::Visitor<'de> for ExtValueVisitor { type Value = Value; #[cold] fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> { "a valid MessagePack Ext".fmt(fmt) } #[inline] fn visit_seq(self, mut seq: V) -> Result where V: SeqAccess<'de> { let tag = seq.next_element()? .ok_or_else(|| de::Error::invalid_length(0, &self))?; let bytes: serde_bytes::ByteBuf = seq.next_element()? .ok_or_else(|| de::Error::invalid_length(1, &self))?; Ok(Value::Ext(tag, bytes.to_vec())) } } deserializer.deserialize_tuple(2, ExtValueVisitor) } } de.deserialize_any(ValueVisitor) } } impl<'de> Deserialize<'de> for ValueRef<'de> { #[inline] fn deserialize(de: D) -> Result where D: Deserializer<'de> { struct ValueVisitor; impl<'de> de::Visitor<'de> for ValueVisitor { type Value = ValueRef<'de>; #[cold] fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> { "any valid MessagePack value".fmt(fmt) } #[inline] fn visit_some(self, de: D) -> Result where D: Deserializer<'de> { Deserialize::deserialize(de) } #[inline] fn visit_none(self) -> Result { Ok(ValueRef::Nil) } #[inline] fn visit_unit(self) -> Result { Ok(ValueRef::Nil) } #[inline] fn visit_bool(self, value: bool) -> Result { Ok(ValueRef::Boolean(value)) } #[inline] fn visit_u64(self, value: u64) -> Result { Ok(ValueRef::from(value)) } #[inline] fn visit_i64(self, value: i64) -> Result { Ok(ValueRef::from(value)) } #[inline] fn visit_f32(self, value: f32) -> Result { Ok(ValueRef::F32(value)) } #[inline] fn visit_f64(self, value: f64) -> Result { Ok(ValueRef::F64(value)) } #[inline] fn visit_borrowed_str(self, value: &'de str) -> Result where E: de::Error { Ok(ValueRef::String(Utf8StringRef::from(value))) } #[inline] fn visit_seq(self, mut visitor: V) -> Result where V: SeqAccess<'de> { let mut vec = Vec::new(); while let Some(elem) = visitor.next_element()? { vec.push(elem); } Ok(ValueRef::Array(vec)) } #[inline] fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result where E: de::Error { Ok(ValueRef::Binary(v)) } #[inline] fn visit_map(self, mut visitor: V) -> Result where V: de::MapAccess<'de> { let mut vec = Vec::new(); while let Some(key) = visitor.next_key()? { let val = visitor.next_value()?; vec.push((key, val)); } Ok(ValueRef::Map(vec)) } fn visit_newtype_struct(self, deserializer: D) -> Result where D: Deserializer<'de>, { struct ExtValueRefVisitor; impl<'de> serde::de::Visitor<'de> for ExtValueRefVisitor { type Value = ValueRef<'de>; fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> { "a valid MessagePack Ext".fmt(fmt) } #[inline] fn visit_seq(self, mut seq: V) -> Result, V::Error> where V: SeqAccess<'de> { let tag = seq.next_element()? .ok_or_else(|| de::Error::invalid_length(0, &"invalid ext sequence"))?; let bytes: &[u8] = seq.next_element()? .ok_or_else(|| de::Error::invalid_length(1, &"invalid ext sequence"))?; Ok(ValueRef::Ext(tag, bytes)) } } deserializer.deserialize_tuple(2, ExtValueRefVisitor) } } de.deserialize_any(ValueVisitor) } } impl<'de> Deserializer<'de> for Value { type Error = Error; fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> { match self { Value::Nil => visitor.visit_unit(), Value::Boolean(v) => visitor.visit_bool(v), Value::Integer(Integer { n }) => match n { IntPriv::PosInt(v) => visitor.visit_u64(v), IntPriv::NegInt(v) => visitor.visit_i64(v), }, Value::F32(v) => visitor.visit_f32(v), Value::F64(v) => visitor.visit_f64(v), Value::String(v) => match v.s { Ok(v) => visitor.visit_string(v), Err(v) => visitor.visit_byte_buf(v.0), }, Value::Binary(v) => visitor.visit_byte_buf(v), Value::Array(v) => { let len = v.len(); let mut de = SeqDeserializer::new(v.into_iter()); let seq = visitor.visit_seq(&mut de)?; if de.iter.len() == 0 { Ok(seq) } else { Err(de::Error::invalid_length(len, &"fewer elements in array")) } } Value::Map(v) => { let len = v.len(); let mut de = MapDeserializer::new(v.into_iter()); let map = visitor.visit_map(&mut de)?; if de.iter.len() == 0 { Ok(map) } else { Err(de::Error::invalid_length(len, &"fewer elements in map")) } } Value::Ext(tag, data) => { let de = ExtDeserializer::new_owned(tag, data); visitor.visit_newtype_struct(de) } } } #[inline] fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de> { ValueBase::deserialize_option(self, visitor) } #[inline] fn deserialize_enum(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de> { ValueBase::deserialize_enum(self, visitor) } #[inline] fn deserialize_newtype_struct(self, name: &'static str, visitor: V) -> Result where V: Visitor<'de> { if name == MSGPACK_EXT_STRUCT_NAME { match self { Value::Ext(tag, data) => { let ext_de = ExtDeserializer::new_owned(tag, data); return visitor.visit_newtype_struct(ext_de); } other => return Err(de::Error::invalid_type(other.unexpected(), &"expected Ext")), } } visitor.visit_newtype_struct(self) } #[inline] fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result where V: Visitor<'de> { ValueBase::deserialize_unit_struct(self, visitor) } forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq bytes byte_buf map tuple_struct struct identifier tuple ignored_any } } impl<'de> Deserializer<'de> for ValueRef<'de> { type Error = Error; #[inline] fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> { match self { ValueRef::Nil => visitor.visit_unit(), ValueRef::Boolean(v) => visitor.visit_bool(v), ValueRef::Integer(Integer { n }) => match n { IntPriv::PosInt(v) => visitor.visit_u64(v), IntPriv::NegInt(v) => visitor.visit_i64(v), }, ValueRef::F32(v) => visitor.visit_f32(v), ValueRef::F64(v) => visitor.visit_f64(v), ValueRef::String(v) => match v.s { Ok(v) => visitor.visit_borrowed_str(v), Err(v) => visitor.visit_borrowed_bytes(v.0), }, ValueRef::Binary(v) => visitor.visit_borrowed_bytes(v), ValueRef::Array(v) => { let len = v.len(); let mut de = SeqDeserializer::new(v.into_iter()); let seq = visitor.visit_seq(&mut de)?; if de.iter.len() == 0 { Ok(seq) } else { Err(de::Error::invalid_length(len, &"fewer elements in array")) } } ValueRef::Map(v) => { let len = v.len(); let mut de = MapDeserializer::new(v.into_iter()); let map = visitor.visit_map(&mut de)?; if de.iter.len() == 0 { Ok(map) } else { Err(de::Error::invalid_length(len, &"fewer elements in map")) } } ValueRef::Ext(tag, data) => { let de = ExtDeserializer::new_ref(tag, data); visitor.visit_newtype_struct(de) } } } #[inline] fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de> { ValueBase::deserialize_option(self, visitor) } #[inline] fn deserialize_enum(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de> { ValueBase::deserialize_enum(self, visitor) } #[inline] fn deserialize_newtype_struct(self, name: &'static str, visitor: V) -> Result where V: Visitor<'de> { if name == MSGPACK_EXT_STRUCT_NAME { match self { ValueRef::Ext(tag, data) => { let ext_de = ExtDeserializer::new_ref(tag, data); return visitor.visit_newtype_struct(ext_de); } other => return Err(de::Error::invalid_type(other.unexpected(), &"expected Ext")), } } visitor.visit_newtype_struct(self) } #[inline] fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result where V: Visitor<'de> { ValueBase::deserialize_unit_struct(self, visitor) } forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq bytes byte_buf map tuple_struct struct identifier tuple ignored_any } } impl<'de> Deserializer<'de> for &'de ValueRef<'de> { type Error = Error; #[inline] fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> { match *self { ValueRef::Nil => visitor.visit_unit(), ValueRef::Boolean(v) => visitor.visit_bool(v), ValueRef::Integer(Integer { n }) => match n { IntPriv::PosInt(v) => visitor.visit_u64(v), IntPriv::NegInt(v) => visitor.visit_i64(v), }, ValueRef::F32(v) => visitor.visit_f32(v), ValueRef::F64(v) => visitor.visit_f64(v), ValueRef::String(v) => match v.s { Ok(v) => visitor.visit_borrowed_str(v), Err(v) => visitor.visit_borrowed_bytes(v.0), }, ValueRef::Binary(v) => visitor.visit_borrowed_bytes(v), ValueRef::Array(ref v) => { let len = v.len(); let mut de = SeqDeserializer::new(v.iter()); let seq = visitor.visit_seq(&mut de)?; if de.iter.len() == 0 { Ok(seq) } else { Err(de::Error::invalid_length(len, &"fewer elements in array")) } } ValueRef::Map(ref v) => { let len = v.len(); let mut de = MapRefDeserializer::new(v.iter()); let map = visitor.visit_map(&mut de)?; if de.iter.len() == 0 { Ok(map) } else { Err(de::Error::invalid_length(len, &"fewer elements in map")) } } ValueRef::Ext(tag, data) => { let de = ExtDeserializer::new_ref(tag, data); visitor.visit_newtype_struct(de) } } } #[inline] fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de> { if let ValueRef::Nil = *self { visitor.visit_none() } else { visitor.visit_some(self) } } #[inline] fn deserialize_enum(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de> { match self { ValueRef::Array(v) => { let len = v.len(); let mut iter = v.iter(); if !(len == 1 || len == 2) { return Err(de::Error::invalid_length(len, &"array with one or two elements")); } let id = match iter.next() { Some(id) => deserialize_from(id)?, None => { return Err(de::Error::invalid_length(len, &"array with one or two elements")); } }; visitor.visit_enum(EnumRefDeserializer::new(id, iter.next())) } other => Err(de::Error::invalid_type(other.unexpected(), &"array, map or int")), } } #[inline] fn deserialize_newtype_struct(self, name: &'static str, visitor: V) -> Result where V: Visitor<'de> { if name == MSGPACK_EXT_STRUCT_NAME { match self { ValueRef::Ext(tag, data) => { let ext_de = ExtDeserializer::new_ref(*tag, data); return visitor.visit_newtype_struct(ext_de); } other => return Err(de::Error::invalid_type(other.unexpected(), &"expected Ext")), } } visitor.visit_newtype_struct(self) } #[inline] fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result where V: Visitor<'de> { match self { ValueRef::Array(v) => { if v.is_empty() { visitor.visit_unit() } else { Err(de::Error::invalid_length(v.len(), &"empty array")) } } other => Err(de::Error::invalid_type(other.unexpected(), &"empty array")), } } forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq bytes byte_buf map tuple_struct struct identifier tuple ignored_any } } struct ExtDeserializer<'de> { tag: Option, data: Option>, } impl<'de> ExtDeserializer<'de> { fn new_owned(tag: i8, data: Vec) -> Self { ExtDeserializer { tag: Some(tag), data: Some(Cow::Owned(data)), } } fn new_ref(tag: i8, data: &'de [u8]) -> Self { ExtDeserializer { tag: Some(tag), data: Some(Cow::Borrowed(data)), } } } impl<'de> SeqAccess<'de> for ExtDeserializer<'de> { type Error = Error; fn next_element_seed(&mut self, seed: T) -> Result, Error> where T: DeserializeSeed<'de>, { if self.tag.is_some() || self.data.is_some() { return Ok(Some(seed.deserialize(self)?)); } Ok(None) } } /// Deserializer for Ext (expecting sequence) impl<'a, 'de: 'a> Deserializer<'de> for ExtDeserializer<'de> { type Error = Error; #[inline] fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> { visitor.visit_seq(self) } forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq bytes byte_buf map unit_struct newtype_struct struct identifier tuple enum ignored_any tuple_struct } } /// Deserializer for Ext `SeqAccess` elements impl<'a, 'de: 'a> Deserializer<'de> for &'a mut ExtDeserializer<'de> { type Error = Error; #[inline] fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> { if self.tag.is_some() { let tag = self.tag.take().unwrap(); visitor.visit_i8(tag) } else if self.data.is_some() { let data = self.data.take().unwrap(); match data { Cow::Owned(data) => visitor.visit_byte_buf(data), Cow::Borrowed(data) => visitor.visit_borrowed_bytes(data), } } else { debug_assert!(false, "ext seq only has two elements"); Err(Error::Syntax(String::new())) } } forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq bytes byte_buf map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any } } struct SeqDeserializer { iter: I, } impl SeqDeserializer { fn new(iter: I) -> Self { Self { iter } } } impl<'de, I, U> SeqAccess<'de> for SeqDeserializer where I: Iterator, U: Deserializer<'de, Error = Error> { type Error = Error; fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: de::DeserializeSeed<'de> { match self.iter.next() { Some(val) => seed.deserialize(val).map(Some), None => Ok(None), } } } impl<'de, I, U> Deserializer<'de> for SeqDeserializer where I: ExactSizeIterator, U: Deserializer<'de, Error = Error> { type Error = Error; #[inline] fn deserialize_any(mut self, visitor: V) -> Result where V: Visitor<'de> { let len = self.iter.len(); if len == 0 { visitor.visit_unit() } else { let ret = visitor.visit_seq(&mut self)?; let rem = self.iter.len(); if rem == 0 { Ok(ret) } else { Err(de::Error::invalid_length(len, &"fewer elements in array")) } } } forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq bytes byte_buf map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any } } struct MapDeserializer { val: Option, iter: I, } impl MapDeserializer { fn new(iter: I) -> Self { Self { val: None, iter } } } impl<'de, I, U> de::MapAccess<'de> for MapDeserializer where I: Iterator, U: ValueBase<'de> { type Error = Error; fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> where T: DeserializeSeed<'de> { match self.iter.next() { Some((key, val)) => { self.val = Some(val); seed.deserialize(key).map(Some) } None => Ok(None), } } fn next_value_seed(&mut self, seed: T) -> Result where T: DeserializeSeed<'de> { match self.val.take() { Some(val) => seed.deserialize(val), None => Err(de::Error::custom("value is missing")), } } } impl<'de, I, U> Deserializer<'de> for MapDeserializer where I: Iterator, U: ValueBase<'de> { type Error = Error; #[inline] fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> { visitor.visit_map(self) } forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq bytes byte_buf map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any } } struct EnumDeserializer { id: u32, value: Option, } impl EnumDeserializer { pub fn new(id: u32, value: Option) -> Self { Self { id, value } } } impl<'de, U: ValueBase<'de> + ValueExt> de::EnumAccess<'de> for EnumDeserializer { type Error = Error; type Variant = VariantDeserializer; fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where V: de::DeserializeSeed<'de> { let variant = self.id.into_deserializer(); let visitor = VariantDeserializer { value: self.value }; seed.deserialize(variant).map(|v| (v, visitor)) } } struct VariantDeserializer { value: Option, } impl<'de, U: ValueBase<'de> + ValueExt> de::VariantAccess<'de> for VariantDeserializer { type Error = Error; fn unit_variant(self) -> Result<(), Error> { // Can accept only [u32]. match self.value { Some(v) => { match v.into_iter() { Ok(ref v) if v.len() == 0 => Ok(()), Ok(..) => Err(de::Error::invalid_value(Unexpected::Seq, &"empty array")), Err(v) => Err(de::Error::invalid_value(v.unexpected(), &"empty array")), } } None => Ok(()), } } fn newtype_variant_seed(self, seed: T) -> Result where T: de::DeserializeSeed<'de> { // Can accept both [u32, T...] and [u32, [T]] cases. match self.value { Some(v) => { match v.into_iter() { Ok(mut iter) => { if iter.len() > 1 { seed.deserialize(SeqDeserializer::new(iter)) } else { let val = match iter.next() { Some(val) => seed.deserialize(val), None => return Err(de::Error::invalid_value(Unexpected::Seq, &"array with one element")), }; if iter.next().is_some() { Err(de::Error::invalid_value(Unexpected::Seq, &"array with one element")) } else { val } } } Err(v) => seed.deserialize(v), } } None => Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant")), } } fn tuple_variant(self, _len: usize, visitor: V) -> Result where V: Visitor<'de> { // Can accept [u32, [T...]]. match self.value { Some(v) => { match v.into_iter() { Ok(v) => Deserializer::deserialize_any(SeqDeserializer::new(v), visitor), Err(v) => Err(de::Error::invalid_type(v.unexpected(), &"tuple variant")), } } None => Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant")) } } fn struct_variant(self, _fields: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de>, { match self.value { Some(v) => { match v.into_iter() { Ok(iter) => Deserializer::deserialize_any(SeqDeserializer::new(iter), visitor), Err(v) => { match v.into_map_iter() { Ok(iter) => Deserializer::deserialize_any(MapDeserializer::new(iter), visitor), Err(v) => Err(de::Error::invalid_type(v.unexpected(), &"struct variant")), } } } } None => Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant")) } } } pub struct MapRefDeserializer<'de> { val: Option<&'de ValueRef<'de>>, iter: Iter<'de, (ValueRef<'de>, ValueRef<'de>)>, } impl<'de> MapRefDeserializer<'de> { fn new(iter: Iter<'de, (ValueRef<'de>, ValueRef<'de>)>) -> Self { Self { val: None, iter } } } impl<'de> de::MapAccess<'de> for MapRefDeserializer<'de> { type Error = Error; fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> where T: DeserializeSeed<'de> { match self.iter.next() { Some((key, val)) => { self.val = Some(val); seed.deserialize(key).map(Some) } None => Ok(None), } } fn next_value_seed(&mut self, seed: T) -> Result where T: DeserializeSeed<'de> { match self.val.take() { Some(val) => seed.deserialize(val), None => Err(de::Error::custom("value is missing")), } } } impl<'de> Deserializer<'de> for MapRefDeserializer<'de> { type Error = Error; #[inline] fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> { visitor.visit_map(self) } forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq bytes byte_buf map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any } } pub struct EnumRefDeserializer<'de> { id: u32, value: Option<&'de ValueRef<'de>>, } impl<'de> EnumRefDeserializer<'de> { #[must_use] pub fn new(id: u32, value: Option<&'de ValueRef<'de>>) -> Self { Self { id, value } } } impl<'de> de::EnumAccess<'de> for EnumRefDeserializer<'de> { type Error = Error; type Variant = VariantRefDeserializer<'de>; fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where V: de::DeserializeSeed<'de> { let variant = self.id.into_deserializer(); let visitor = VariantRefDeserializer { value: self.value }; seed.deserialize(variant).map(|v| (v, visitor)) } } pub struct VariantRefDeserializer<'de> { value: Option<&'de ValueRef<'de>>, } impl<'de> de::VariantAccess<'de> for VariantRefDeserializer<'de> { type Error = Error; fn unit_variant(self) -> Result<(), Error> { // Can accept only [u32]. match self.value { Some(ValueRef::Array(v)) => { if v.is_empty() { Ok(()) } else { Err(de::Error::invalid_value(Unexpected::Seq, &"empty array")) } } Some(v) => Err(de::Error::invalid_value(v.unexpected(), &"empty array")), None => Ok(()), } } fn newtype_variant_seed(self, seed: T) -> Result where T: de::DeserializeSeed<'de> { // Can accept both [u32, T...] and [u32, [T]] cases. match self.value { Some(ValueRef::Array(v)) => { let len = v.len(); let mut iter = v.iter(); if len > 1 { seed.deserialize(SeqDeserializer::new(iter)) } else { let val = match iter.next() { Some(val) => seed.deserialize(val), None => return Err(de::Error::invalid_length(len, &"array with one element")), }; if iter.next().is_some() { Err(de::Error::invalid_length(len, &"array with one element")) } else { val } } } Some(v) => seed.deserialize(v), None => Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant")), } } fn tuple_variant(self, _len: usize, visitor: V) -> Result where V: Visitor<'de> { // Can accept [u32, [T...]]. match self.value { Some(ValueRef::Array(v)) => { Deserializer::deserialize_any(SeqDeserializer::new(v.iter()), visitor) } Some(v) => Err(de::Error::invalid_type(v.unexpected(), &"tuple variant")), None => Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant")) } } fn struct_variant(self, _fields: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de>, { match self.value { Some(ValueRef::Array(v)) => { Deserializer::deserialize_any(SeqDeserializer::new(v.iter()), visitor) } Some(ValueRef::Map(v)) => { Deserializer::deserialize_any(MapRefDeserializer::new(v.iter()), visitor) } Some(v) => Err(de::Error::invalid_type(v.unexpected(), &"struct variant")), None => Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant")) } } } // TODO: Ugly hack. Needed for avoiding copy-pasting similar code, but I don't like it. trait ValueBase<'de>: Deserializer<'de, Error = Error> + ValueExt { type Item: ValueBase<'de>; type Iter: ExactSizeIterator; type MapIter: Iterator; type MapDeserializer: Deserializer<'de>; fn is_nil(&self) -> bool; fn into_iter(self) -> Result; fn into_map_iter(self) -> Result; #[inline] fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de> { if self.is_nil() { visitor.visit_none() } else { visitor.visit_some(self) } } #[inline] fn deserialize_enum(self, visitor: V) -> Result where V: Visitor<'de> { match self.into_iter() { Ok(mut iter) => { if !(iter.len() == 1 || iter.len() == 2) { return Err(de::Error::invalid_length(iter.len(), &"array with one or two elements")); } let id = match iter.next() { Some(id) => deserialize_from(id)?, None => { return Err(de::Error::invalid_value(Unexpected::Seq, &"array with one or two elements")); } }; visitor.visit_enum(EnumDeserializer::new(id, iter.next())) } Err(other) => { Err(de::Error::invalid_type(other.unexpected(), &"array, map or int")) } } } #[inline] fn deserialize_newtype_struct(self, visitor: V) -> Result where V: Visitor<'de> { visitor.visit_newtype_struct(self) } #[inline] fn deserialize_unit_struct(self, visitor: V) -> Result where V: Visitor<'de> { match self.into_iter() { Ok(iter) => { if iter.len() == 0 { visitor.visit_unit() } else { Err(de::Error::invalid_type(Unexpected::Seq, &"empty array")) } } Err(other) => Err(de::Error::invalid_type(other.unexpected(), &"empty array")), } } } impl<'de> ValueBase<'de> for Value { type Item = Value; type Iter = IntoIter; type MapIter = IntoIter<(Value, Value)>; type MapDeserializer = MapDeserializer; #[inline] fn is_nil(&self) -> bool { if let Value::Nil = *self { true } else { false } } #[inline] fn into_iter(self) -> Result { match self { Value::Array(v) => Ok(v.into_iter()), other => Err(other), } } #[inline] fn into_map_iter(self) -> Result { match self { Value::Map(v) => Ok(v.into_iter()), other => Err(other), } } } impl<'de> ValueBase<'de> for ValueRef<'de> { type Item = ValueRef<'de>; type Iter = IntoIter>; type MapIter = IntoIter<(ValueRef<'de>, ValueRef<'de>)>; type MapDeserializer = MapDeserializer; #[inline] fn is_nil(&self) -> bool { if let ValueRef::Nil = *self { true } else { false } } #[inline] fn into_iter(self) -> Result { match self { ValueRef::Array(v) => Ok(v.into_iter()), other => Err(other), } } #[inline] fn into_map_iter(self) -> Result { match self { ValueRef::Map(v) => Ok(v.into_iter()), other => Err(other), } } } rmpv-1.3.0/src/ext/mod.rs000064400000000000000000000046501046102023000133320ustar 00000000000000use std::error; use std::fmt::{self, Display, Formatter}; use serde::de::Unexpected; use crate::{IntPriv, Integer, Value, ValueRef}; pub use self::de::{deserialize_from, from_value, EnumRefDeserializer}; pub use self::se::to_value; mod de; mod se; #[derive(Debug)] pub enum Error { Syntax(String), } impl Display for Error { #[cold] fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> { match *self { Error::Syntax(ref err) => write!(fmt, "error while decoding value: {err}"), } } } impl error::Error for Error {} trait ValueExt { fn unexpected(&self) -> Unexpected<'_>; } impl ValueExt for Value { #[cold] fn unexpected(&self) -> Unexpected<'_> { match *self { Value::Nil => Unexpected::Unit, Value::Boolean(v) => Unexpected::Bool(v), Value::Integer(Integer { n }) => match n { IntPriv::PosInt(v) => Unexpected::Unsigned(v), IntPriv::NegInt(v) => Unexpected::Signed(v), }, Value::F32(v) => Unexpected::Float(f64::from(v)), Value::F64(v) => Unexpected::Float(v), Value::String(ref v) => match v.s { Ok(ref v) => Unexpected::Str(v), Err(ref v) => Unexpected::Bytes(&v.0[..]), }, Value::Binary(ref v) => Unexpected::Bytes(v), Value::Array(..) => Unexpected::Seq, Value::Map(..) => Unexpected::Map, Value::Ext(..) => Unexpected::Seq, } } } impl<'a> ValueExt for ValueRef<'a> { #[cold] fn unexpected(&self) -> Unexpected<'_> { match *self { ValueRef::Nil => Unexpected::Unit, ValueRef::Boolean(v) => Unexpected::Bool(v), ValueRef::Integer(Integer { n }) => match n { IntPriv::PosInt(v) => Unexpected::Unsigned(v), IntPriv::NegInt(v) => Unexpected::Signed(v), }, ValueRef::F32(v) => Unexpected::Float(f64::from(v)), ValueRef::F64(v) => Unexpected::Float(v), ValueRef::String(ref v) => match v.s { Ok(v) => Unexpected::Str(v), Err(ref v) => Unexpected::Bytes(v.0), }, ValueRef::Binary(v) => Unexpected::Bytes(v), ValueRef::Array(..) => Unexpected::Seq, ValueRef::Map(..) => Unexpected::Map, ValueRef::Ext(..) => Unexpected::Seq, } } } rmpv-1.3.0/src/ext/se.rs000064400000000000000000000573611046102023000131710ustar 00000000000000use std::fmt::Display; use serde::ser::{ self, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct, }; use serde::Serialize; use serde_bytes::Bytes; use crate::{IntPriv, Integer, Value}; use super::Error; use crate::MSGPACK_EXT_STRUCT_NAME; impl Serialize for Value { fn serialize(&self, s: S) -> Result where S: ser::Serializer { match *self { Value::Nil => s.serialize_unit(), Value::Boolean(v) => s.serialize_bool(v), Value::Integer(Integer { n }) => match n { IntPriv::PosInt(n) => s.serialize_u64(n), IntPriv::NegInt(n) => s.serialize_i64(n), }, Value::F32(v) => s.serialize_f32(v), Value::F64(v) => s.serialize_f64(v), Value::String(ref v) => match v.s { Ok(ref v) => s.serialize_str(v), Err(ref v) => Bytes::new(&v.0[..]).serialize(s), }, Value::Binary(ref v) => Bytes::new(&v[..]).serialize(s), Value::Array(ref array) => { let mut state = s.serialize_seq(Some(array.len()))?; for item in array { state.serialize_element(item)?; } state.end() } Value::Map(ref map) => { let mut state = s.serialize_map(Some(map.len()))?; for (key, val) in map { state.serialize_entry(key, val)?; } state.end() } Value::Ext(ty, ref buf) => { let value = (ty, Bytes::new(&buf[..])); s.serialize_newtype_struct(MSGPACK_EXT_STRUCT_NAME, &value) } } } } impl ser::Error for Error { #[cold] fn custom(msg: T) -> Self { Error::Syntax(format!("{msg}")) } } struct Serializer; /// Convert a `T` into `rmpv::Value` which is an enum that can represent any valid MessagePack data. /// /// This conversion can fail if `T`'s implementation of `Serialize` decides to fail. /// /// ```rust /// # use rmpv::Value; /// /// let val = rmpv::ext::to_value("John Smith").unwrap(); /// /// assert_eq!(Value::String("John Smith".into()), val); /// ``` #[inline] pub fn to_value(value: T) -> Result { value.serialize(Serializer) } impl ser::Serializer for Serializer { type Ok = Value; type Error = Error; type SerializeSeq = SerializeVec; type SerializeTuple = SerializeVec; type SerializeTupleStruct = SerializeVec; type SerializeTupleVariant = SerializeTupleVariant; type SerializeMap = DefaultSerializeMap; type SerializeStruct = SerializeVec; type SerializeStructVariant = SerializeStructVariant; #[inline] fn serialize_bool(self, val: bool) -> Result { Ok(Value::Boolean(val)) } #[inline] fn serialize_i8(self, val: i8) -> Result { self.serialize_i64(i64::from(val)) } #[inline] fn serialize_i16(self, val: i16) -> Result { self.serialize_i64(i64::from(val)) } #[inline] fn serialize_i32(self, val: i32) -> Result { self.serialize_i64(i64::from(val)) } #[inline] fn serialize_i64(self, val: i64) -> Result { Ok(Value::from(val)) } #[inline] fn serialize_u8(self, val: u8) -> Result { self.serialize_u64(u64::from(val)) } #[inline] fn serialize_u16(self, val: u16) -> Result { self.serialize_u64(u64::from(val)) } #[inline] fn serialize_u32(self, val: u32) -> Result { self.serialize_u64(u64::from(val)) } #[inline] fn serialize_u64(self, val: u64) -> Result { Ok(Value::from(val)) } #[inline] fn serialize_f32(self, val: f32) -> Result { Ok(Value::F32(val)) } #[inline] fn serialize_f64(self, val: f64) -> Result { Ok(Value::F64(val)) } #[inline] fn serialize_char(self, val: char) -> Result { let mut buf = String::new(); buf.push(val); self.serialize_str(&buf) } #[inline] fn serialize_str(self, val: &str) -> Result { Ok(Value::String(val.into())) } #[inline] fn serialize_bytes(self, val: &[u8]) -> Result { Ok(Value::Binary(val.into())) } #[inline] fn serialize_unit(self) -> Result { Ok(Value::Nil) } #[inline] fn serialize_unit_struct(self, _name: &'static str) -> Result { Ok(Value::Array(Vec::new())) } #[inline] fn serialize_unit_variant(self, _name: &'static str, idx: u32, _variant: &'static str) -> Result { let vec = vec![ Value::from(idx), Value::Array(Vec::new()) ]; Ok(Value::Array(vec)) } #[inline] fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result where T: Serialize { if name == MSGPACK_EXT_STRUCT_NAME { let mut ext_se = ExtSerializer::new(); value.serialize(&mut ext_se)?; return ext_se.value(); } to_value(value) } fn serialize_newtype_variant(self, _name: &'static str, idx: u32, _variant: &'static str, value: &T) -> Result where T: Serialize { let vec = vec![ Value::from(idx), Value::Array(vec![to_value(value)?]), ]; Ok(Value::Array(vec)) } #[inline] fn serialize_none(self) -> Result { self.serialize_unit() } #[inline] fn serialize_some(self, value: &T) -> Result where T: Serialize { value.serialize(self) } fn serialize_seq(self, len: Option) -> Result { let se = SerializeVec { vec: Vec::with_capacity(len.unwrap_or(0)), }; Ok(se) } fn serialize_tuple(self, len: usize) -> Result { self.serialize_seq(Some(len)) } fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result { self.serialize_tuple(len) } fn serialize_tuple_variant(self, _name: &'static str, idx: u32, _variant: &'static str, len: usize) -> Result { let se = SerializeTupleVariant { idx, vec: Vec::with_capacity(len), }; Ok(se) } fn serialize_map(self, len: Option) -> Result { let se = DefaultSerializeMap { map: Vec::with_capacity(len.unwrap_or(0)), next_key: None, }; Ok(se) } #[inline] fn serialize_struct(self, name: &'static str, len: usize) -> Result { self.serialize_tuple_struct(name, len) } #[inline] fn serialize_struct_variant(self, _name: &'static str, idx: u32, _variant: &'static str, len: usize) -> Result { let se = SerializeStructVariant { idx, vec: Vec::with_capacity(len), }; Ok(se) } } pub struct ExtSerializer { fields_se: Option, } impl ser::Serializer for &mut ExtSerializer { type Ok = (); type Error = Error; type SerializeSeq = ser::Impossible<(), Error>; type SerializeTuple = Self; type SerializeTupleStruct = ser::Impossible<(), Error>; type SerializeTupleVariant = ser::Impossible<(), Error>; type SerializeMap = ser::Impossible<(), Error>; type SerializeStruct = ser::Impossible<(), Error>; type SerializeStructVariant = ser::Impossible<(), Error>; #[inline] fn serialize_bytes(self, _val: &[u8]) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_bool(self, _val: bool) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_i8(self, _value: i8) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_i16(self, _val: i16) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_i32(self, _val: i32) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_i64(self, _val: i64) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_u8(self, _val: u8) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_u16(self, _val: u16) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_u32(self, _val: u32) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_u64(self, _val: u64) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_f32(self, _val: f32) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_f64(self, _val: f64) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_char(self, _val: char) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_str(self, _val: &str) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_unit(self) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_unit_struct(self, _name: &'static str) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_unit_variant(self, _name: &'static str, _idx: u32, _variant: &'static str) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result where T: Serialize { Err(::custom("expected tuple")) } #[inline] fn serialize_newtype_variant(self, _name: &'static str, _idx: u32, _variant: &'static str, _value: &T) -> Result where T: Serialize { Err(::custom("expected tuple")) } #[inline] fn serialize_none(self) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_some(self, _value: &T) -> Result where T: Serialize { Err(::custom("expected tuple")) } #[inline] fn serialize_seq(self, _len: Option) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_tuple(self, _len: usize) -> Result { // FIXME check len self.fields_se = Some(ExtFieldSerializer::new()); Ok(self) } #[inline] fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_tuple_variant(self, _name: &'static str, _idx: u32, _variant: &'static str, _len: usize) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_map(self, _len: Option) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { Err(::custom("expected tuple")) } #[inline] fn serialize_struct_variant(self, _name: &'static str, _idx: u32, _variant: &'static str, _len: usize) -> Result { Err(::custom("expected tuple")) } } impl SerializeTuple for &mut ExtSerializer { type Ok = (); type Error = Error; #[inline] fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize { match self.fields_se { Some(ref mut se) => value.serialize(&mut *se), None => { debug_assert!(false); Err(Error::Syntax(String::new())) } } } #[inline(always)] fn end(self) -> Result<(), Error> { Ok(()) } } pub struct ExtFieldSerializer { tag: Option, binary: Option>, } impl ser::Serializer for &mut ExtFieldSerializer { type Ok = (); type Error = Error; type SerializeSeq = ser::Impossible<(), Error>; type SerializeTuple = ser::Impossible<(), Error>; type SerializeTupleStruct = ser::Impossible<(), Error>; type SerializeTupleVariant = ser::Impossible<(), Error>; type SerializeMap = ser::Impossible<(), Error>; type SerializeStruct = ser::Impossible<(), Error>; type SerializeStructVariant = ser::Impossible<(), Error>; #[inline] fn serialize_i8(self, value: i8) -> Result { if self.tag.is_none() { self.tag.replace(value); Ok(()) } else { Err(::custom("received second i8")) } } #[inline] fn serialize_bytes(self, val: &[u8]) -> Result { if self.binary.is_none() { self.binary.replace(val.to_vec()); Ok(()) } else { Err(::custom("expected i8 and bytes")) } } #[inline] fn serialize_bool(self, _val: bool) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_i16(self, _val: i16) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_i32(self, _val: i32) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_i64(self, _val: i64) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_u8(self, _val: u8) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_u16(self, _val: u16) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_u32(self, _val: u32) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_u64(self, _val: u64) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_f32(self, _val: f32) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_f64(self, _val: f64) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_char(self, _val: char) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_str(self, _val: &str) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_unit(self) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_unit_struct(self, _name: &'static str) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_unit_variant(self, _name: &'static str, _idx: u32, _variant: &'static str) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result where T: Serialize { Err(::custom("expected i8 and bytes")) } fn serialize_newtype_variant(self, _name: &'static str, _idx: u32, _variant: &'static str, _value: &T) -> Result where T: Serialize { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_none(self) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_some(self, _value: &T) -> Result where T: Serialize { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_seq(self, _len: Option) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_tuple(self, _len: usize) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_tuple_variant(self, _name: &'static str, _idx: u32, _variant: &'static str, _len: usize) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_map(self, _len: Option) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { Err(::custom("expected i8 and bytes")) } #[inline] fn serialize_struct_variant(self, _name: &'static str, _idx: u32, _variant: &'static str, _len: usize) -> Result { Err(::custom("expected i8 and bytes")) } } impl ExtSerializer { #[inline] fn new() -> Self { Self { fields_se: None } } fn value(self) -> Result { match self.fields_se { Some(fields_se) => fields_se.value(), None => Err(::custom("expected tuple")) } } } impl ExtFieldSerializer { #[inline] fn new() -> Self { Self { tag: None, binary: None, } } fn value(self) -> Result { match (self.tag, self.binary) { (Some(tag), Some(binary)) => Ok(Value::Ext(tag, binary)), (Some(_), None) => Err(::custom("expected i8 and bytes")), (None, Some(_)) => Err(::custom("expected i8 and bytes")), (None, None) => Err(::custom("expected i8 and bytes")), } } } #[doc(hidden)] pub struct SerializeVec { vec: Vec, } /// Default implementation for tuple variant serialization. It packs given enums as a tuple of an /// index with a tuple of arguments. #[doc(hidden)] pub struct SerializeTupleVariant { idx: u32, vec: Vec, } #[doc(hidden)] pub struct DefaultSerializeMap { map: Vec<(Value, Value)>, next_key: Option, } #[doc(hidden)] pub struct SerializeStructVariant { idx: u32, vec: Vec, } impl SerializeSeq for SerializeVec { type Ok = Value; type Error = Error; #[inline] fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize { self.vec.push(to_value(value)?); Ok(()) } #[inline] fn end(self) -> Result { Ok(Value::Array(self.vec)) } } impl SerializeTuple for SerializeVec { type Ok = Value; type Error = Error; #[inline] fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize { ser::SerializeSeq::serialize_element(self, value) } #[inline] fn end(self) -> Result { ser::SerializeSeq::end(self) } } impl SerializeTupleStruct for SerializeVec { type Ok = Value; type Error = Error; #[inline] fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize { ser::SerializeSeq::serialize_element(self, value) } #[inline] fn end(self) -> Result { ser::SerializeSeq::end(self) } } impl ser::SerializeTupleVariant for SerializeTupleVariant { type Ok = Value; type Error = Error; #[inline] fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize { self.vec.push(to_value(value)?); Ok(()) } #[inline] fn end(self) -> Result { Ok(Value::Array(vec![Value::from(self.idx), Value::Array(self.vec)])) } } impl ser::SerializeMap for DefaultSerializeMap { type Ok = Value; type Error = Error; #[inline] fn serialize_key(&mut self, key: &T) -> Result<(), Error> where T: Serialize { self.next_key = Some(to_value(key)?); Ok(()) } fn serialize_value(&mut self, value: &T) -> Result<(), Error> where T: ser::Serialize { // Panic because this indicates a bug in the program rather than an // expected failure. let key = self.next_key.take() .expect("`serialize_value` called before `serialize_key`"); self.map.push((key, to_value(value)?)); Ok(()) } #[inline] fn end(self) -> Result { Ok(Value::Map(self.map)) } } impl SerializeStruct for SerializeVec { type Ok = Value; type Error = Error; #[inline] fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<(), Error> where T: Serialize { ser::SerializeSeq::serialize_element(self, value) } #[inline] fn end(self) -> Result { ser::SerializeSeq::end(self) } } impl ser::SerializeStructVariant for SerializeStructVariant { type Ok = Value; type Error = Error; #[inline] fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<(), Error> where T: Serialize { self.vec.push(to_value(value)?); Ok(()) } #[inline] fn end(self) -> Result { Ok(Value::Array(vec![ Value::from(self.idx), Value::Array(self.vec), ])) } } rmpv-1.3.0/src/lib.rs000064400000000000000000001171341046102023000125230ustar 00000000000000//! Contains Value and `ValueRef` structs and its conversion traits. #![forbid(unsafe_code)] use std::borrow::Cow; use std::convert::TryFrom; use std::fmt::{self, Debug, Display}; use std::iter::FromIterator; use std::ops::Index; use std::str::Utf8Error; use num_traits::NumCast; pub mod decode; pub mod encode; #[cfg(feature = "with-serde")] pub mod ext; #[derive(Copy, Clone, Debug, PartialEq)] enum IntPriv { /// Always non-less than zero. PosInt(u64), /// Always less than zero. NegInt(i64), } /// Name of Serde newtype struct to Represent Msgpack's Ext /// Msgpack Ext: Ext(tag, binary) /// Serde data model: _ExtStruct((tag, binary)) /// Example Serde impl for custom type: /// /// ```ignore /// #[derive(Debug, PartialEq, Serialize, Deserialize)] /// #[serde(rename = "_ExtStruct")] /// struct ExtStruct((i8, serde_bytes::ByteBuf)); /// /// test_round(ExtStruct((2, serde_bytes::ByteBuf::from(vec![5]))), /// Value::Ext(2, vec![5])); /// ``` pub const MSGPACK_EXT_STRUCT_NAME: &str = "_ExtStruct"; /// Represents a MessagePack integer, whether signed or unsigned. /// /// A `Value` or `ValueRef` that contains integer can be constructed using `From` trait. #[derive(Copy, Clone, PartialEq)] pub struct Integer { n: IntPriv, } impl Integer { /// Returns `true` if the integer can be represented as `i64`. #[inline] #[must_use] pub fn is_i64(&self) -> bool { match self.n { IntPriv::PosInt(n) => n <= std::i64::MAX as u64, IntPriv::NegInt(..) => true, } } /// Returns `true` if the integer can be represented as `u64`. #[inline] #[must_use] pub fn is_u64(&self) -> bool { match self.n { IntPriv::PosInt(..) => true, IntPriv::NegInt(..) => false, } } /// Returns the integer represented as `i64` if possible, or else `None`. #[inline] #[must_use] pub fn as_i64(&self) -> Option { match self.n { IntPriv::PosInt(n) => NumCast::from(n), IntPriv::NegInt(n) => Some(n), } } /// Returns the integer represented as `u64` if possible, or else `None`. #[inline] #[must_use] pub fn as_u64(&self) -> Option { match self.n { IntPriv::PosInt(n) => Some(n), IntPriv::NegInt(n) => NumCast::from(n), } } /// Returns the integer represented as `f64` if possible, or else `None`. #[inline] #[must_use] pub fn as_f64(&self) -> Option { match self.n { IntPriv::PosInt(n) => NumCast::from(n), IntPriv::NegInt(n) => NumCast::from(n), } } } impl Debug for Integer { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { Debug::fmt(&self.n, fmt) } } impl Display for Integer { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match self.n { IntPriv::PosInt(v) => Display::fmt(&v, fmt), IntPriv::NegInt(v) => Display::fmt(&v, fmt), } } } impl From for Integer { #[inline] fn from(n: u8) -> Self { Integer { n: IntPriv::PosInt(n as u64) } } } impl From for Integer { #[inline] fn from(n: u16) -> Self { Integer { n: IntPriv::PosInt(n as u64) } } } impl From for Integer { #[inline] fn from(n: u32) -> Self { Integer { n: IntPriv::PosInt(n as u64) } } } impl From for Integer { #[inline] fn from(n: u64) -> Self { Integer { n: IntPriv::PosInt(n) } } } impl From for Integer { #[inline] fn from(n: usize) -> Self { Integer { n: IntPriv::PosInt(n as u64) } } } impl From for Integer { #[inline] fn from(n: i8) -> Self { if n < 0 { Integer { n: IntPriv::NegInt(n as i64) } } else { Integer { n: IntPriv::PosInt(n as u64) } } } } impl From for Integer { #[inline] fn from(n: i16) -> Self { if n < 0 { Integer { n: IntPriv::NegInt(n as i64) } } else { Integer { n: IntPriv::PosInt(n as u64) } } } } impl From for Integer { #[inline] fn from(n: i32) -> Self { if n < 0 { Integer { n: IntPriv::NegInt(n as i64) } } else { Integer { n: IntPriv::PosInt(n as u64) } } } } impl From for Integer { #[inline] fn from(n: i64) -> Self { if n < 0 { Integer { n: IntPriv::NegInt(n) } } else { Integer { n: IntPriv::PosInt(n as u64) } } } } impl From for Integer { #[inline] fn from(n: isize) -> Self { if n < 0 { Integer { n: IntPriv::NegInt(n as i64) } } else { Integer { n: IntPriv::PosInt(n as u64) } } } } /// Represents an UTF-8 MessagePack string type. /// /// According to the MessagePack spec, string objects may contain invalid byte sequence and the /// behavior of a deserializer depends on the actual implementation when it received invalid byte /// sequence. /// Deserializers should provide functionality to get the original byte array so that applications /// can decide how to handle the object. /// /// Summarizing, it's prohibited to instantiate a string type with invalid UTF-8 sequences, however /// it is possible to obtain an underlying bytes that were attempted to convert to a `String`. This /// may happen when trying to unpack strings that were decoded using older MessagePack spec with /// raw types instead of string/binary. #[derive(Clone, Debug, PartialEq)] pub struct Utf8String { s: Result, Utf8Error)>, } impl Utf8String { /// Returns `true` if the string is valid UTF-8. #[inline] #[must_use] pub fn is_str(&self) -> bool { self.s.is_ok() } /// Returns `true` if the string contains invalid UTF-8 sequence. #[inline] #[must_use] pub fn is_err(&self) -> bool { self.s.is_err() } /// Returns the string reference if the string is valid UTF-8, or else `None`. #[inline] #[must_use] pub fn as_str(&self) -> Option<&str> { match self.s { Ok(ref s) => Some(s.as_str()), Err(..) => None, } } /// Returns the underlying `Utf8Error` if the string contains invalud UTF-8 sequence, or /// else `None`. #[inline] #[must_use] pub fn as_err(&self) -> Option<&Utf8Error> { match self.s { Ok(..) => None, Err((_, ref err)) => Some(err), } } /// Returns a byte slice of this `Utf8String`'s contents. #[inline] #[must_use] pub fn as_bytes(&self) -> &[u8] { match self.s { Ok(ref s) => s.as_bytes(), Err(ref err) => &err.0[..], } } /// Consumes this object, yielding the string if the string is valid UTF-8, or else `None`. #[inline] #[must_use] pub fn into_str(self) -> Option { self.s.ok() } /// Converts a `Utf8String` into a byte vector. #[inline] #[must_use] pub fn into_bytes(self) -> Vec { match self.s { Ok(s) => s.into_bytes(), Err(err) => err.0, } } #[inline] #[must_use] pub fn as_ref(&self) -> Utf8StringRef<'_> { match self.s { Ok(ref s) => Utf8StringRef { s: Ok(s.as_str()) }, Err((ref buf, err)) => Utf8StringRef { s: Err((&buf[..], err)) }, } } } impl Display for Utf8String { #[cold] fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match self.s { Ok(ref s) => Debug::fmt(&s, fmt), Err(ref err) => Debug::fmt(&err.0, fmt), } } } impl<'a> From for Utf8String { #[inline] fn from(val: String) -> Self { Utf8String { s: Ok(val) } } } impl<'a> From<&'a str> for Utf8String { #[inline] fn from(val: &str) -> Self { Utf8String { s: Ok(val.into()) } } } impl<'a> From> for Utf8String { #[inline] fn from(val: Cow<'a, str>) -> Self { Utf8String { s: Ok(val.into_owned()), } } } /// A non-owning evil twin of `Utf8String`. Does exactly the same thing except ownership. #[derive(Clone, Copy, Debug, PartialEq)] pub struct Utf8StringRef<'a> { s: Result<&'a str, (&'a [u8], Utf8Error)>, } impl<'a> Utf8StringRef<'a> { /// Returns `true` if the string is valid UTF-8. #[inline] #[must_use] pub fn is_str(&self) -> bool { self.s.is_ok() } /// Returns `true` if the string contains invalid UTF-8 sequence. #[inline] #[must_use] pub fn is_err(&self) -> bool { self.s.is_err() } /// Returns the string reference if the string is valid UTF-8, or else `None`. #[inline] #[must_use] pub fn as_str(&self) -> Option<&str> { match self.s { Ok(s) => Some(s), Err(..) => None, } } /// Returns the underlying `Utf8Error` if the string contains invalud UTF-8 sequence, or /// else `None`. #[inline] #[must_use] pub fn as_err(&self) -> Option<&Utf8Error> { match self.s { Ok(..) => None, Err((_, ref err)) => Some(err), } } /// Returns a byte slice of this string contents no matter whether it's valid or not UTF-8. #[inline] #[must_use] pub fn as_bytes(&self) -> &[u8] { match self.s { Ok(s) => s.as_bytes(), Err(ref err) => err.0, } } /// Consumes this object, yielding the string if the string is valid UTF-8, or else `None`. #[inline] #[must_use] pub fn into_string(self) -> Option { self.s.ok().map(|s| s.into()) } /// Consumes this object, yielding the string reference if the string is valid UTF-8, or else `None`. #[inline] #[must_use] pub fn into_str(self) -> Option<&'a str> { self.s.ok() } /// Converts a `Utf8StringRef` into a byte vector. #[inline] #[must_use] pub fn into_bytes(self) -> Vec { match self.s { Ok(s) => s.as_bytes().into(), Err(err) => err.0.into(), } } } impl<'a> Display for Utf8StringRef<'a> { #[cold] fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match self.s { Ok(ref s) => Debug::fmt(&s, fmt), Err(ref err) => Debug::fmt(&err.0, fmt), } } } impl<'a> From<&'a str> for Utf8StringRef<'a> { #[inline] fn from(val: &'a str) -> Self { Utf8StringRef { s: Ok(val) } } } impl<'a> From> for Utf8String { fn from(val: Utf8StringRef<'a>) -> Self { match val.s { Ok(s) => Utf8String { s: Ok(s.into()) }, Err((buf, err)) => Utf8String { s: Err((buf.into(), err)) }, } } } /// Represents any valid MessagePack value. #[derive(Clone, Debug, PartialEq)] pub enum Value { /// Nil represents nil. Nil, /// Boolean represents true or false. Boolean(bool), /// Integer represents an integer. /// /// A value of an `Integer` object is limited from `-(2^63)` upto `(2^64)-1`. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert_eq!(42, Value::from(42).as_i64().unwrap()); /// ``` Integer(Integer), /// A 32-bit floating point number. F32(f32), /// A 64-bit floating point number. F64(f64), /// String extending Raw type represents a UTF-8 string. /// /// # Note /// /// String objects may contain invalid byte sequence and the behavior of a deserializer depends /// on the actual implementation when it received invalid byte sequence. Deserializers should /// provide functionality to get the original byte array so that applications can decide how to /// handle the object String(Utf8String), /// Binary extending Raw type represents a byte array. Binary(Vec), /// Array represents a sequence of objects. Array(Vec), /// Map represents key-value pairs of objects. Map(Vec<(Value, Value)>), /// Extended implements Extension interface: represents a tuple of type information and a byte /// array where type information is an integer whose meaning is defined by applications. Ext(i8, Vec), } impl Value { /// Converts the current owned Value to a `ValueRef`. /// /// # Panics /// /// Panics in unable to allocate memory to keep all internal structures and buffers. /// /// # Examples /// ``` /// use rmpv::{Value, ValueRef}; /// /// let val = Value::Array(vec![ /// Value::Nil, /// Value::from(42), /// Value::Array(vec![ /// Value::String("le message".into()) /// ]) /// ]); /// /// let expected = ValueRef::Array(vec![ /// ValueRef::Nil, /// ValueRef::from(42), /// ValueRef::Array(vec![ /// ValueRef::from("le message"), /// ]) /// ]); /// /// assert_eq!(expected, val.as_ref()); /// ``` #[must_use] pub fn as_ref(&self) -> ValueRef<'_> { match *self { Value::Nil => ValueRef::Nil, Value::Boolean(val) => ValueRef::Boolean(val), Value::Integer(val) => ValueRef::Integer(val), Value::F32(val) => ValueRef::F32(val), Value::F64(val) => ValueRef::F64(val), Value::String(ref val) => ValueRef::String(val.as_ref()), Value::Binary(ref val) => ValueRef::Binary(val.as_slice()), Value::Array(ref val) => { ValueRef::Array(val.iter().map(|v| v.as_ref()).collect()) } Value::Map(ref val) => { ValueRef::Map(val.iter().map(|(k, v)| (k.as_ref(), v.as_ref())).collect()) } Value::Ext(ty, ref buf) => ValueRef::Ext(ty, buf.as_slice()), } } /// Returns true if the `Value` is a Null. Returns false otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert!(Value::Nil.is_nil()); /// ``` #[inline] #[must_use] pub fn is_nil(&self) -> bool { if let Value::Nil = *self { true } else { false } } /// Returns true if the `Value` is a Boolean. Returns false otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert!(Value::Boolean(true).is_bool()); /// /// assert!(!Value::Nil.is_bool()); /// ``` #[inline] #[must_use] pub fn is_bool(&self) -> bool { self.as_bool().is_some() } /// Returns true if the `Value` is convertible to an i64. Returns false otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert!(Value::from(42).is_i64()); /// /// assert!(!Value::from(42.0).is_i64()); /// ``` #[inline] #[must_use] pub fn is_i64(&self) -> bool { if let Value::Integer(ref v) = *self { v.is_i64() } else { false } } /// Returns true if the `Value` is convertible to an u64. Returns false otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert!(Value::from(42).is_u64()); /// /// assert!(!Value::F32(42.0).is_u64()); /// assert!(!Value::F64(42.0).is_u64()); /// ``` #[inline] #[must_use] pub fn is_u64(&self) -> bool { if let Value::Integer(ref v) = *self { v.is_u64() } else { false } } /// Returns true if (and only if) the `Value` is a f32. Returns false otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert!(Value::F32(42.0).is_f32()); /// /// assert!(!Value::from(42).is_f32()); /// assert!(!Value::F64(42.0).is_f32()); /// ``` #[inline] #[must_use] pub fn is_f32(&self) -> bool { if let Value::F32(..) = *self { true } else { false } } /// Returns true if (and only if) the `Value` is a f64. Returns false otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert!(Value::F64(42.0).is_f64()); /// /// assert!(!Value::from(42).is_f64()); /// assert!(!Value::F32(42.0).is_f64()); /// ``` #[inline] #[must_use] pub fn is_f64(&self) -> bool { if let Value::F64(..) = *self { true } else { false } } /// Returns true if the `Value` is a Number. Returns false otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert!(Value::from(42).is_number()); /// assert!(Value::F32(42.0).is_number()); /// assert!(Value::F64(42.0).is_number()); /// /// assert!(!Value::Nil.is_number()); /// ``` #[must_use] pub fn is_number(&self) -> bool { match *self { Value::Integer(..) | Value::F32(..) | Value::F64(..) => true, _ => false, } } /// Returns true if the `Value` is a String. Returns false otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert!(Value::String("value".into()).is_str()); /// /// assert!(!Value::Nil.is_str()); /// ``` #[inline] #[must_use] pub fn is_str(&self) -> bool { self.as_str().is_some() } /// Returns true if the `Value` is a Binary. Returns false otherwise. #[inline] #[must_use] pub fn is_bin(&self) -> bool { self.as_slice().is_some() } /// Returns true if the `Value` is an Array. Returns false otherwise. #[inline] #[must_use] pub fn is_array(&self) -> bool { self.as_array().is_some() } /// Returns true if the `Value` is a Map. Returns false otherwise. #[inline] #[must_use] pub fn is_map(&self) -> bool { self.as_map().is_some() } /// Returns true if the `Value` is an Ext. Returns false otherwise. #[inline] #[must_use] pub fn is_ext(&self) -> bool { self.as_ext().is_some() } /// If the `Value` is a Boolean, returns the associated bool. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert_eq!(Some(true), Value::Boolean(true).as_bool()); /// /// assert_eq!(None, Value::Nil.as_bool()); /// ``` #[inline] #[must_use] pub fn as_bool(&self) -> Option { if let Value::Boolean(val) = *self { Some(val) } else { None } } /// If the `Value` is an integer, return or cast it to a i64. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert_eq!(Some(42i64), Value::from(42).as_i64()); /// /// assert_eq!(None, Value::F64(42.0).as_i64()); /// ``` #[inline] #[must_use] pub fn as_i64(&self) -> Option { match *self { Value::Integer(ref n) => n.as_i64(), _ => None, } } /// If the `Value` is an integer, return or cast it to a u64. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert_eq!(Some(42u64), Value::from(42).as_u64()); /// /// assert_eq!(None, Value::from(-42).as_u64()); /// assert_eq!(None, Value::F64(42.0).as_u64()); /// ``` #[inline] #[must_use] pub fn as_u64(&self) -> Option { match *self { Value::Integer(ref n) => n.as_u64(), _ => None, } } /// If the `Value` is a number, return or cast it to a f64. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert_eq!(Some(42.0), Value::from(42).as_f64()); /// assert_eq!(Some(42.0), Value::F32(42.0f32).as_f64()); /// assert_eq!(Some(42.0), Value::F64(42.0f64).as_f64()); /// /// assert_eq!(Some(2147483647.0), Value::from(i32::MAX as i64).as_f64()); /// /// assert_eq!(None, Value::Nil.as_f64()); /// ``` #[must_use] pub fn as_f64(&self) -> Option { match *self { Value::Integer(ref n) => n.as_f64(), Value::F32(n) => Some(From::from(n)), Value::F64(n) => Some(n), _ => None, } } /// If the `Value` is a String, returns the associated str. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert_eq!(Some("le message"), Value::String("le message".into()).as_str()); /// /// assert_eq!(None, Value::Boolean(true).as_str()); /// ``` #[inline] #[must_use] pub fn as_str(&self) -> Option<&str> { if let Value::String(ref val) = *self { val.as_str() } else { None } } /// If the `Value` is a Binary or a String, returns the associated slice. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert_eq!(Some(&[1, 2, 3, 4, 5][..]), Value::Binary(vec![1, 2, 3, 4, 5]).as_slice()); /// /// assert_eq!(None, Value::Boolean(true).as_slice()); /// ``` #[must_use] pub fn as_slice(&self) -> Option<&[u8]> { if let Value::Binary(ref val) = *self { Some(val) } else if let Value::String(ref val) = *self { Some(val.as_bytes()) } else { None } } /// If the `Value` is an Array, returns the associated vector. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// let val = Value::Array(vec![Value::Nil, Value::Boolean(true)]); /// /// assert_eq!(Some(&vec![Value::Nil, Value::Boolean(true)]), val.as_array()); /// /// assert_eq!(None, Value::Nil.as_array()); /// ``` #[inline] #[must_use] pub fn as_array(&self) -> Option<&Vec> { if let Value::Array(ref array) = *self { Some(array) } else { None } } /// If the `Value` is a Map, returns the associated vector of key-value tuples. /// Returns None otherwise. /// /// # Note /// /// MessagePack represents map as a vector of key-value tuples. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// let val = Value::Map(vec![(Value::Nil, Value::Boolean(true))]); /// /// assert_eq!(Some(&vec![(Value::Nil, Value::Boolean(true))]), val.as_map()); /// /// assert_eq!(None, Value::Nil.as_map()); /// ``` #[inline] #[must_use] pub fn as_map(&self) -> Option<&Vec<(Value, Value)>> { if let Value::Map(ref map) = *self { Some(map) } else { None } } /// If the `Value` is an Ext, returns the associated tuple with a ty and slice. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::Value; /// /// assert_eq!(Some((42, &[1, 2, 3, 4, 5][..])), Value::Ext(42, vec![1, 2, 3, 4, 5]).as_ext()); /// /// assert_eq!(None, Value::Boolean(true).as_ext()); /// ``` #[inline] #[must_use] pub fn as_ext(&self) -> Option<(i8, &[u8])> { if let Value::Ext(ty, ref buf) = *self { Some((ty, buf)) } else { None } } } static NIL: Value = Value::Nil; static NIL_REF: ValueRef<'static> = ValueRef::Nil; impl Index for Value { type Output = Value; fn index(&self, index: usize) -> &Value { self.as_array().and_then(|v| v.get(index)).unwrap_or(&NIL) } } impl Index<&str> for Value { type Output = Value; fn index(&self, index: &str) -> &Value { if let Value::Map(ref map) = *self { if let Some(found) = map.iter().find( |(key, _val)| { if let Value::String(ref strval) = *key { if let Some(s) = strval.as_str() { if s == index { return true; } } } false }) { return &found.1; } } &NIL } } impl From for Value { #[inline] fn from(v: bool) -> Self { Value::Boolean(v) } } impl From for Value { #[inline] fn from(v: u8) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: u16) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: u32) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: u64) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: usize) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: i8) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: i16) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: i32) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: i64) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: isize) -> Self { Value::Integer(From::from(v)) } } impl From for Value { #[inline] fn from(v: f32) -> Self { Value::F32(v) } } impl From for Value { #[inline] fn from(v: f64) -> Self { Value::F64(v) } } impl From for Value { #[inline] fn from(v: String) -> Self { Value::String(Utf8String::from(v)) } } impl<'a> From<&'a str> for Value { #[inline] fn from(v: &str) -> Self { Value::String(Utf8String::from(v)) } } impl<'a> From> for Value { #[inline] fn from(v: Cow<'a, str>) -> Self { Value::String(Utf8String::from(v)) } } impl From> for Value { #[inline] fn from(v: Vec) -> Self { Value::Binary(v) } } impl<'a> From<&'a [u8]> for Value { #[inline] fn from(v: &[u8]) -> Self { Value::Binary(v.into()) } } impl<'a> From> for Value { #[inline] fn from(v: Cow<'a, [u8]>) -> Self { Value::Binary(v.into_owned()) } } impl From> for Value { #[inline] fn from(v: Vec) -> Self { Value::Array(v) } } impl From> for Value { #[inline] fn from(v: Vec<(Value, Value)>) -> Self { Value::Map(v) } } /// Note that an `Iterator` will be collected into an /// [`Array`](crate::Value::Array), rather than a /// [`Binary`](crate::Value::Binary) impl FromIterator for Value where V: Into { fn from_iter>(iter: I) -> Self { let v: Vec = iter.into_iter().map(|v| v.into()).collect(); Value::Array(v) } } impl TryFrom for u64 { type Error = Value; fn try_from(val: Value) -> Result { match val { Value::Integer(n) => { match n.as_u64() { Some(i) => Ok(i), None => Err(val) } } v => Err(v), } } } impl TryFrom for i64 { type Error = Value; fn try_from(val: Value) -> Result { match val { Value::Integer(n) => { match n.as_i64() { Some(i) => Ok(i), None => Err(val) } } v => Err(v), } } } impl TryFrom for f64 { type Error = Value; fn try_from(val: Value) -> Result { match val { Value::Integer(n) => { match n.as_f64() { Some(i) => Ok(i), None => Err(val) } } Value::F32(n) => Ok(From::from(n)), Value::F64(n) => Ok(n), v => Err(v), } } } impl TryFrom for String { type Error = Value; fn try_from(val: Value) -> Result { match val { Value::String(Utf8String{ s: Ok(u)}) => { Ok(u) } _ => Err(val) } } } // The following impl was left out intentionally, see // https://github.com/3Hren/msgpack-rust/pull/228#discussion_r359513925 /* impl TryFrom for (i8, Vec) { type Error = Value; fn try_from(val: Value) -> Result { match val { Value::Ext(i, v) => Ok((i, v)), v => Err(v), } } } */ macro_rules! impl_try_from { ($t: ty, $p: ident) => { impl TryFrom for $t { type Error = Value; fn try_from(val: Value) -> Result<$t, Self::Error> { match val { Value::$p(v) => Ok(v), v => Err(v) } } } }; } impl_try_from!(bool, Boolean); impl_try_from!(Vec, Array); impl_try_from!(Vec<(Value, Value)>, Map); impl_try_from!(Vec, Binary); impl_try_from!(f32, F32); impl_try_from!(Utf8String, String); impl Display for Value { #[cold] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match *self { Value::Nil => f.write_str("nil"), Value::Boolean(val) => Display::fmt(&val, f), Value::Integer(ref val) => Display::fmt(&val, f), Value::F32(val) => Display::fmt(&val, f), Value::F64(val) => Display::fmt(&val, f), Value::String(ref val) => Display::fmt(&val, f), Value::Binary(ref val) => Debug::fmt(&val, f), Value::Array(ref vec) => { // TODO: This can be slower than naive implementation. Need benchmarks for more // information. let res = vec.iter() .map(|val| format!("{val}")) .collect::>() .join(", "); write!(f, "[{res}]") } Value::Map(ref vec) => { write!(f, "{{")?; match vec.iter().take(1).next() { Some((k, v)) => { write!(f, "{k}: {v}")?; } None => { write!(f, "")?; } } for (k, v) in vec.iter().skip(1) { write!(f, ", {k}: {v}")?; } write!(f, "}}") } Value::Ext(ty, ref data) => { write!(f, "[{ty}, {data:?}]") } } } } #[derive(Clone, Debug, PartialEq)] pub enum ValueRef<'a> { /// Nil represents nil. Nil, /// Boolean represents true or false. Boolean(bool), /// Integer represents an integer. /// /// A value of an `Integer` object is limited from `-(2^63)` upto `(2^64)-1`. Integer(Integer), /// A 32-bit floating point number. F32(f32), /// A 64-bit floating point number. F64(f64), /// String extending Raw type represents a UTF-8 string. String(Utf8StringRef<'a>), /// Binary extending Raw type represents a byte array. Binary(&'a [u8]), /// Array represents a sequence of objects. Array(Vec>), /// Map represents key-value pairs of objects. Map(Vec<(ValueRef<'a>, ValueRef<'a>)>), /// Extended implements Extension interface: represents a tuple of type information and a byte /// array where type information is an integer whose meaning is defined by applications. Ext(i8, &'a [u8]), } impl<'a> ValueRef<'a> { /// Converts the current non-owning value to an owned Value. /// /// This is achieved by deep copying all underlying structures and borrowed buffers. /// /// # Panics /// /// Panics in unable to allocate memory to keep all internal structures and buffers. /// /// # Examples /// ``` /// use rmpv::{Value, ValueRef}; /// /// let val = ValueRef::Array(vec![ /// ValueRef::Nil, /// ValueRef::from(42), /// ValueRef::Array(vec![ /// ValueRef::from("le message"), /// ]) /// ]); /// /// let expected = Value::Array(vec![ /// Value::Nil, /// Value::from(42), /// Value::Array(vec![ /// Value::String("le message".into()) /// ]) /// ]); /// /// assert_eq!(expected, val.to_owned()); /// ``` #[must_use] pub fn to_owned(&self) -> Value { match *self { ValueRef::Nil => Value::Nil, ValueRef::Boolean(val) => Value::Boolean(val), ValueRef::Integer(val) => Value::Integer(val), ValueRef::F32(val) => Value::F32(val), ValueRef::F64(val) => Value::F64(val), ValueRef::String(val) => Value::String(val.into()), ValueRef::Binary(val) => Value::Binary(val.to_vec()), ValueRef::Array(ref val) => { Value::Array(val.iter().map(|v| v.to_owned()).collect()) } ValueRef::Map(ref val) => { Value::Map(val.iter().map(|(k, v)| (k.to_owned(), v.to_owned())).collect()) } ValueRef::Ext(ty, buf) => Value::Ext(ty, buf.to_vec()), } } #[must_use] pub fn index(&self, index: usize) -> &ValueRef<'_> { self.as_array().and_then(|v| v.get(index)).unwrap_or(&NIL_REF) } /// If the `ValueRef` is an integer, return or cast it to a u64. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::ValueRef; /// /// assert_eq!(Some(42), ValueRef::from(42).as_u64()); /// ``` #[must_use] pub fn as_u64(&self) -> Option { match *self { ValueRef::Integer(ref n) => n.as_u64(), _ => None, } } /// If the `ValueRef` is an Array, returns the associated vector. /// Returns None otherwise. /// /// # Examples /// /// ``` /// use rmpv::ValueRef; /// /// let val = ValueRef::Array(vec![ValueRef::Nil, ValueRef::Boolean(true)]); /// /// assert_eq!(Some(&vec![ValueRef::Nil, ValueRef::Boolean(true)]), val.as_array()); /// assert_eq!(None, ValueRef::Nil.as_array()); /// ``` #[must_use] pub fn as_array(&self) -> Option<&Vec>> { if let ValueRef::Array(ref array) = *self { Some(array) } else { None } } #[inline] #[must_use] pub fn into_array(self) -> Option>> { if let ValueRef::Array(array) = self { Some(array) } else { None } } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: u8) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: u16) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: u32) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: u64) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: usize) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: i8) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: i16) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: i32) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: i64) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: isize) -> Self { ValueRef::Integer(From::from(v)) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: f32) -> Self { ValueRef::F32(v) } } impl<'a> From for ValueRef<'a> { #[inline] fn from(v: f64) -> Self { ValueRef::F64(v) } } impl<'a> From<&'a str> for ValueRef<'a> { #[inline] fn from(v: &'a str) -> Self { ValueRef::String(Utf8StringRef::from(v)) } } impl<'a> From<&'a [u8]> for ValueRef<'a> { #[inline] fn from(v: &'a [u8]) -> Self { ValueRef::Binary(v) } } impl<'a> From>> for ValueRef<'a> { #[inline] fn from(v: Vec>) -> Self { ValueRef::Array(v) } } /// Note that an `Iterator` will be collected into an /// [`Array`](crate::Value::Array), rather than a /// [`Binary`](crate::Value::Binary) impl<'a, V> FromIterator for ValueRef<'a> where V: Into> { fn from_iter>(iter: I) -> Self { let v: Vec> = iter.into_iter().map(|v| v.into()).collect(); ValueRef::Array(v) } } impl<'a> From, ValueRef<'a>)>> for ValueRef<'a> { fn from(v: Vec<(ValueRef<'a>, ValueRef<'a>)>) -> Self { ValueRef::Map(v) } } impl<'a> TryFrom> for u64 { type Error = ValueRef<'a>; fn try_from(val: ValueRef<'a>) -> Result { match val { ValueRef::Integer(n) => match n.as_u64() { Some(i) => Ok(i), None => Err(val), }, v => Err(v), } } } // The following impl was left out intentionally, see // https://github.com/3Hren/msgpack-rust/pull/228#discussion_r359513925 /* impl<'a> TryFrom> for (i8, &'a[u8]) { type Error = ValueRef<'a>; fn try_from(val: ValueRef<'a>) -> Result { match val { ValueRef::Ext(i, v) => Ok((i, v)), v => Err(v), } } } */ macro_rules! impl_try_from_ref { ($t: ty, $p: ident) => { impl<'a> TryFrom> for $t { type Error = ValueRef<'a>; fn try_from(val: ValueRef<'a>) -> Result<$t, Self::Error> { match val { ValueRef::$p(v) => Ok(v), v => Err(v) } } } }; } impl_try_from_ref!(bool, Boolean); impl_try_from_ref!(Vec>, Array); impl_try_from_ref!(Vec<(ValueRef<'a>, ValueRef<'a>)>, Map); impl_try_from_ref!(&'a [u8], Binary); impl_try_from_ref!(f32, F32); impl_try_from_ref!(Utf8StringRef<'a>, String); impl<'a> Display for ValueRef<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match *self { ValueRef::Nil => write!(f, "nil"), ValueRef::Boolean(val) => Display::fmt(&val, f), ValueRef::Integer(ref val) => Display::fmt(&val, f), ValueRef::F32(val) => Display::fmt(&val, f), ValueRef::F64(val) => Display::fmt(&val, f), ValueRef::String(ref val) => Display::fmt(&val, f), ValueRef::Binary(ref val) => Debug::fmt(&val, f), ValueRef::Array(ref vec) => { let res = vec.iter() .map(|val| format!("{val}")) .collect::>() .join(", "); write!(f, "[{res}]") } ValueRef::Map(ref vec) => { write!(f, "{{")?; match vec.iter().take(1).next() { Some((k, v)) => { write!(f, "{k}: {v}")?; } None => { write!(f, "")?; } } for (k, v) in vec.iter().skip(1) { write!(f, ", {k}: {v}")?; } write!(f, "}}") } ValueRef::Ext(ty, data) => { write!(f, "[{ty}, {data:?}]") } } } } rmpv-1.3.0/tests/decode.rs000064400000000000000000000256031046102023000135520ustar 00000000000000use rmpv::decode::{read_value, Error}; use rmpv::Value; #[test] fn from_null_decode_value() { let buf = [0xc0]; assert_eq!(Value::Nil, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_pfix_decode_value() { let buf = [0x1f]; assert_eq!(Value::from(31), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_bool_decode_value() { let buf = [0xc3, 0xc2]; assert_eq!(Value::Boolean(true), read_value(&mut &buf[..]).unwrap()); assert_eq!(Value::Boolean(false), read_value(&mut &buf[1..]).unwrap()); } #[test] fn from_bin8_decode_value() { let buf: &[u8] = &[ 0xc4, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]; let expected = Value::Binary(vec!(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08)); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_bin16_decode_value() { let buf: &[u8] = &[ 0xc5, 0x00, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]; let expected = Value::Binary(vec!(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08)); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_bin32_decode_value() { let buf: &[u8] = &[ 0xc6, 0x00, 0x00, 0x00, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]; let expected = Value::Binary(vec!(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08)); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_i32_decode_value() { let buf = [0xd2, 0xff, 0xff, 0xff, 0xff]; assert_eq!(Value::from(-1), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_f64_decode_value() { let buf = [0xcb, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; assert_eq!(Value::F64(::std::f64::NEG_INFINITY), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_strfix_decode_value() { let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65]; assert_eq!(Value::String("le message".into()), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_fixarray_decode_value() { let buf = [ 0x93, 0x00, 0x2a, 0xf7 ]; let expected = Value::Array(vec![ Value::from(0), Value::from(42), Value::from(-9), ]); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_fixarray_incomplete_decode_value() { let buf = [ 0x93, 0x00, 0x2a ]; match read_value(&mut &buf[..]) { Err(Error::InvalidMarkerRead(..)) => {} other => panic!("unexpected result: {other:?}"), } } #[test] fn from_fixarray_decode_empty() { let buf: &[u8] = &[0x90]; assert_eq!(Value::Array(vec![]), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_fixarray_of_decode_max_length() { let buf: &[u8] = &[0x9f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]; let expected = Value::Array(vec![Value::from(1), Value::from(2), Value::from(3), Value::from(4), Value::from(5), Value::from(6), Value::from(7), Value::from(8), Value::from(9), Value::from(10), Value::from(11), Value::from(12), Value::from(13), Value::from(14), Value::from(15)]); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_array16_decode_value() { let buf: &[u8] = &[ 0xdc, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]; let expected = Value::Array(vec![Value::from(1), Value::from(2), Value::from(3), Value::from(4), Value::from(5), Value::from(6)]); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_array32_decode_value() { let buf: &[u8] = &[ 0xdd, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]; let expected = Value::Array(vec![Value::from(1), Value::from(2), Value::from(3), Value::from(4), Value::from(5), Value::from(6)]); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_fixmap_decode_value() { let buf = [ 0x82, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94, 0xa3, 0x6b, 0x65, 0x79, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65 ]; let expected = Value::Map(vec![ (Value::from(42), Value::from(100500)), (Value::String("key".into()), Value::String("value".into())), ]); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_map16_decode_value() { let buf = [ 0xde, 0x00, 0x02, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94, 0xa3, 0x6b, 0x65, 0x79, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65 ]; let expected = Value::Map(vec![ (Value::from(42), Value::from(100500)), (Value::String("key".into()), Value::String("value".into())), ]); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_map32_decode_value() { let buf = [ 0xdf, 0x00, 0x00, 0x00, 0x02, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94, 0xa3, 0x6b, 0x65, 0x79, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65 ]; let expected = Value::Map(vec![ (Value::from(42), Value::from(100500)), (Value::String("key".into()), Value::String("value".into())), ]); assert_eq!(expected, read_value(&mut &buf[..]).unwrap()); } #[test] fn from_fixext1_decode_value() { let buf = [0xd4, 0x01, 0x02]; assert_eq!(Value::Ext(1, vec![2]), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_fixext2_decode_value() { let buf = [0xd5, 0x01, 0x02, 0x03]; assert_eq!(Value::Ext(1, vec![2, 3]), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_fixext4_decode_value() { let buf = [0xd6, 0x01, 0x02, 0x03, 0x04, 0x05]; assert_eq!(Value::Ext(1, vec![2, 3, 4, 5]), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_fixext8_decode_value() { let buf = [0xd7, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]; assert_eq!(Value::Ext(1, vec![2, 3, 4, 5, 6, 7, 8, 9]), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_fixext16_decode_value() { let buf = [0xd8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]; assert_eq!(Value::Ext(1, vec![2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5, 6, 7, 8, 9]), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_ext8_decode_value() { let buf = [0xc7, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05]; assert_eq!(Value::Ext(1, vec![2, 3, 4, 5]), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_ext16_decode_value() { let buf = [0xc8, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05]; assert_eq!(Value::Ext(1, vec![2, 3, 4, 5]), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_ext32_decode_value() { let buf = [0xc9, 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05]; assert_eq!(Value::Ext(1, vec![2, 3, 4, 5]), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_str8_decode_value() { let buf: &[u8] = &[ 0xd9, 0x20, 0x42, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x45 ]; assert_eq!(Value::String("B123456789012345678901234567890E".into()), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_str8_invalid_utf8() { // Invalid 2 Octet Sequence. let buf: &[u8] = &[0xd9, 0x02, 0xc3, 0x28]; match read_value(&mut &buf[..]).unwrap() { Value::String(s) => { assert!(s.is_err()); assert_eq!(vec![0xc3, 0x28], s.into_bytes()); } _ => panic!("wrong type"), } } #[test] fn from_str16_decode_value() { let buf: &[u8] = &[ 0xda, 0x00, 0x20, 0x42, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x45 ]; assert_eq!(Value::String("B123456789012345678901234567890E".into()), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_str16_invalid_utf8() { // Invalid 2 Octet Sequence. let buf: &[u8] = &[0xda, 0x00, 0x02, 0xc3, 0x28]; match read_value(&mut &buf[..]).unwrap() { Value::String(s) => { assert!(s.is_err()); assert_eq!(vec![0xc3, 0x28], s.into_bytes()); } _ => panic!("wrong type"), } } #[test] fn from_str32_decode_value() { let buf: &[u8] = &[ 0xdb, 0x00, 0x00, 0x00, 0x20, 0x42, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x45 ]; assert_eq!(Value::String("B123456789012345678901234567890E".into()), read_value(&mut &buf[..]).unwrap()); } #[test] fn from_str32_invalid_utf8() { // Invalid 2 Octet Sequence. let buf: &[u8] = &[0xdb, 0x00, 0x00, 0x00, 0x02, 0xc3, 0x28]; match read_value(&mut &buf[..]).unwrap() { Value::String(s) => { assert!(s.is_err()); assert_eq!(vec![0xc3, 0x28], s.into_bytes()); } _ => panic!("wrong type"), } } #[test] fn from_array_of_two_integers() { let buf: &[u8] = &[0x92, 0x04, 0x2a]; let vec = vec![Value::from(4), Value::from(42)]; assert_eq!(Value::Array(vec), read_value(&mut &buf[..]).unwrap()); } #[test] fn invalid_buf_size_bin32() { // This invalid buffer requests a 4 GiB byte vec. let buf: &[u8] = &[0xc6, 0xff, 0xff, 0xff, 0xff, 0x00]; match read_value(&mut &buf[..]) { Ok(_) => panic!("Unexpected success"), Err(Error::InvalidDataRead(_)) => { /* expected */ }, Err(e) => panic!("Unexpected error: {e}"), } } #[test] fn invalid_buf_size_arr() { // This invalid buffer requests a nested array of depth 10. // All arrays contain the maximum possible number of elements. // If a byte is preallocated for every array content, // that would require 40 GiB of RAM. let buf: &[u8] = &[ 0xdd, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, ]; match read_value(&mut &buf[..]) { Ok(_) => panic!("Unexpected success"), Err(Error::InvalidMarkerRead(_)) => { /* expected */ }, Err(e) => panic!("Unexpected error: {e}"), } } rmpv-1.3.0/tests/decode_ref.rs000064400000000000000000000373311046102023000144070ustar 00000000000000use rmpv::decode::{read_value_ref, Error}; use rmpv::ValueRef; #[test] fn from_nil() { let buf = [0xc0]; let mut rd = &buf[..]; assert_eq!(ValueRef::Nil, read_value_ref(&mut rd).unwrap()); } #[test] fn from_bool_false() { let buf = [0xc2]; let mut rd = &buf[..]; assert_eq!(ValueRef::Boolean(false), read_value_ref(&mut rd).unwrap()); } #[test] fn from_bool_true() { let buf = [0xc3]; let mut rd = &buf[..]; assert_eq!(ValueRef::Boolean(true), read_value_ref(&mut rd).unwrap()); } #[test] fn from_null_read_twice() { use std::io::Cursor; let buf = [0xc0, 0xc0]; let mut cur1 = Cursor::new(&buf[..]); let v1 = read_value_ref(&mut cur1).unwrap(); let mut cur2 = Cursor::new(&buf[cur1.position() as usize..]); let v2 = read_value_ref(&mut cur2).unwrap(); assert_eq!(ValueRef::Nil, v1); assert_eq!(ValueRef::Nil, v2); } #[test] fn from_pfix() { let buf = [0x1f]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(31), read_value_ref(&mut rd).unwrap()); } #[test] fn from_nfix() { let buf = [0xe0]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(-32), read_value_ref(&mut rd).unwrap()); } #[test] fn from_u8() { let buf = [0xcc, 0xff]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(255), read_value_ref(&mut rd).unwrap()); } #[test] fn from_u16() { let buf = [0xcd, 0xff, 0xff]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(65535), read_value_ref(&mut rd).unwrap()); } #[test] fn from_u32() { let buf = [0xce, 0xff, 0xff, 0xff, 0xff]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(4294967295u32), read_value_ref(&mut rd).unwrap()); } #[test] fn from_u64() { let buf = [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(18446744073709551615u64), read_value_ref(&mut rd).unwrap()); } #[test] fn from_i8() { let buf = [0xd0, 0x7f]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(127), read_value_ref(&mut rd).unwrap()); } #[test] fn from_i16() { let buf = [0xd1, 0x7f, 0xff]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(32767), read_value_ref(&mut rd).unwrap()); } #[test] fn from_i32() { let buf = [0xd2, 0x7f, 0xff, 0xff, 0xff]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(2147483647), read_value_ref(&mut rd).unwrap()); } #[test] fn from_i64() { let buf = [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; let mut rd = &buf[..]; assert_eq!(ValueRef::from(9223372036854775807i64), read_value_ref(&mut rd).unwrap()); } #[test] fn from_f32() { let buf = [0xca, 0x7f, 0x7f, 0xff, 0xff]; let mut rd = &buf[..]; assert_eq!(ValueRef::F32(3.4028234e38_f32), read_value_ref(&mut rd).unwrap()); } #[test] fn from_f64() { use std::f64; let buf = [0xcb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; let mut rd = &buf[..]; assert_eq!(ValueRef::F64(f64::INFINITY), read_value_ref(&mut rd).unwrap()); } #[test] fn from_strfix() { let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65]; assert_eq!(ValueRef::from("le message"), read_value_ref(&mut &buf[..]).unwrap()); } #[test] fn from_str8() { let buf = [ 0xd9, // Type. 0x20, // Size 0x42, // B 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x45 // E ]; let mut slice = &buf[..]; assert_eq!(ValueRef::from("B123456789012345678901234567890E"), read_value_ref(&mut slice).ok().unwrap()); } #[test] fn from_str16() { let buf = [ 0xda, // Type. 0x00, 0x20, // Size 0x42, // B 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x45 // E ]; let mut slice = &buf[..]; assert_eq!(ValueRef::from("B123456789012345678901234567890E"), read_value_ref(&mut slice).ok().unwrap()); } #[test] fn from_str32() { let buf = [ 0xdb, // Type. 0x00, 0x00, 0x00, 0x20, // Size 0x42, // B 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x45 // E ]; let mut slice = &buf[..]; assert_eq!(ValueRef::from("B123456789012345678901234567890E"), read_value_ref(&mut slice).ok().unwrap()); } #[test] fn from_empty_buffer_invalid_marker_read() { let buf = []; let mut slice = &buf[..]; match read_value_ref(&mut slice).err().unwrap() { Error::InvalidMarkerRead(..) => (), _ => panic!(), } } #[test] fn from_empty_buffer_invalid_buffer_fill() { use rmpv::decode::value_ref::BorrowRead; use std::io::{self, Read}; struct ErrorRead; impl Read for ErrorRead { fn read(&mut self, _buf: &mut [u8]) -> io::Result { Err(io::Error::new(io::ErrorKind::Other, "Mock Error")) } } impl<'a> BorrowRead<'a> for ErrorRead { fn fill_buf(&self) -> &'a [u8] { &[] } fn consume(&mut self, _: usize) {} } let mut rd = ErrorRead; match read_value_ref(&mut rd).err().unwrap() { Error::InvalidMarkerRead(..) => (), _ => panic!(), } } #[test] fn from_string_insufficient_bytes_while_reading_length() { let buf = [0xd9]; let mut rd = &buf[..]; match read_value_ref(&mut rd).err().unwrap() { Error::InvalidDataRead(..) => (), _ => panic!(), } } #[test] fn from_string_insufficient_bytes_while_reading_data() { let buf = [ 0xd9, // Type. 0x20, // Size == 32 0x42, // B 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 ]; let mut rd = &buf[..]; match read_value_ref(&mut rd).err().unwrap() { Error::InvalidDataRead(..) => (), _ => panic!(), } } #[test] fn from_string_invalid_utf8() { // Invalid 2 Octet Sequence. let buf = [0xd9, 0x02, 0xc3, 0x28]; let mut rd = &buf[..]; match read_value_ref(&mut rd).unwrap() { ValueRef::String(s) => { assert!(s.is_err()); assert_eq!([0xc3, 0x28], s.as_bytes()); } _ => panic!("wrong type"), } } #[test] fn from_bin8() { let buf = [0xc4, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04]; let mut rd = &buf[..]; assert_eq!(ValueRef::Binary(&[0, 1, 2, 3, 4]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_bin16() { let buf = [0xc5, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04]; let mut rd = &buf[..]; assert_eq!(ValueRef::Binary(&[0, 1, 2, 3, 4]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_bin32() { let buf = [0xc6, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04]; let mut rd = &buf[..]; assert_eq!(ValueRef::Binary(&[0, 1, 2, 3, 4]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_bin8_eof_while_reading_data() { let buf = [0xc4, 0x05, 0x00, 0x01, 0x02, 0x03]; let mut rd = &buf[..]; match read_value_ref(&mut rd).err().unwrap() { Error::InvalidDataRead(..) => (), _ => panic!(), } } #[test] fn from_fixext1() { let buf = [0xd4, 0x2a, 0xff]; let mut rd = &buf[..]; assert_eq!(ValueRef::Ext(42, &[255]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_ext1_eof_while_reading_type() { let buf = [0xd4]; let mut rd = &buf[..]; match read_value_ref(&mut rd).err().unwrap() { Error::InvalidDataRead(..) => (), _ => panic!(), } } #[test] fn from_fixext2() { let buf = [0xd5, 0x2a, 0xff, 0xee]; let mut rd = &buf[..]; assert_eq!(ValueRef::Ext(42, &[255, 238]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_fixext4() { let buf = [0xd6, 0x2a, 0xff, 0xee, 0xdd, 0xcc]; let mut rd = &buf[..]; assert_eq!(ValueRef::Ext(42, &[255, 238, 221, 204]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_fixext8() { let buf = [0xd7, 0x2a, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88]; let mut rd = &buf[..]; assert_eq!(ValueRef::Ext(42, &[255, 238, 221, 204, 187, 170, 153, 136]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_fixext16() { let buf = [ 0xd8, 0x2a, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 ]; let mut rd = &buf[..]; assert_eq!(ValueRef::Ext(42, &[255, 238, 221, 204, 187, 170, 153, 136, 119, 102, 85, 68, 51, 34, 17, 0]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_ext8() { let buf = [0xc7, 0x04, 0x2a, 0xff, 0xee, 0xdd, 0xcc]; let mut rd = &buf[..]; assert_eq!(ValueRef::Ext(42, &[255, 238, 221, 204]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_ext16() { let buf = [0xc8, 0x00, 0x04, 0x2a, 0xff, 0xee, 0xdd, 0xcc]; let mut rd = &buf[..]; assert_eq!(ValueRef::Ext(42, &[255, 238, 221, 204]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_ext32() { let buf = [0xc9, 0x00, 0x00, 0x00, 0x04, 0x2a, 0xff, 0xee, 0xdd, 0xcc]; let mut rd = &buf[..]; assert_eq!(ValueRef::Ext(42, &[255, 238, 221, 204]), read_value_ref(&mut rd).ok().unwrap()); } #[test] fn from_fixmap() { let buf = [ 0x82, // size: 2 0x2a, // 42 0xce, 0x0, 0x1, 0x88, 0x94, // 100500 0xa3, 0x6b, 0x65, 0x79, // 'key' 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65 // 'value' ]; let mut rd = &buf[..]; let map = vec![ (ValueRef::from(42), ValueRef::from(100500)), (ValueRef::from("key"), ValueRef::from("value")), ]; let expected = ValueRef::Map(map); assert_eq!(expected, read_value_ref(&mut rd).unwrap()); } #[test] fn from_map16() { let buf = [ 0xde, 0x00, 0x01, 0xa3, 0x6b, 0x65, 0x79, // 'key' 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65 // 'value' ]; let mut rd = &buf[..]; let map = vec![(ValueRef::from("key"), ValueRef::from("value"))]; let expected = ValueRef::Map(map); assert_eq!(expected, read_value_ref(&mut rd).unwrap()); } #[test] fn from_map32() { let buf = [ 0xdf, 0x00, 0x00, 0x00, 0x01, 0xa3, 0x6b, 0x65, 0x79, // 'key' 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65 // 'value' ]; let mut rd = &buf[..]; let map = vec![(ValueRef::from("key"), ValueRef::from("value"))]; let expected = ValueRef::Map(map); assert_eq!(expected, read_value_ref(&mut rd).unwrap()); } #[test] fn from_fixarray() { let buf = [ 0x92, 0xa2, 0x76, 0x31, 0xa2, 0x76, 0x32, ]; let mut rd = &buf[..]; let vec = vec![ValueRef::from("v1"), ValueRef::from("v2")]; assert_eq!(ValueRef::Array(vec), read_value_ref(&mut rd).unwrap()); } #[test] fn from_array16() { let buf = [ 0xdc, 0x00, 0x02, 0xa2, 0x76, 0x31, 0xa2, 0x76, 0x32, ]; let mut rd = &buf[..]; let vec = vec![ValueRef::from("v1"), ValueRef::from("v2")]; assert_eq!(ValueRef::Array(vec), read_value_ref(&mut rd).unwrap()); } #[test] fn from_array32() { let buf = [ 0xdd, 0x00, 0x00, 0x00, 0x02, 0xa2, 0x76, 0x31, 0xa2, 0x76, 0x32, ]; let mut rd = &buf[..]; let vec = vec![ValueRef::from("v1"), ValueRef::from("v2")]; assert_eq!(ValueRef::Array(vec), read_value_ref(&mut rd).unwrap()); } #[test] fn from_fixmap_using_cursor() { use std::io::Cursor; let buf = [ 0x82, // size: 2 0x2a, // 42 0xce, 0x0, 0x1, 0x88, 0x94, // 100500 0xa3, 0x6b, 0x65, 0x79, // 'key' 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65 // 'value' ]; let mut rd = Cursor::new(&buf[..]); let map = vec![ (ValueRef::from(42), ValueRef::from(100500)), (ValueRef::from("key"), ValueRef::from("value")), ]; let expected = ValueRef::Map(map); assert_eq!(expected, read_value_ref(&mut rd).unwrap()); assert_eq!(17, rd.position()); } // [None, 42, ['le message'], {'map': [True, {42: 100500}], 'key': 'value'}, [1, 2, 3], {'key': {'k1': 'v1'}}] const COMPLEX_MSGPACK: [u8; 55] = [ 0x96, 0xc0, 0x2a, 0x91, 0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x82, 0xa3, 0x6d, 0x61, 0x70, 0x92, 0xc3, 0x81, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94, 0xa3, 0x6b, 0x65, 0x79, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x93, 0x1, 0x2, 0x3, 0x81, 0xa3, 0x6b, 0x65, 0x79, 0x81, 0xa2, 0x6b, 0x31, 0xa2, 0x76, 0x31 ]; fn get_complex_msgpack_value<'a>() -> ValueRef<'a> { ValueRef::Array(vec![ ValueRef::Nil, ValueRef::from(42), ValueRef::Array(vec![ ValueRef::from("le message"), ]), ValueRef::Map(vec![ ( ValueRef::from("map"), ValueRef::Array(vec![ ValueRef::Boolean(true), ValueRef::Map(vec![ ( ValueRef::from(42), ValueRef::from(100500) ) ]) ]) ), ( ValueRef::from("key"), ValueRef::from("value") ) ]), ValueRef::Array(vec![ ValueRef::from(1), ValueRef::from(2), ValueRef::from(3), ]), ValueRef::Map(vec![ ( ValueRef::from("key"), ValueRef::Map(vec![ ( ValueRef::from("k1"), ValueRef::from("v1") ) ]) ) ]) ]) } #[test] fn from_complex_value_using_slice() { let buf = COMPLEX_MSGPACK; let mut rd = &buf[..]; assert_eq!(get_complex_msgpack_value(), read_value_ref(&mut rd).unwrap()); } #[test] fn from_complex_value_using_cursor() { use std::io::Cursor; let buf = COMPLEX_MSGPACK; let mut rd = Cursor::new(&buf[..]); assert_eq!(get_complex_msgpack_value(), read_value_ref(&mut rd).unwrap()); assert_eq!(buf.len() as u64, rd.position()); } #[test] fn from_reserved() { let buf = [0xc1]; let mut rd = &buf[..]; assert_eq!(ValueRef::Nil, read_value_ref(&mut rd).unwrap()); } #[test] fn into_owned() { use rmpv::Value; let val = get_complex_msgpack_value(); let expected = Value::Array(vec![ Value::Nil, Value::from(42), Value::Array(vec![ Value::from("le message"), ]), Value::Map(vec![ ( Value::from("map"), Value::Array(vec![ Value::Boolean(true), Value::Map(vec![ ( Value::from(42), Value::from(100500) ) ]) ]) ), ( Value::from("key"), Value::from("value") ) ]), Value::Array(vec![ Value::from(1), Value::from(2), Value::from(3), ]), Value::Map(vec![ ( Value::from("key"), Value::Map(vec![ ( Value::from("k1"), Value::from("v1") ) ]) ) ]) ]); assert_eq!(expected, val.to_owned()); assert_eq!(expected.as_ref(), val); } rmpv-1.3.0/tests/encode_ref.rs000064400000000000000000000053341046102023000144170ustar 00000000000000use rmpv::encode::write_value_ref; use rmpv::ValueRef; #[test] fn pack_nil() { let mut buf = [0x00]; let val = ValueRef::Nil; write_value_ref(&mut &mut buf[..], &val).unwrap(); assert_eq!([0xc0], buf); } #[test] fn pack_nil_when_buffer_is_tool_small() { let mut buf = []; let val = ValueRef::Nil; match write_value_ref(&mut &mut buf[..], &val) { Err(..) => (), other => panic!("unexpected result: {other:?}"), } } #[test] fn pass_pack_true() { let mut buf = [0x00]; let val = ValueRef::Boolean(true); write_value_ref(&mut &mut buf[..], &val).unwrap(); assert_eq!([0xc3], buf); } #[test] fn pass_pack_uint_u16() { let mut buf = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; let val = ValueRef::from(65535); write_value_ref(&mut &mut buf[..], &val).unwrap(); assert_eq!([0xcd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], buf); } #[test] fn pass_pack_i64() { let mut buf = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; let val = ValueRef::from(-9223372036854775808i64); write_value_ref(&mut &mut buf[..], &val).unwrap(); assert_eq!([0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], buf); } fn check_packed_eq(expected: &Vec, actual: &ValueRef<'_>) { let mut buf = Vec::new(); write_value_ref(&mut buf, actual).unwrap(); assert_eq!(*expected, buf); } #[test] fn pass_pack_f32() { check_packed_eq( &vec![0xca, 0x7f, 0x7f, 0xff, 0xff], &ValueRef::F32(3.4028234e38_f32), ); } #[test] fn pass_pack_f64() { use std::f64; check_packed_eq( &vec![0xcb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], &ValueRef::F64(f64::INFINITY), ); } #[test] fn pass_pack_string() { check_packed_eq( &vec![0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65], &ValueRef::from("le message") ); } #[test] fn pass_pack_bin() { check_packed_eq( &vec![0xc4, 0x0a, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65], &ValueRef::Binary(&[0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65]) ); } #[test] fn pass_pack_array() { check_packed_eq( &vec![0x93, 0x01, 0x02, 0x03], &ValueRef::Array( vec![ ValueRef::from(1), ValueRef::from(2), ValueRef::from(3) ] ) ); } #[test] fn pass_pack_map() { check_packed_eq( &vec![0x81, 0x01, 0x02], &ValueRef::Map( vec![(ValueRef::from(1), ValueRef::from(2))] ) ); } #[test] fn pass_pack_ext() { check_packed_eq( &vec![0xc7, 0x03, 0x10, 0x01, 0x02, 0x03], &ValueRef::Ext(16, &[0x01, 0x02, 0x03]), ); } rmpv-1.3.0/tests/mirror.rs000064400000000000000000000020471046102023000136360ustar 00000000000000#[macro_use] extern crate quickcheck; use rmpv::decode::read_value; use rmpv::encode::write_value; use rmpv::Value; fn mirror_test(xs: T) -> bool where Value: From { let mut buf = Vec::new(); write_value(&mut buf, &Value::from(xs.clone())).unwrap(); Value::from(xs) == read_value(&mut &buf[..]).unwrap() } quickcheck! { fn mirror_uint(xs: u64) -> bool { mirror_test(xs) } fn mirror_sint(xs: i64) -> bool { mirror_test(xs) } fn mirror_f32_value(xs: f32) -> bool { let mut buf = Vec::new(); write_value(&mut buf, &Value::from(xs)).unwrap(); let eq = Value::from(xs) == read_value(&mut &buf[..]).unwrap(); eq || (!eq && xs.is_nan()) } fn mirror_f64_value(xs: f64) -> bool { let mut buf = Vec::new(); write_value(&mut buf, &Value::from(xs)).unwrap(); let eq = Value::from(xs) == read_value(&mut &buf[..]).unwrap(); eq || (!eq && xs.is_nan()) } fn mirror_str(xs: String) -> bool { mirror_test(xs) } } rmpv-1.3.0/tests/value.rs000064400000000000000000000114041046102023000134350ustar 00000000000000use rmpv::Value; #[test] fn display_nil() { assert_eq!("nil", format!("{}", Value::Nil)); } #[test] fn display_bool() { assert_eq!("true", format!("{}", Value::Boolean(true))); assert_eq!("false", format!("{}", Value::Boolean(false))); } #[test] fn display_int() { assert_eq!("42", format!("{}", Value::from(42))); assert_eq!("42", format!("{}", Value::from(42))); } #[test] fn display_float() { assert_eq!("3.1415", format!("{}", Value::F32(3.1415))); assert_eq!("3.1415", format!("{}", Value::F64(3.1415))); } #[test] fn display_string() { assert_eq!("\"le string\"", format!("{}", Value::String("le string".into()))); } #[test] fn display_binary() { assert_eq!("[108, 101, 32, 115, 116, 114, 105, 110, 103]", format!("{}", Value::Binary(b"le string".to_vec()))); } #[test] fn display_array() { assert_eq!("[]", format!("{}", Value::Array(vec![]))); assert_eq!("[nil]", format!("{}", Value::Array(vec![Value::Nil]))); assert_eq!("[nil, nil]", format!("{}", Value::Array(vec![Value::Nil, Value::Nil]))); } #[test] fn display_map() { assert_eq!("{}", format!("{}", Value::Map(vec![]))); assert_eq!("{nil: nil}", format!("{}", Value::Map(vec![(Value::Nil, Value::Nil)]))); assert_eq!("{nil: nil, true: false}", format!("{}", Value::Map(vec![(Value::Nil, Value::Nil), (Value::Boolean(true), Value::Boolean(false))]))); } #[test] fn display_ext() { assert_eq!("[1, []]", format!("{}", Value::Ext(1, vec![]))); assert_eq!("[1, [100]]", format!("{}", Value::Ext(1, vec![100]))); assert_eq!("[1, [100, 42]]", format!("{}", Value::Ext(1, vec![100, 42]))); } #[test] fn from_bool() { assert_eq!(Value::Boolean(true), Value::from(true)); assert_eq!(Value::Boolean(false), Value::from(false)); } #[test] fn from_u8() { assert_eq!(Value::from(42), Value::from(42u8)); } #[test] fn from_u16() { assert_eq!(Value::from(42), Value::from(42u16)); } #[test] fn from_u32() { assert_eq!(Value::from(42), Value::from(42u32)); } #[test] fn from_u64() { assert_eq!(Value::from(42), Value::from(42u64)); } #[test] fn from_usize() { assert_eq!(Value::from(42), Value::from(42usize)); } #[test] fn from_i8() { assert_eq!(Value::from(-42), Value::from(-42i8)); } #[test] fn from_i16() { assert_eq!(Value::from(-42), Value::from(-42i16)); } #[test] fn from_i32() { assert_eq!(Value::from(-42), Value::from(-42i32)); } #[test] fn from_i64() { assert_eq!(Value::from(-42), Value::from(-42i64)); } #[test] fn from_isize() { assert_eq!(Value::from(-42), Value::from(-42isize)); } #[test] fn from_f32() { assert_eq!(Value::F32(3.1415), Value::from(3.1415f32)); } #[test] fn from_f64() { assert_eq!(Value::F64(3.1415), Value::from(3.1415f64)); } #[test] fn from_iterator() { let v: Vec = vec![0u8, 1u8, 2u8]; let w: Value = v.into_iter().collect(); let w2 = Value::Array(vec![ Value::from(0u8), Value::from(1u8), Value::from(2u8) ]); assert_eq!(w, w2); let w3 = Value::Binary(vec![0u8, 1u8, 2u8]); assert!(w != w3); } #[test] fn is_nil() { assert!(Value::Nil.is_nil()); assert!(!Value::Boolean(true).is_nil()); } #[test] fn monadic_index() { let val = Value::Array(vec![ Value::Array(vec![ Value::String("value".into()), Value::Boolean(true), ]), Value::Boolean(false), ]); assert_eq!("value", val[0][0].as_str().unwrap()); assert!(val[0][1].as_bool().unwrap()); assert!(!val[1].as_bool().unwrap()); assert!(val[0][0][0].is_nil()); assert!(val[2].is_nil()); assert!(val[1][2][3][4][5].is_nil()); } #[test] fn index_into_map() { let val = Value::Map(vec![ ( Value::String("a".into()), Value::from(1) ), ( Value::String("b".into()), Value::Array(vec![ Value::from(3), Value::from(4), Value::from(5) ])), ( Value::String("c".into()), Value::Map(vec![ ( Value::String("d".into()), Value::from(8) ), ( Value::String("e".into()), Value::from(9) ) ])) ]); assert_eq!(1, val["a"].as_i64().unwrap()); assert_eq!(5, val["b"][2].as_i64().unwrap()); assert_eq!(9, val["c"]["e"].as_i64().unwrap()); assert!(val["b"][3].is_nil()); assert!(val["d"][4].is_nil()); } #[test] fn try_from_val() { use rmpv::Utf8String; use std::convert::TryInto; assert_eq!(false, Value::Boolean(false).try_into().unwrap()); assert_eq!(Utf8String::from("spook"), Value::from("spook").try_into().unwrap()); assert_eq!(String::from("spook"), TryInto::::try_into(Value::from("spook")).unwrap()); assert_eq!(vec![0], TryInto::>::try_into(Value::Binary(vec![0u8])).unwrap()); }