1use crate::params::message;
3use crate::signature::SignatureIter;
4use crate::wire::errors::MarshalError;
5use crate::wire::errors::UnmarshalError;
6use crate::wire::marshal::traits::{Marshal, SignatureBuffer};
7use crate::wire::marshal::MarshalContext;
8use crate::wire::unmarshal::UnmarshalContext;
9use crate::wire::validate_raw;
10use crate::wire::UnixFd;
11use crate::ByteOrder;
12
13#[derive(Copy, Clone, Debug, PartialEq, Eq)]
15pub enum MessageType {
16 Signal,
17 Error,
18 Call,
19 Reply,
20 Invalid,
21}
22
23#[derive(Copy, Clone, PartialEq, Eq)]
25pub enum HeaderFlags {
26 NoReplyExpected,
27 NoAutoStart,
28 AllowInteractiveAuthorization,
29}
30
31impl HeaderFlags {
32 pub fn into_raw(self) -> u8 {
33 match self {
34 HeaderFlags::NoReplyExpected => 1,
35 HeaderFlags::NoAutoStart => 2,
36 HeaderFlags::AllowInteractiveAuthorization => 4,
37 }
38 }
39
40 pub fn is_set(self, flags: u8) -> bool {
41 flags & self.into_raw() == 1
42 }
43
44 pub fn set(self, flags: &mut u8) {
45 *flags |= self.into_raw()
46 }
47
48 pub fn unset(self, flags: &mut u8) {
49 *flags &= 0xFF - self.into_raw()
50 }
51 pub fn toggle(self, flags: &mut u8) {
52 if self.is_set(*flags) {
53 self.unset(flags)
54 } else {
55 self.set(flags)
56 }
57 }
58}
59
60#[derive(Debug, Clone, Default)]
62pub struct DynamicHeader {
63 pub interface: Option<String>,
64 pub member: Option<String>,
65 pub object: Option<String>,
66 pub destination: Option<String>,
67 pub serial: Option<u32>,
68 pub sender: Option<String>,
69 pub signature: Option<String>,
70 pub error_name: Option<String>,
71 pub response_serial: Option<u32>,
72 pub num_fds: Option<u32>,
73}
74
75impl DynamicHeader {
76 pub fn make_error_response<S: Into<String>>(
78 &self,
79 error_name: S,
80 error_msg: Option<String>,
81 ) -> crate::message_builder::MarshalledMessage {
82 let mut err_resp = crate::message_builder::MarshalledMessage {
83 typ: MessageType::Reply,
84 dynheader: DynamicHeader {
85 interface: None,
86 member: None,
87 object: None,
88 destination: self.sender.clone(),
89 serial: None,
90 num_fds: None,
91 sender: None,
92 signature: None,
93 response_serial: self.serial,
94 error_name: Some(error_name.into()),
95 },
96 flags: 0,
97 body: crate::message_builder::MarshalledMessageBody::new(),
98 };
99 if let Some(text) = error_msg {
100 err_resp.body.push_param(text).unwrap();
101 }
102 err_resp
103 }
104 pub fn make_response(&self) -> crate::message_builder::MarshalledMessage {
106 crate::message_builder::MarshalledMessage {
107 typ: MessageType::Reply,
108 dynheader: DynamicHeader {
109 interface: None,
110 member: None,
111 object: None,
112 destination: self.sender.clone(),
113 serial: None,
114 num_fds: None,
115 sender: None,
116 signature: None,
117 response_serial: self.serial,
118 error_name: None,
119 },
120 flags: 0,
121 body: crate::message_builder::MarshalledMessageBody::new(),
122 }
123 }
124}
125
126#[derive(Default)]
128pub struct MessageBuilder {
129 msg: MarshalledMessage,
130}
131
132pub struct CallBuilder {
134 msg: MarshalledMessage,
135}
136
137pub struct SignalBuilder {
139 msg: MarshalledMessage,
140}
141
142impl MessageBuilder {
143 pub fn new() -> MessageBuilder {
145 MessageBuilder {
146 msg: MarshalledMessage::new(),
147 }
148 }
149
150 pub fn with_byteorder(b: ByteOrder) -> MessageBuilder {
152 MessageBuilder {
153 msg: MarshalledMessage::with_byteorder(b),
154 }
155 }
156
157 pub fn call<S: Into<String>>(mut self, member: S) -> CallBuilder {
158 self.msg.typ = MessageType::Call;
159 self.msg.dynheader.member = Some(member.into());
160 CallBuilder { msg: self.msg }
161 }
162 pub fn signal<S1, S2, S3>(mut self, interface: S1, member: S2, object: S3) -> SignalBuilder
163 where
164 S1: Into<String>,
165 S2: Into<String>,
166 S3: Into<String>,
167 {
168 self.msg.typ = MessageType::Signal;
169 self.msg.dynheader.member = Some(member.into());
170 self.msg.dynheader.interface = Some(interface.into());
171 self.msg.dynheader.object = Some(object.into());
172 SignalBuilder { msg: self.msg }
173 }
174}
175
176impl CallBuilder {
177 pub fn on<S: Into<String>>(mut self, object_path: S) -> Self {
178 self.msg.dynheader.object = Some(object_path.into());
179 self
180 }
181
182 pub fn with_interface<S: Into<String>>(mut self, interface: S) -> Self {
183 self.msg.dynheader.interface = Some(interface.into());
184 self
185 }
186
187 pub fn at<S: Into<String>>(mut self, destination: S) -> Self {
188 self.msg.dynheader.destination = Some(destination.into());
189 self
190 }
191
192 pub fn build(self) -> MarshalledMessage {
193 self.msg
194 }
195}
196
197impl SignalBuilder {
198 pub fn to<S: Into<String>>(mut self, destination: S) -> Self {
199 self.msg.dynheader.destination = Some(destination.into());
200 self
201 }
202
203 pub fn build(self) -> MarshalledMessage {
204 self.msg
205 }
206}
207
208#[derive(Debug)]
215pub struct MarshalledMessage {
216 pub body: MarshalledMessageBody,
217
218 pub dynheader: DynamicHeader,
219
220 pub typ: MessageType,
221 pub flags: u8,
222}
223
224impl Default for MarshalledMessage {
225 fn default() -> Self {
226 Self::new()
227 }
228}
229
230impl MarshalledMessage {
231 pub fn get_buf(&self) -> &[u8] {
232 &self.body.buf
233 }
234 pub fn get_sig(&self) -> &str {
235 &self.body.sig
236 }
237
238 pub fn new() -> Self {
240 MarshalledMessage {
241 typ: MessageType::Invalid,
242 dynheader: DynamicHeader::default(),
243
244 flags: 0,
245 body: MarshalledMessageBody::new(),
246 }
247 }
248
249 pub fn with_byteorder(b: ByteOrder) -> Self {
251 MarshalledMessage {
252 typ: MessageType::Invalid,
253 dynheader: DynamicHeader::default(),
254
255 flags: 0,
256 body: MarshalledMessageBody::with_byteorder(b),
257 }
258 }
259
260 pub fn reserve(&mut self, additional: usize) {
263 self.body.reserve(additional)
264 }
265
266 pub fn unmarshall_all<'a, 'e>(self) -> Result<message::Message<'a, 'e>, UnmarshalError> {
267 let params = if self.body.sig.is_empty() {
268 vec![]
269 } else {
270 let sigs: Vec<_> = crate::signature::Type::parse_description(&self.body.sig)?;
271
272 let (_, params) = crate::wire::unmarshal::unmarshal_body(
273 self.body.byteorder,
274 &sigs,
275 &self.body.buf,
276 &self.body.raw_fds,
277 0,
278 )?;
279 params
280 };
281 Ok(message::Message {
282 dynheader: self.dynheader,
283 params,
284 typ: self.typ,
285 flags: self.flags,
286 raw_fds: self.body.raw_fds,
287 })
288 }
289}
290#[derive(Debug)]
293pub struct MarshalledMessageBody {
294 pub(crate) buf: Vec<u8>,
295
296 pub(crate) raw_fds: Vec<crate::wire::UnixFd>,
298
299 sig: SignatureBuffer,
300 pub(crate) byteorder: ByteOrder,
301}
302
303impl Default for MarshalledMessageBody {
304 fn default() -> Self {
305 Self::new()
306 }
307}
308
309pub fn marshal_as_variant<P: Marshal>(
312 p: P,
313 byteorder: ByteOrder,
314 buf: &mut Vec<u8>,
315 fds: &mut Vec<crate::wire::UnixFd>,
316) -> Result<(), MarshalError> {
317 let mut ctx = MarshalContext {
318 fds,
319 buf,
320 byteorder,
321 };
322 let ctx = &mut ctx;
323
324 let mut sig_str = SignatureBuffer::new();
326 P::sig_str(&mut sig_str);
327 let sig = crate::wire::SignatureWrapper::new(sig_str)?;
328 sig.marshal(ctx)?;
329
330 p.marshal(ctx)?;
332 Ok(())
333}
334
335impl MarshalledMessageBody {
336 pub fn new() -> Self {
338 MarshalledMessageBody {
339 buf: Vec::new(),
340 raw_fds: Vec::new(),
341 sig: SignatureBuffer::new(),
342 byteorder: ByteOrder::NATIVE,
343 }
344 }
345
346 pub fn with_byteorder(b: ByteOrder) -> Self {
348 MarshalledMessageBody {
349 buf: Vec::new(),
350 raw_fds: Vec::new(),
351 sig: SignatureBuffer::new(),
352 byteorder: b,
353 }
354 }
355
356 pub fn from_parts(
357 buf: Vec<u8>,
358 raw_fds: Vec<crate::wire::UnixFd>,
359 sig: String,
360 byteorder: ByteOrder,
361 ) -> Self {
362 let sig = SignatureBuffer::from_string(sig);
363 Self {
364 buf,
365 raw_fds,
366 sig,
367 byteorder,
368 }
369 }
370 pub fn get_fds(&self) -> Vec<UnixFd> {
374 self.raw_fds.clone()
375 }
376 pub fn reset(&mut self) {
380 self.sig.clear();
381 self.buf.clear();
382 }
383
384 pub fn reserve(&mut self, additional: usize) {
387 self.buf.reserve(additional)
388 }
389
390 pub fn push_old_param(&mut self, p: &crate::params::Param) -> Result<(), MarshalError> {
393 let mut ctx = MarshalContext {
394 buf: &mut self.buf,
395 fds: &mut self.raw_fds,
396 byteorder: self.byteorder,
397 };
398 let ctx = &mut ctx;
399 crate::wire::marshal::container::marshal_param(p, ctx)?;
400 p.sig().to_str(self.sig.to_string_mut());
401 Ok(())
402 }
403
404 pub fn push_old_params(&mut self, ps: &[crate::params::Param]) -> Result<(), MarshalError> {
406 for p in ps {
407 self.push_old_param(p)?;
408 }
409 Ok(())
410 }
411 fn create_ctx(&mut self) -> MarshalContext {
412 MarshalContext {
413 buf: &mut self.buf,
414 fds: &mut self.raw_fds,
415 byteorder: self.byteorder,
416 }
417 }
418
419 pub fn push_param<P: Marshal>(&mut self, p: P) -> Result<(), MarshalError> {
421 let mut ctx = self.create_ctx();
422 p.marshal(&mut ctx)?;
423 P::sig_str(&mut self.sig);
424 Ok(())
425 }
426
427 fn push_mult_helper<F>(&mut self, push_calls: F) -> Result<(), MarshalError>
430 where
431 F: FnOnce(&mut MarshalledMessageBody) -> Result<(), MarshalError>,
432 {
433 let sig_len = self.sig.len();
434 let buf_len = self.buf.len();
435 let fds_len = self.raw_fds.len();
436
437 match push_calls(self) {
438 Ok(ret) => Ok(ret),
439 Err(e) => {
440 self.sig.truncate(sig_len)?;
442 self.buf.truncate(buf_len);
443 self.raw_fds.truncate(fds_len);
444 Err(e)
445 }
446 }
447 }
448
449 pub fn push_param2<P1: Marshal, P2: Marshal>(
451 &mut self,
452 p1: P1,
453 p2: P2,
454 ) -> Result<(), MarshalError> {
455 self.push_mult_helper(move |msg: &mut Self| {
456 msg.push_param(p1)?;
457 msg.push_param(p2)
458 })
459 }
460
461 pub fn push_param3<P1: Marshal, P2: Marshal, P3: Marshal>(
463 &mut self,
464 p1: P1,
465 p2: P2,
466 p3: P3,
467 ) -> Result<(), MarshalError> {
468 self.push_mult_helper(move |msg: &mut Self| {
469 msg.push_param(p1)?;
470 msg.push_param(p2)?;
471 msg.push_param(p3)
472 })
473 }
474
475 pub fn push_param4<P1: Marshal, P2: Marshal, P3: Marshal, P4: Marshal>(
477 &mut self,
478 p1: P1,
479 p2: P2,
480 p3: P3,
481 p4: P4,
482 ) -> Result<(), MarshalError> {
483 self.push_mult_helper(move |msg: &mut Self| {
484 msg.push_param(p1)?;
485 msg.push_param(p2)?;
486 msg.push_param(p3)?;
487 msg.push_param(p4)
488 })
489 }
490
491 pub fn push_param5<P1: Marshal, P2: Marshal, P3: Marshal, P4: Marshal, P5: Marshal>(
493 &mut self,
494 p1: P1,
495 p2: P2,
496 p3: P3,
497 p4: P4,
498 p5: P5,
499 ) -> Result<(), MarshalError> {
500 self.push_mult_helper(move |msg: &mut Self| {
501 msg.push_param(p1)?;
502 msg.push_param(p2)?;
503 msg.push_param(p3)?;
504 msg.push_param(p4)?;
505 msg.push_param(p5)
506 })
507 }
508
509 pub fn push_params<P: Marshal>(&mut self, params: &[P]) -> Result<(), MarshalError> {
511 for p in params {
512 self.push_param(p)?;
513 }
514 Ok(())
515 }
516
517 pub fn push_variant<P: Marshal>(&mut self, p: P) -> Result<(), MarshalError> {
519 self.sig.push_static("v");
520 let mut ctx = self.create_ctx();
521 p.marshal_as_variant(&mut ctx)
522 }
523 pub fn validate(&self) -> Result<(), UnmarshalError> {
525 if self.sig.is_empty() && self.buf.is_empty() {
526 return Ok(());
527 }
528 let types = crate::signature::Type::parse_description(&self.sig)?;
529 let mut used = 0;
530 for typ in types {
531 used += validate_raw::validate_marshalled(self.byteorder, used, &self.buf, &typ)
532 .map_err(|(_, e)| e)?;
533 }
534 if used == self.buf.len() {
535 Ok(())
536 } else {
537 Err(UnmarshalError::NotAllBytesUsed)
538 }
539 }
540 #[inline]
542 pub fn parser(&self) -> MessageBodyParser {
543 MessageBodyParser::new(self)
544 }
545}
546
547#[test]
548fn test_marshal_trait() {
549 let mut body = MarshalledMessageBody::new();
550 let bytes: &[&[_]] = &[&[4u64]];
551 body.push_param(bytes).unwrap();
552
553 assert_eq!(
554 vec![12, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0],
555 body.buf
556 );
557 assert_eq!(body.sig.as_str(), "aat");
558
559 let mut body = MarshalledMessageBody::new();
560 let mut map = std::collections::HashMap::new();
561 map.insert("a", 4u32);
562
563 body.push_param(&map).unwrap();
564 assert_eq!(
565 vec![12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, b'a', 0, 0, 0, 4, 0, 0, 0,],
566 body.buf
567 );
568 assert_eq!(body.sig.as_str(), "a{su}");
569
570 let mut body = MarshalledMessageBody::new();
571 body.push_param((11u64, "str", true)).unwrap();
572 assert_eq!(body.sig.as_str(), "(tsb)");
573 assert_eq!(
574 vec![11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, b's', b't', b'r', 0, 1, 0, 0, 0,],
575 body.buf
576 );
577
578 struct MyStruct {
579 x: u64,
580 y: String,
581 }
582
583 use crate::wire::marshal::traits::Signature;
584 use crate::wire::marshal::MarshalContext;
585 impl Signature for &MyStruct {
586 fn signature() -> crate::signature::Type {
587 crate::signature::Type::Container(crate::signature::Container::Struct(
588 crate::signature::StructTypes::new(vec![u64::signature(), String::signature()])
589 .unwrap(),
590 ))
591 }
592
593 fn alignment() -> usize {
594 8
595 }
596 #[inline]
597 fn sig_str(s_buf: &mut crate::wire::marshal::traits::SignatureBuffer) {
598 s_buf.push_static("(ts)")
599 }
600 fn has_sig(sig: &str) -> bool {
601 sig == "(ts)"
602 }
603 }
604 impl Marshal for &MyStruct {
605 fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), MarshalError> {
606 ctx.align_to(8);
608 self.x.marshal(ctx)?;
609 self.y.marshal(ctx)?;
610 Ok(())
611 }
612 }
613
614 let mut body = MarshalledMessageBody::new();
615 body.push_param(&MyStruct {
616 x: 100,
617 y: "A".to_owned(),
618 })
619 .unwrap();
620 assert_eq!(body.sig.as_str(), "(ts)");
621 assert_eq!(
622 vec![100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, b'A', 0,],
623 body.buf
624 );
625
626 let mut body = MarshalledMessageBody::new();
627 let emptymap: std::collections::HashMap<&str, u32> = std::collections::HashMap::new();
628 let mut map = std::collections::HashMap::new();
629 let mut map2 = std::collections::HashMap::new();
630 map.insert("a", 4u32);
631 map2.insert("a", &map);
632
633 body.push_param(&map2).unwrap();
634 body.push_param(&emptymap).unwrap();
635 assert_eq!(body.sig.as_str(), "a{sa{su}}a{su}");
636 assert_eq!(
637 vec![
638 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, b'a', 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
639 0, b'a', 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0
640 ],
641 body.buf
642 );
643
644 let mut body_iter = MessageBodyParser::new(&body);
646
647 type WrongNestedDict =
649 std::collections::HashMap<String, std::collections::HashMap<String, u64>>;
650 assert_eq!(
651 body_iter.get::<WrongNestedDict>().err().unwrap(),
652 UnmarshalError::WrongSignature
653 );
654 type WrongStruct = (u64, i32, String);
655 assert_eq!(
656 body_iter.get::<WrongStruct>().err().unwrap(),
657 UnmarshalError::WrongSignature
658 );
659
660 type NestedDict = std::collections::HashMap<String, std::collections::HashMap<String, u32>>;
662 let newmap2: NestedDict = body_iter.get().unwrap();
663 assert_eq!(newmap2.len(), 1);
664 assert_eq!(newmap2.get("a").unwrap().len(), 1);
665 assert_eq!(*newmap2.get("a").unwrap().get("a").unwrap(), 4);
666
667 assert_eq!(
669 body_iter.get::<WrongNestedDict>().err().unwrap(),
670 UnmarshalError::WrongSignature
671 );
672 assert_eq!(
673 body_iter.get::<WrongStruct>().err().unwrap(),
674 UnmarshalError::WrongSignature
675 );
676
677 let newemptymap: std::collections::HashMap<&str, u32> = body_iter.get().unwrap();
679 assert_eq!(newemptymap.len(), 0);
680
681 let mut body_iter = body.parser();
683 assert_eq!(
684 body_iter.get2::<NestedDict, u16>().unwrap_err(),
685 UnmarshalError::WrongSignature
686 );
687 assert_eq!(
688 body_iter
689 .get3::<NestedDict, std::collections::HashMap<&str, u32>, u32>()
690 .unwrap_err(),
691 UnmarshalError::EndOfMessage
692 );
693
694 let (newmap2, newemptymap): (NestedDict, std::collections::HashMap<&str, u32>) =
697 body_iter.get2().unwrap();
698 assert_eq!(newmap2.len(), 1);
700 assert_eq!(newmap2.get("a").unwrap().len(), 1);
701 assert_eq!(*newmap2.get("a").unwrap().get("a").unwrap(), 4);
702 assert_eq!(newemptymap.len(), 0);
703 assert_eq!(
704 body_iter.get::<u16>().unwrap_err(),
705 UnmarshalError::EndOfMessage
706 );
707
708 let mut body_iter = body.parser();
710
711 let newmap2: NestedDict = body_iter.get().unwrap();
714 let newemptymap = body_iter.get_param().unwrap();
715 assert_eq!(newmap2.len(), 1);
717 assert_eq!(newmap2.get("a").unwrap().len(), 1);
718 assert_eq!(*newmap2.get("a").unwrap().get("a").unwrap(), 4);
719
720 use crate::params::Container;
721 use crate::params::Param;
722 match newemptymap {
723 Param::Container(Container::Dict(dict)) => {
724 assert_eq!(dict.map.len(), 0);
725 assert_eq!(dict.key_sig, crate::signature::Base::String);
726 assert_eq!(
727 dict.value_sig,
728 crate::signature::Type::Base(crate::signature::Base::Uint32)
729 );
730 }
731 _ => panic!("Expected to get a dict"),
732 }
733 assert_eq!(
734 body_iter.get::<u16>().unwrap_err(),
735 UnmarshalError::EndOfMessage
736 );
737}
738
739use crate::wire::unmarshal::traits::Unmarshal;
740#[derive(Debug)]
748pub struct MessageBodyParser<'body> {
749 buf_idx: usize,
750 sig_idx: usize,
751 body: &'body MarshalledMessageBody,
752}
753
754impl<'fds, 'body: 'fds> MessageBodyParser<'body> {
755 pub fn new(body: &'body MarshalledMessageBody) -> Self {
756 Self {
757 buf_idx: 0,
758 sig_idx: 0,
759 body,
760 }
761 }
762
763 #[inline(always)]
764 fn sig_iter(&self) -> SignatureIter<'body> {
765 SignatureIter::new_at_idx(self.body.sig.as_str(), self.sig_idx)
766 }
767
768 #[inline(always)]
770 pub fn get_next_sig(&self) -> Option<&'body str> {
771 self.sig_iter().next()
772 }
773
774 #[inline(always)]
775 pub fn sigs_left(&self) -> usize {
776 self.sig_iter().count()
777 }
778
779 pub fn get<T: Unmarshal<'body, 'fds>>(&mut self) -> Result<T, UnmarshalError> {
782 if let Some(expected_sig) = self.get_next_sig() {
783 if !T::has_sig(expected_sig) {
784 return Err(UnmarshalError::WrongSignature);
785 }
786
787 let mut ctx = UnmarshalContext {
788 byteorder: self.body.byteorder,
789 buf: &self.body.buf,
790 offset: self.buf_idx,
791 fds: &self.body.raw_fds,
792 };
793 match T::unmarshal(&mut ctx) {
794 Ok((bytes, res)) => {
795 self.buf_idx += bytes;
796 self.sig_idx += expected_sig.len();
797 Ok(res)
798 }
799 Err(e) => Err(e),
800 }
801 } else {
802 Err(UnmarshalError::EndOfMessage)
803 }
804 }
805 fn get_mult_helper<T, F>(&mut self, count: usize, get_calls: F) -> Result<T, UnmarshalError>
807 where
808 F: FnOnce(&mut Self) -> Result<T, UnmarshalError>,
809 {
810 if count > self.sigs_left() {
811 return Err(UnmarshalError::EndOfMessage);
812 }
813 let start_sig_idx = self.sig_idx;
814 let start_buf_idx = self.buf_idx;
815 match get_calls(self) {
816 Ok(ret) => Ok(ret),
817 Err(err) => {
818 self.sig_idx = start_sig_idx;
819 self.buf_idx = start_buf_idx;
820 Err(err)
821 }
822 }
823 }
824
825 pub fn get2<T1, T2>(&mut self) -> Result<(T1, T2), UnmarshalError>
828 where
829 T1: Unmarshal<'body, 'fds>,
830 T2: Unmarshal<'body, 'fds>,
831 {
832 let get_calls = |parser: &mut Self| {
833 let ret1 = parser.get()?;
834 let ret2 = parser.get()?;
835 Ok((ret1, ret2))
836 };
837 self.get_mult_helper(2, get_calls)
838 }
839
840 pub fn get3<T1, T2, T3>(&mut self) -> Result<(T1, T2, T3), UnmarshalError>
843 where
844 T1: Unmarshal<'body, 'fds>,
845 T2: Unmarshal<'body, 'fds>,
846 T3: Unmarshal<'body, 'fds>,
847 {
848 let get_calls = |parser: &mut Self| {
849 let ret1 = parser.get()?;
850 let ret2 = parser.get()?;
851 let ret3 = parser.get()?;
852 Ok((ret1, ret2, ret3))
853 };
854 self.get_mult_helper(3, get_calls)
855 }
856
857 pub fn get4<T1, T2, T3, T4>(&mut self) -> Result<(T1, T2, T3, T4), UnmarshalError>
860 where
861 T1: Unmarshal<'body, 'fds>,
862 T2: Unmarshal<'body, 'fds>,
863 T3: Unmarshal<'body, 'fds>,
864 T4: Unmarshal<'body, 'fds>,
865 {
866 let get_calls = |parser: &mut Self| {
867 let ret1 = parser.get()?;
868 let ret2 = parser.get()?;
869 let ret3 = parser.get()?;
870 let ret4 = parser.get()?;
871 Ok((ret1, ret2, ret3, ret4))
872 };
873 self.get_mult_helper(4, get_calls)
874 }
875
876 pub fn get5<T1, T2, T3, T4, T5>(&mut self) -> Result<(T1, T2, T3, T4, T5), UnmarshalError>
879 where
880 T1: Unmarshal<'body, 'fds>,
881 T2: Unmarshal<'body, 'fds>,
882 T3: Unmarshal<'body, 'fds>,
883 T4: Unmarshal<'body, 'fds>,
884 T5: Unmarshal<'body, 'fds>,
885 {
886 let get_calls = |parser: &mut Self| {
887 let ret1 = parser.get()?;
888 let ret2 = parser.get()?;
889 let ret3 = parser.get()?;
890 let ret4 = parser.get()?;
891 let ret5 = parser.get()?;
892 Ok((ret1, ret2, ret3, ret4, ret5))
893 };
894 self.get_mult_helper(5, get_calls)
895 }
896
897 pub fn get_param(&mut self) -> Result<crate::params::Param, UnmarshalError> {
900 if let Some(sig_str) = self.get_next_sig() {
901 let mut ctx = UnmarshalContext {
902 byteorder: self.body.byteorder,
903 buf: &self.body.buf,
904 offset: self.buf_idx,
905 fds: &self.body.raw_fds,
906 };
907
908 let sig = &crate::signature::Type::parse_description(sig_str).unwrap()[0];
909
910 match crate::wire::unmarshal::container::unmarshal_with_sig(sig, &mut ctx) {
911 Ok((bytes, res)) => {
912 self.buf_idx += bytes;
913 self.sig_idx += sig_str.len();
914 Ok(res)
915 }
916 Err(e) => Err(e),
917 }
918 } else {
919 Err(UnmarshalError::EndOfMessage)
920 }
921 }
922}
923
924#[cfg(test)]
925mod tests {
926 #[test]
927 fn parser_get() {
928 use crate::wire::errors::UnmarshalError;
929
930 let mut sig = super::MessageBuilder::new()
931 .signal("io.killingspark", "Signal", "/io/killingspark/Signaler")
932 .build();
933
934 sig.body.push_param3(100u32, 200i32, "ABCDEFGH").unwrap();
935
936 let mut parser = sig.body.parser();
937 assert_eq!(parser.get(), Ok(100u32));
938 assert_eq!(parser.get(), Ok(200i32));
939 assert_eq!(parser.get(), Ok("ABCDEFGH"));
940 assert_eq!(parser.get::<String>(), Err(UnmarshalError::EndOfMessage));
941
942 let mut parser = sig.body.parser();
943 assert_eq!(parser.get2(), Ok((100u32, 200i32)));
944 assert_eq!(parser.get(), Ok("ABCDEFGH"));
945 assert_eq!(parser.get::<String>(), Err(UnmarshalError::EndOfMessage));
946
947 let mut parser = sig.body.parser();
948 assert_eq!(parser.get3(), Ok((100u32, 200i32, "ABCDEFGH")));
949 assert_eq!(parser.get::<String>(), Err(UnmarshalError::EndOfMessage));
950
951 let mut sig = super::MessageBuilder::new()
952 .signal("io.killingspark", "Signal", "/io/killingspark/Signaler")
953 .build();
954
955 sig.body.push_param((100u32, 200i32, "ABCDEFGH")).unwrap();
956 sig.body.push_param((100u32, 200i32, "ABCDEFGH")).unwrap();
957 sig.body.push_param((100u32, 200i32, "ABCDEFGH")).unwrap();
958
959 let mut parser = sig.body.parser();
960 assert!(parser.get::<(u32, i32, &str)>().is_ok());
961 assert!(parser.get2::<(u32, i32, &str), (u32, i32, &str)>().is_ok());
962 }
963}