1use xso::{AsXml, FromXml};
8
9use crate::ns;
10use crate::pubsub::PubSubPayload;
11
12generate_elem_id!(
13 Artist,
15 "artist",
16 TUNE
17);
18
19generate_elem_id!(
20 Length,
22 "length",
23 TUNE,
24 u16
25);
26
27generate_elem_id!(
28 Rating,
30 "rating",
31 TUNE,
32 u8
33);
34
35generate_elem_id!(
36 Source,
39 "source",
40 TUNE
41);
42
43generate_elem_id!(
44 Title,
46 "title",
47 TUNE
48);
49
50generate_elem_id!(
51 Track,
54 "track",
55 TUNE
56);
57
58generate_elem_id!(
59 Uri,
61 "uri",
62 TUNE
63);
64
65#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
67#[xml(namespace = ns::TUNE, name = "tune")]
68pub struct Tune {
69 #[xml(child(default))]
71 artist: Option<Artist>,
72
73 #[xml(child(default))]
75 length: Option<Length>,
76
77 #[xml(child(default))]
79 rating: Option<Rating>,
80
81 #[xml(child(default))]
84 source: Option<Source>,
85
86 #[xml(child(default))]
88 title: Option<Title>,
89
90 #[xml(child(default))]
93 track: Option<Track>,
94
95 #[xml(child(default))]
97 uri: Option<Uri>,
98}
99
100impl PubSubPayload for Tune {}
101
102impl Tune {
103 pub fn new() -> Tune {
105 Tune {
106 artist: None,
107 length: None,
108 rating: None,
109 source: None,
110 title: None,
111 track: None,
112 uri: None,
113 }
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120 use core::str::FromStr;
121 use minidom::Element;
122
123 #[cfg(target_pointer_width = "32")]
124 #[test]
125 fn test_size() {
126 assert_size!(Tune, 68);
127 assert_size!(Artist, 12);
128 assert_size!(Length, 2);
129 assert_size!(Rating, 1);
130 assert_size!(Source, 12);
131 assert_size!(Title, 12);
132 assert_size!(Track, 12);
133 assert_size!(Uri, 12);
134 }
135
136 #[cfg(target_pointer_width = "64")]
137 #[test]
138 fn test_size() {
139 assert_size!(Tune, 128);
140 assert_size!(Artist, 24);
141 assert_size!(Length, 2);
142 assert_size!(Rating, 1);
143 assert_size!(Source, 24);
144 assert_size!(Title, 24);
145 assert_size!(Track, 24);
146 assert_size!(Uri, 24);
147 }
148
149 #[test]
150 fn empty() {
151 let elem: Element = "<tune xmlns='http://jabber.org/protocol/tune'/>"
152 .parse()
153 .unwrap();
154 let elem2 = elem.clone();
155 let tune = Tune::try_from(elem).unwrap();
156 assert!(tune.artist.is_none());
157 assert!(tune.length.is_none());
158 assert!(tune.rating.is_none());
159 assert!(tune.source.is_none());
160 assert!(tune.title.is_none());
161 assert!(tune.track.is_none());
162 assert!(tune.uri.is_none());
163
164 let elem3 = tune.into();
165 assert_eq!(elem2, elem3);
166 }
167
168 #[test]
169 fn full() {
170 let elem: Element = "<tune xmlns='http://jabber.org/protocol/tune'><artist>Yes</artist><length>686</length><rating>8</rating><source>Yessongs</source><title>Heart of the Sunrise</title><track>3</track><uri>http://www.yesworld.com/lyrics/Fragile.html#9</uri></tune>"
171 .parse()
172 .unwrap();
173 let tune = Tune::try_from(elem).unwrap();
174 assert_eq!(tune.artist, Some(Artist::from_str("Yes").unwrap()));
175 assert_eq!(tune.length, Some(Length(686)));
176 assert_eq!(tune.rating, Some(Rating(8)));
177 assert_eq!(tune.source, Some(Source::from_str("Yessongs").unwrap()));
178 assert_eq!(
179 tune.title,
180 Some(Title::from_str("Heart of the Sunrise").unwrap())
181 );
182 assert_eq!(tune.track, Some(Track::from_str("3").unwrap()));
183 assert_eq!(
184 tune.uri,
185 Some(Uri::from_str("http://www.yesworld.com/lyrics/Fragile.html#9").unwrap())
186 );
187 }
188}