Skip to main content

xmpp_parsers/
carbons.rs

1// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use xso::{AsXml, FromXml};
8
9use crate::forwarding::Forwarded;
10use crate::iq::IqSetPayload;
11use crate::message::MessagePayload;
12use crate::ns;
13
14/// Enable carbons for this session.
15#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
16#[xml(namespace = ns::CARBONS, name = "enable")]
17pub struct Enable;
18
19impl IqSetPayload for Enable {}
20
21/// Disable a previously-enabled carbons.
22#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
23#[xml(namespace = ns::CARBONS, name = "disable")]
24pub struct Disable;
25
26impl IqSetPayload for Disable {}
27
28/// Request the enclosing message to not be copied to other carbons-enabled
29/// resources of the user.
30#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
31#[xml(namespace = ns::CARBONS, name = "private")]
32pub struct Private;
33
34impl MessagePayload for Private {}
35
36/// Wrapper for a message received on another resource.
37#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
38#[xml(namespace = ns::CARBONS, name = "received")]
39pub struct Received {
40    /// Wrapper for the enclosed message.
41    #[xml(child)]
42    pub forwarded: Forwarded,
43}
44
45impl MessagePayload for Received {}
46
47/// Wrapper for a message sent from another resource.
48#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
49#[xml(namespace = ns::CARBONS, name = "sent")]
50pub struct Sent {
51    /// Wrapper for the enclosed message.
52    #[xml(child)]
53    pub forwarded: Forwarded,
54}
55
56impl MessagePayload for Sent {}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61    #[cfg(not(feature = "component"))]
62    use jid::Jid;
63    use minidom::Element;
64
65    #[cfg(target_pointer_width = "32")]
66    #[test]
67    fn test_size() {
68        assert_size!(Enable, 0);
69        assert_size!(Disable, 0);
70        assert_size!(Private, 0);
71        assert_size!(Received, 152);
72        assert_size!(Sent, 152);
73    }
74
75    #[cfg(target_pointer_width = "64")]
76    #[test]
77    fn test_size() {
78        assert_size!(Enable, 0);
79        assert_size!(Disable, 0);
80        assert_size!(Private, 0);
81        assert_size!(Received, 288);
82        assert_size!(Sent, 288);
83    }
84
85    #[test]
86    fn empty_elements() {
87        let elem: Element = "<enable xmlns='urn:xmpp:carbons:2'/>".parse().unwrap();
88        Enable::try_from(elem).unwrap();
89
90        let elem: Element = "<disable xmlns='urn:xmpp:carbons:2'/>".parse().unwrap();
91        Disable::try_from(elem).unwrap();
92
93        let elem: Element = "<private xmlns='urn:xmpp:carbons:2'/>".parse().unwrap();
94        Private::try_from(elem).unwrap();
95    }
96
97    #[test]
98    #[cfg(not(feature = "component"))] // feature = "component" changes <message/> namespace
99    fn forwarded_elements() {
100        let elem: Element = "<received xmlns='urn:xmpp:carbons:2'>
101  <forwarded xmlns='urn:xmpp:forward:0'>
102    <message xmlns='jabber:client'
103             to='juliet@capulet.example/balcony'
104             from='romeo@montague.example/home'/>
105  </forwarded>
106</received>"
107            .parse()
108            .unwrap();
109        let received = Received::try_from(elem).unwrap();
110        assert_eq!(
111            received.forwarded.message.to.unwrap(),
112            Jid::new("juliet@capulet.example/balcony").unwrap()
113        );
114        assert_eq!(
115            received.forwarded.message.from.unwrap(),
116            Jid::new("romeo@montague.example/home").unwrap()
117        );
118
119        let elem: Element = "<sent xmlns='urn:xmpp:carbons:2'>
120  <forwarded xmlns='urn:xmpp:forward:0'>
121    <message xmlns='jabber:client'
122             to='juliet@capulet.example/balcony'
123             from='romeo@montague.example/home'/>
124  </forwarded>
125</sent>"
126            .parse()
127            .unwrap();
128        let sent = Sent::try_from(elem).unwrap();
129        assert_eq!(
130            sent.forwarded.message.to.unwrap(),
131            Jid::new("juliet@capulet.example/balcony").unwrap()
132        );
133        assert_eq!(
134            sent.forwarded.message.from.unwrap(),
135            Jid::new("romeo@montague.example/home").unwrap()
136        );
137    }
138
139    #[test]
140    #[cfg(not(feature = "component"))] // feature = "component" changes <message/> namespace
141    fn test_serialize_received() {
142        let reference: Element = "<received xmlns='urn:xmpp:carbons:2'><forwarded xmlns='urn:xmpp:forward:0'><message xmlns='jabber:client' to='juliet@capulet.example/balcony' from='romeo@montague.example/home'/></forwarded></received>"
143        .parse()
144        .unwrap();
145
146        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'><message xmlns='jabber:client' to='juliet@capulet.example/balcony' from='romeo@montague.example/home'/></forwarded>"
147          .parse()
148          .unwrap();
149        let forwarded = Forwarded::try_from(elem).unwrap();
150
151        let received = Received {
152            forwarded: forwarded,
153        };
154
155        let serialized: Element = received.into();
156        assert_eq!(serialized, reference);
157    }
158
159    #[test]
160    #[cfg(not(feature = "component"))] // feature = "component" changes <message/> namespace
161    fn test_serialize_sent() {
162        let reference: Element = "<sent xmlns='urn:xmpp:carbons:2'><forwarded xmlns='urn:xmpp:forward:0'><message xmlns='jabber:client' to='juliet@capulet.example/balcony' from='romeo@montague.example/home'/></forwarded></sent>"
163        .parse()
164        .unwrap();
165
166        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'><message xmlns='jabber:client' to='juliet@capulet.example/balcony' from='romeo@montague.example/home'/></forwarded>"
167          .parse()
168          .unwrap();
169        let forwarded = Forwarded::try_from(elem).unwrap();
170
171        let sent = Sent {
172            forwarded: forwarded,
173        };
174
175        let serialized: Element = sent.into();
176        assert_eq!(serialized, reference);
177    }
178}