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
117impl Default for Tune {
118 fn default() -> Self {
119 Self::new()
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126 use core::str::FromStr;
127 use minidom::Element;
128
129 #[cfg(target_pointer_width = "32")]
130 #[test]
131 fn test_size() {
132 assert_size!(Tune, 68);
133 assert_size!(Artist, 12);
134 assert_size!(Length, 2);
135 assert_size!(Rating, 1);
136 assert_size!(Source, 12);
137 assert_size!(Title, 12);
138 assert_size!(Track, 12);
139 assert_size!(Uri, 12);
140 }
141
142 #[cfg(target_pointer_width = "64")]
143 #[test]
144 fn test_size() {
145 assert_size!(Tune, 128);
146 assert_size!(Artist, 24);
147 assert_size!(Length, 2);
148 assert_size!(Rating, 1);
149 assert_size!(Source, 24);
150 assert_size!(Title, 24);
151 assert_size!(Track, 24);
152 assert_size!(Uri, 24);
153 }
154
155 #[test]
156 fn empty() {
157 let elem: Element = "<tune xmlns='http://jabber.org/protocol/tune'/>"
158 .parse()
159 .unwrap();
160 let elem2 = elem.clone();
161 let tune = Tune::try_from(elem).unwrap();
162 assert!(tune.artist.is_none());
163 assert!(tune.length.is_none());
164 assert!(tune.rating.is_none());
165 assert!(tune.source.is_none());
166 assert!(tune.title.is_none());
167 assert!(tune.track.is_none());
168 assert!(tune.uri.is_none());
169
170 let elem3 = tune.into();
171 assert_eq!(elem2, elem3);
172 }
173
174 #[test]
175 fn full() {
176 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>"
177 .parse()
178 .unwrap();
179 let tune = Tune::try_from(elem).unwrap();
180 assert_eq!(tune.artist, Some(Artist::from_str("Yes").unwrap()));
181 assert_eq!(tune.length, Some(Length(686)));
182 assert_eq!(tune.rating, Some(Rating(8)));
183 assert_eq!(tune.source, Some(Source::from_str("Yessongs").unwrap()));
184 assert_eq!(
185 tune.title,
186 Some(Title::from_str("Heart of the Sunrise").unwrap())
187 );
188 assert_eq!(tune.track, Some(Track::from_str("3").unwrap()));
189 assert_eq!(
190 tune.uri,
191 Some(Uri::from_str("http://www.yesworld.com/lyrics/Fragile.html#9").unwrap())
192 );
193 }
194}