Skip to main content

xmpp_parsers/
displayed_markers.rs

1// Copyright (c) 2026 Paul Fariello <paul@fariello.eu>
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::message::{Id, MessagePayload};
10use crate::ns;
11
12/// Request to know if the recipient has displayed a message.
13#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
14#[xml(namespace = ns::DISPLAYED_MARKERS, name = "markable")]
15pub struct Markable;
16
17impl MessagePayload for Markable {}
18
19/// Inform that all messages up to a given message have been displayed.
20#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
21#[xml(namespace = ns::DISPLAYED_MARKERS, name = "displayed")]
22pub struct Displayed {
23    /// The 'id' attribute of the displayed message.
24    #[xml(attribute)]
25    pub id: Id,
26}
27
28impl MessagePayload for Displayed {}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33    use crate::ns;
34    use minidom::Element;
35    use xso::error::{Error, FromElementError};
36    use xso::exports::rxml;
37
38    #[cfg(target_pointer_width = "32")]
39    #[test]
40    fn test_size() {
41        assert_size!(Markable, 0);
42        assert_size!(Displayed, 12);
43    }
44
45    #[cfg(target_pointer_width = "64")]
46    #[test]
47    fn test_size() {
48        assert_size!(Markable, 0);
49        assert_size!(Displayed, 24);
50    }
51
52    #[test]
53    fn test_simple() {
54        let elem: Element = "<markable xmlns='urn:xmpp:chat-markers:0'/>"
55            .parse()
56            .unwrap();
57        Markable::try_from(elem).unwrap();
58
59        let elem: Element = "<displayed xmlns='urn:xmpp:chat-markers:0' id='39K7ZYIp'/>"
60            .parse()
61            .unwrap();
62        let displayed = Displayed::try_from(elem).unwrap();
63        assert_eq!(displayed.id, Id(String::from("39K7ZYIp")));
64    }
65
66    #[test]
67    fn test_missing_id() {
68        let elem: Element = "<displayed xmlns='urn:xmpp:chat-markers:0'/>"
69            .parse()
70            .unwrap();
71        let error = Displayed::try_from(elem).unwrap_err();
72        let message = match error {
73            FromElementError::Invalid(Error::Other(string)) => string,
74            _ => panic!(),
75        };
76        assert_eq!(
77            message,
78            "Required attribute field 'id' on Displayed element missing."
79        );
80    }
81
82    #[test]
83    fn test_serialise() {
84        let receipt = Markable;
85        let elem: Element = receipt.into();
86        assert!(elem.is("markable", ns::DISPLAYED_MARKERS));
87        assert_eq!(elem.attrs().into_iter().count(), 0);
88
89        let receipt = Displayed {
90            id: Id(String::from("39K7ZYIp")),
91        };
92        let elem: Element = receipt.into();
93        assert!(elem.is("displayed", ns::DISPLAYED_MARKERS));
94        assert_eq!(elem.attr(rxml::xml_ncname!("id")), Some("39K7ZYIp"));
95    }
96}