1use crate::wire::marshal::traits::Signature;
4use crate::wire::unmarshal;
5use crate::wire::unmarshal::UnmarshalContext;
6
7mod base;
9mod container;
10pub use base::*;
11pub use container::*;
12
13pub trait Unmarshal<'buf, 'fds>: Sized + Signature {
139 fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> unmarshal::UnmarshalResult<Self>;
140}
141
142pub fn unmarshal<'buf, 'fds, T: Unmarshal<'buf, 'fds>>(
143 ctx: &mut UnmarshalContext<'fds, 'buf>,
144) -> unmarshal::UnmarshalResult<T> {
145 T::unmarshal(ctx)
146}
147
148#[cfg(test)]
149mod test {
150 use super::unmarshal;
151 use super::Unmarshal;
152 use super::UnmarshalContext;
153 use super::Variant;
154 use crate::wire::marshal::MarshalContext;
155 use crate::ByteOrder;
156 use crate::Marshal;
157 use crate::Signature;
158
159 #[test]
160 fn test_generic_unmarshal() {
161 let mut fds = Vec::new();
162 let mut buf = Vec::new();
163 let mut ctx = MarshalContext {
164 buf: &mut buf,
165 fds: &mut fds,
166 byteorder: ByteOrder::LittleEndian,
167 };
168 let ctx = &mut ctx;
169
170 "ABCD".marshal(ctx).unwrap();
172 let _s: &str = unmarshal(&mut UnmarshalContext {
173 buf: &ctx.buf,
174 byteorder: ctx.byteorder,
175 fds: &ctx.fds,
176 offset: 0,
177 })
178 .unwrap()
179 .1;
180
181 ctx.buf.clear();
183 true.marshal(ctx).unwrap();
184 let _b: bool = unmarshal(&mut UnmarshalContext {
185 buf: &ctx.buf,
186 byteorder: ctx.byteorder,
187 fds: &ctx.fds,
188 offset: 0,
189 })
190 .unwrap()
191 .1;
192
193 ctx.buf.clear();
195 0i32.marshal(ctx).unwrap();
196 let _i = unmarshal::<i32>(&mut UnmarshalContext {
197 buf: &ctx.buf,
198 byteorder: ctx.byteorder,
199 fds: &ctx.fds,
200 offset: 0,
201 })
202 .unwrap()
203 .1;
204
205 ctx.buf.clear();
207 fn x(_arg: (i32, i32, &str)) {}
208 (0, 0, "ABCD").marshal(ctx).unwrap();
209 let arg = unmarshal(&mut UnmarshalContext {
210 buf: &ctx.buf,
211 byteorder: ctx.byteorder,
212 fds: &ctx.fds,
213 offset: 0,
214 })
215 .unwrap()
216 .1;
217 x(arg);
218 }
219
220 #[test]
221 fn test_unmarshal_byte_array() {
222 use crate::wire::marshal::MarshalContext;
223 use crate::Marshal;
224
225 let mut orig = vec![];
226 for x in 0..1024 {
227 orig.push((x % 255) as u8);
228 }
229
230 let mut fds = Vec::new();
231 let mut buf = Vec::new();
232 let mut ctx = MarshalContext {
233 buf: &mut buf,
234 fds: &mut fds,
235 byteorder: ByteOrder::LittleEndian,
236 };
237 let ctx = &mut ctx;
238
239 orig.marshal(ctx).unwrap();
240 assert_eq!(&ctx.buf[..4], &[0, 4, 0, 0]);
241 assert_eq!(ctx.buf.len(), 1028);
242 let (bytes, unorig) = <&[u8] as Unmarshal>::unmarshal(&mut UnmarshalContext {
243 buf: ctx.buf,
244 fds: ctx.fds,
245 byteorder: ctx.byteorder,
246 offset: 0,
247 })
248 .unwrap();
249 assert_eq!(bytes, orig.len() + 4);
250 assert_eq!(orig, unorig);
251
252 let mut orig1 = vec![];
254 let mut orig2 = vec![];
255 for x in 0..1024 {
256 orig1.push((x % 255) as u8);
257 }
258 for x in 0..1024 {
259 orig2.push(((x + 4) % 255) as u8);
260 }
261
262 let orig = vec![orig1.as_slice(), orig2.as_slice()];
263
264 ctx.buf.clear();
265 orig.marshal(ctx).unwrap();
266
267 let (_bytes, unorig) = <Vec<&[u8]> as Unmarshal>::unmarshal(&mut UnmarshalContext {
269 buf: ctx.buf,
270 fds: ctx.fds,
271 byteorder: ctx.byteorder,
272 offset: 0,
273 })
274 .unwrap();
275 assert_eq!(orig, unorig);
276 }
277
278 #[test]
279 fn test_unmarshal_traits() {
280 use crate::wire::marshal::MarshalContext;
281 use crate::Marshal;
282
283 let mut fds = Vec::new();
284 let mut buf = Vec::new();
285 let mut ctx = MarshalContext {
286 buf: &mut buf,
287 fds: &mut fds,
288 byteorder: ByteOrder::LittleEndian,
289 };
290 let ctx = &mut ctx;
291
292 let original = &["a", "b"];
293 original.marshal(ctx).unwrap();
294
295 let (_, v) = Vec::<&str>::unmarshal(&mut UnmarshalContext {
296 buf: ctx.buf,
297 fds: ctx.fds,
298 byteorder: ctx.byteorder,
299 offset: 0,
300 })
301 .unwrap();
302
303 assert_eq!(original, v.as_slice());
304
305 ctx.buf.clear();
306
307 let mut original = std::collections::HashMap::new();
308 original.insert(0u64, "abc");
309 original.insert(1u64, "dce");
310 original.insert(2u64, "fgh");
311
312 original.marshal(ctx).unwrap();
313
314 let (_, map) = std::collections::HashMap::<u64, &str>::unmarshal(&mut UnmarshalContext {
315 buf: ctx.buf,
316 fds: ctx.fds,
317 byteorder: ctx.byteorder,
318 offset: 0,
319 })
320 .unwrap();
321 assert_eq!(original, map);
322
323 ctx.buf.clear();
324
325 let orig = (30u8, true, 100u8, -123i32);
326 orig.marshal(ctx).unwrap();
327 type ST = (u8, bool, u8, i32);
328 let s = ST::unmarshal(&mut UnmarshalContext {
329 buf: ctx.buf,
330 fds: ctx.fds,
331 byteorder: ctx.byteorder,
332 offset: 0,
333 })
334 .unwrap()
335 .1;
336 assert_eq!(orig, s);
337
338 ctx.buf.clear();
339
340 use crate::wire::UnixFd;
341 use crate::wire::{ObjectPath, SignatureWrapper};
342 let orig_fd = UnixFd::new(nix::unistd::dup(1).unwrap());
343 let orig = (
344 ObjectPath::new("/a/b/c").unwrap(),
345 SignatureWrapper::new("ss(aiau)").unwrap(),
346 &orig_fd,
347 );
348 orig.marshal(ctx).unwrap();
349 assert_eq!(
350 ctx.buf,
351 &[
352 6, 0, 0, 0, b'/', b'a', b'/', b'b', b'/', b'c', 0, 8, b's', b's', b'(', b'a', b'i',
353 b'a', b'u', b')', 0, 0, 0, 0, 0, 0, 0, 0
354 ]
355 );
356 let (_, (p, s, _fd)) =
357 <(ObjectPath<String>, SignatureWrapper<&str>, UnixFd) as Unmarshal>::unmarshal(
358 &mut UnmarshalContext {
359 buf: ctx.buf,
360 fds: ctx.fds,
361 byteorder: ctx.byteorder,
362 offset: 0,
363 },
364 )
365 .unwrap();
366
367 assert_eq!(p.as_ref(), "/a/b/c");
368 assert_eq!(s.as_ref(), "ss(aiau)");
369 }
370
371 #[test]
372 fn test_variant() {
373 use crate::message_builder::MarshalledMessageBody;
374 use crate::params::{Array, Base, Container, Dict, Param, Variant as ParamVariant};
375 use crate::signature::Type;
376 use crate::wire::SignatureWrapper;
377 use std::collections::HashMap;
378
379 let params: [(Param, Type); 10] = [
381 (Base::Byte(0x41).into(), u8::signature()),
382 (Base::Int16(-1234).into(), i16::signature()),
383 (Base::Uint16(1234).into(), u16::signature()),
384 (Base::Int32(-1234567).into(), i32::signature()),
385 (Base::Uint32(1234567).into(), u32::signature()),
386 (Base::Int64(-1234568901234).into(), i64::signature()),
387 (Base::Uint64(1234568901234).into(), u64::signature()),
388 (
389 Base::String("Hello world!".to_string()).into(),
390 String::signature(),
391 ),
392 (
393 Base::Signature("sy".to_string()).into(),
394 SignatureWrapper::<String>::signature(),
395 ),
396 (Base::Boolean(true).into(), bool::signature()),
397 ];
398
399 let mut body = MarshalledMessageBody::new();
401 for param in ¶ms {
402 let cont = Container::Variant(Box::new(ParamVariant {
403 sig: param.1.clone(),
404 value: param.0.clone(),
405 }));
406 body.push_old_param(&Param::Container(cont)).unwrap();
407 }
408
409 let var_vec = params
411 .iter()
412 .map(|(param, typ)| {
413 Param::Container(Container::Variant(Box::new(ParamVariant {
414 sig: typ.clone(),
415 value: param.clone(),
416 })))
417 })
418 .collect();
419 let vec_param = Param::Container(Container::Array(Array {
420 element_sig: Variant::signature(),
421 values: var_vec,
422 }));
423 body.push_old_param(&vec_param).unwrap();
424
425 let var_map = params
427 .iter()
428 .enumerate()
429 .map(|(i, (param, typ))| {
430 (
431 Base::String(format!("{}", i)),
432 Param::Container(Container::Variant(Box::new(ParamVariant {
433 sig: typ.clone(),
434 value: param.clone(),
435 }))),
436 )
437 })
438 .collect();
439 let map_param = Param::Container(Container::Dict(Dict {
440 key_sig: crate::signature::Base::String,
441 value_sig: Variant::signature(),
442 map: var_map,
443 }));
444 body.push_old_param(&map_param).unwrap();
445
446 let mut parser = body.parser();
448 assert_eq!(
449 0x41_u8,
450 parser.get::<Variant>().unwrap().get::<u8>().unwrap()
451 );
452 assert_eq!(
453 -1234_i16,
454 parser.get::<Variant>().unwrap().get::<i16>().unwrap()
455 );
456 assert_eq!(
457 1234_u16,
458 parser.get::<Variant>().unwrap().get::<u16>().unwrap()
459 );
460 assert_eq!(
461 -1234567_i32,
462 parser.get::<Variant>().unwrap().get::<i32>().unwrap()
463 );
464 assert_eq!(
465 1234567_u32,
466 parser.get::<Variant>().unwrap().get::<u32>().unwrap()
467 );
468 assert_eq!(
469 -1234568901234_i64,
470 parser.get::<Variant>().unwrap().get::<i64>().unwrap()
471 );
472 assert_eq!(
473 1234568901234_u64,
474 parser.get::<Variant>().unwrap().get::<u64>().unwrap()
475 );
476 assert_eq!(
477 "Hello world!",
478 parser.get::<Variant>().unwrap().get::<&str>().unwrap()
479 );
480 assert_eq!(
481 SignatureWrapper::new("sy").unwrap(),
482 parser.get::<Variant>().unwrap().get().unwrap()
483 );
484 assert_eq!(
485 true,
486 parser.get::<Variant>().unwrap().get::<bool>().unwrap()
487 );
488
489 let var_vec: Vec<Variant> = parser.get().unwrap();
491 assert_eq!(0x41_u8, var_vec[0].get::<u8>().unwrap());
492 assert_eq!(-1234_i16, var_vec[1].get::<i16>().unwrap());
493 assert_eq!(1234_u16, var_vec[2].get::<u16>().unwrap());
494 assert_eq!(-1234567_i32, var_vec[3].get::<i32>().unwrap());
495 assert_eq!(1234567_u32, var_vec[4].get::<u32>().unwrap());
496 assert_eq!(-1234568901234_i64, var_vec[5].get::<i64>().unwrap());
497 assert_eq!(1234568901234_u64, var_vec[6].get::<u64>().unwrap());
498 assert_eq!("Hello world!", var_vec[7].get::<&str>().unwrap());
499 assert_eq!(
500 SignatureWrapper::new("sy").unwrap(),
501 var_vec[8].get().unwrap()
502 );
503 assert_eq!(true, var_vec[9].get::<bool>().unwrap());
504
505 let var_map: HashMap<String, Variant> = parser.get().unwrap();
507 assert_eq!(0x41_u8, var_map["0"].get::<u8>().unwrap());
508 assert_eq!(-1234_i16, var_map["1"].get::<i16>().unwrap());
509 assert_eq!(1234_u16, var_map["2"].get::<u16>().unwrap());
510 assert_eq!(-1234567_i32, var_map["3"].get::<i32>().unwrap());
511 assert_eq!(1234567_u32, var_map["4"].get::<u32>().unwrap());
512 assert_eq!(-1234568901234_i64, var_map["5"].get::<i64>().unwrap());
513 assert_eq!(1234568901234_u64, var_map["6"].get::<u64>().unwrap());
514 assert_eq!("Hello world!", var_map["7"].get::<&str>().unwrap());
515 assert_eq!(
516 SignatureWrapper::new("sy").unwrap(),
517 var_map["8"].get().unwrap()
518 );
519 assert_eq!(true, var_map["9"].get::<bool>().unwrap());
520 }
521}