1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
pub mod float;
pub mod from;
pub mod integer;
pub mod utf8_string;
pub use float::Float;
pub use float::Number as FloatNumber;
pub use integer::Integer;
pub use integer::Number as IntegerNumber;
pub use utf8_string::{Utf8String, Utf8StringRef};
use chrono::{self, TimeZone};
use std::fmt;
pub struct Nil;
#[derive(Clone, PartialEq, Debug)]
pub enum Value {
// represents an integer
Integer(integer::Integer),
// represents nil
Nil,
// represents true or false
Boolean(bool),
// represents a IEEE 754 double precision floating point number including NaN and Infinity
Float(float::Float),
// Raw. extending Raw type represents a byte array
Binary(Vec<u8>),
// Raw. extending Raw type represents a UTF-8 string
String(utf8_string::Utf8String),
// represents a sequence of objects
Array(Vec<Value>),
// represents key-value pairs of objects
Map(Vec<(Value, Value)>),
// represents a tuple of type information and a byte array where type information is an integer whose meaning is defined by applications or MessagePack specification
Extension(i8, Vec<u8>),
// represents an instantaneous point on the time-line in the world that is independent from time zones or calendars. Maximum precision is nanoseconds.
Timestamp(i64, u32),
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Value::Nil => write!(f, "null"),
Value::Boolean(val) => write!(f, "{}", if *val { "true" } else { "false" }),
Value::Float(val) => val.fmt(f),
Value::Integer(val) => val.fmt(f),
Value::Binary(ref val) => {
for v in val {
write!(f, "{:02X}", v)?;
}
Ok(())
}
Value::String(ref val) => val.fmt(f),
Value::Array(ref val) => {
write!(f, "[")?;
let mut s = true;
for v in val {
if s {
s = false
} else {
write!(f, ", ")?;
}
v.fmt(f)?;
}
write!(f, "]")
}
Value::Map(ref val) => {
write!(f, "{{")?;
let mut s = true;
for v in val {
if s {
s = false
} else {
write!(f, ", ")?;
}
write!(f, "{}: {}", v.0, v.1)?;
}
write!(f, "}}")
}
Value::Extension(ty, ref buf) => {
write!(f, "Extension({}, ", ty)?;
for b in buf {
write!(f, "{:X}", b)?;
}
write!(f, ")")
}
Value::Timestamp(sec, nsec) => {
write!(f, "{}", chrono::Local.timestamp(*sec as i64, *nsec))
}
}
}
}
#[derive(Debug, PartialEq)]
pub enum RefValue<'a> {
// represents an integer
Integer(integer::Integer),
// represents nil
Nil,
// represents true or false
Boolean(bool),
// represents a IEEE 754 double precision floating point number including NaN and Infinity
Float(float::Float),
// Raw. extending Raw type represents a byte array
Binary(&'a [u8]),
// Raw. extending Raw type represents a UTF-8 string
String(utf8_string::Utf8StringRef<'a>),
// represents a sequence of objects
Array(Vec<RefValue<'a>>),
// represents key-value pairs of objects
Map(Vec<(RefValue<'a>, RefValue<'a>)>),
// represents a tuple of type information and a byte array where type information is an integer whose meaning is defined by applications or MessagePack specification
Extension(i8, &'a [u8]),
// represents an instantaneous point on the time-line in the world that is independent from time zones or calendars. Maximum precision is nanoseconds.
Timestamp(i64, u32),
}
impl<'a> fmt::Display for RefValue<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RefValue::Nil => write!(f, "null"),
RefValue::Boolean(val) => write!(f, "{}", if *val { "true" } else { "false" }),
RefValue::Float(val) => val.fmt(f),
RefValue::Integer(val) => val.fmt(f),
RefValue::Binary(val) => {
for v in *val {
write!(f, "{:02X}", v)?;
}
Ok(())
}
RefValue::String(ref val) => val.fmt(f),
RefValue::Array(ref val) => {
write!(f, "[")?;
let mut s = true;
for v in val {
if s {
s = false
} else {
write!(f, ", ")?;
}
v.fmt(f)?;
}
write!(f, "]")
}
RefValue::Map(ref val) => {
write!(f, "{{")?;
let mut s = true;
for v in val {
if s {
s = false
} else {
write!(f, ", ")?;
}
write!(f, "{}: {}", v.0, v.1)?;
}
write!(f, "}}")
}
RefValue::Extension(ty, buf) => {
write!(f, "Extension({}, ", ty)?;
for b in *buf {
write!(f, "{:X}", b)?;
}
write!(f, ")")
}
RefValue::Timestamp(sec, nsec) => {
write!(f, "{}", chrono::Local.timestamp(*sec as i64, *nsec))
}
}
}
}
impl Value {
pub fn to_ref(&self) -> RefValue {
match self {
&Value::Nil => RefValue::Nil,
&Value::Boolean(val) => RefValue::Boolean(val),
&Value::Float(v) => RefValue::Float(v),
&Value::Integer(val) => RefValue::Integer(val),
&Value::Binary(ref v) => RefValue::Binary(v.as_slice()),
&Value::String(ref v) => RefValue::String(v.as_ref()), // XXX
&Value::Array(ref v) => RefValue::Array(v.iter().map(|v| v.to_ref()).collect()),
&Value::Map(ref v) => RefValue::Map(
v.iter()
.map(|&(ref k, ref v)| (k.to_ref(), v.to_ref()))
.collect(),
),
&Value::Extension(ty, ref buf) => RefValue::Extension(ty, buf.as_slice()),
&Value::Timestamp(sec, nsec) => RefValue::Timestamp(sec, nsec),
}
}
pub fn to_nil(&self) -> Option<Nil> {
match self {
Value::Nil => Some(Nil),
_ => None,
}
}
pub fn to_ary(&self) -> Option<&Vec<Value>> {
match self {
Value::Array(v) => Some(v),
_ => None,
}
}
}
impl<'a> RefValue<'a> {
pub fn to_owned(&self) -> Value {
match self {
&RefValue::Nil => Value::Nil,
&RefValue::Boolean(v) => Value::Boolean(v),
&RefValue::Integer(v) => Value::Integer(v),
&RefValue::Float(v) => Value::Float(v),
&RefValue::Binary(v) => Value::Binary(v.into()),
&RefValue::String(v) => Value::String(v.into()), // XXX
&RefValue::Array(ref v) => Value::Array(v.iter().map(|v| v.to_owned()).collect()),
&RefValue::Map(ref v) => Value::Map(
v.iter()
.map(|&(ref k, ref v)| (k.to_owned(), v.to_owned()))
.collect(),
),
&RefValue::Extension(ty, buf) => Value::Extension(ty, buf.into()),
&RefValue::Timestamp(sec, nsec) => Value::Timestamp(sec, nsec),
}
}
pub fn to_nil(&self) -> Option<Nil> {
match self {
RefValue::Nil => Some(Nil),
_ => None,
}
}
pub fn to_ary(&self) -> Option<&Vec<RefValue>> {
match self {
RefValue::Array(v) => Some(v),
_ => None,
}
}
pub fn to_str(&self) -> Option<&str> {
match self {
RefValue::String(v) => v.as_str(),
_ => None,
}
}
pub fn to_slice(&self) -> Option<&[u8]> {
match self {
RefValue::String(v) => Some(v.as_slice()),
_ => None,
}
}
}