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/.
67use xso::{AsXml, FromXml};
89use crate::ns;
10use crate::pubsub::PubSubPayload;
1112generate_elem_id!(
13/// The artist or performer of the song or piece.
14Artist,
15"artist",
16 TUNE
17);
1819generate_elem_id!(
20/// The duration of the song or piece in seconds.
21Length,
22"length",
23 TUNE,
24 u16
25);
2627generate_elem_id!(
28/// The user's rating of the song or piece, from 1 (lowest) to 10 (highest).
29Rating,
30"rating",
31 TUNE,
32 u8
33);
3435generate_elem_id!(
36/// The collection (e.g., album) or other source (e.g., a band website that hosts streams or
37 /// audio files).
38Source,
39"source",
40 TUNE
41);
4243generate_elem_id!(
44/// The title of the song or piece.
45Title,
46"title",
47 TUNE
48);
4950generate_elem_id!(
51/// A unique identifier for the tune; e.g., the track number within a collection or the
52 /// specific URI for the object (e.g., a stream or audio file).
53Track,
54"track",
55 TUNE
56);
5758generate_elem_id!(
59/// A URI or URL pointing to information about the song, collection, or artist.
60Uri,
61"uri",
62 TUNE
63);
6465/// Container for formatted text.
66#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
67#[xml(namespace = ns::TUNE, name = "tune")]
68pub struct Tune {
69/// The artist or performer of the song or piece.
70#[xml(child(default))]
71artist: Option<Artist>,
7273/// The duration of the song or piece in seconds.
74#[xml(child(default))]
75length: Option<Length>,
7677/// The user's rating of the song or piece, from 1 (lowest) to 10 (highest).
78#[xml(child(default))]
79rating: Option<Rating>,
8081/// The collection (e.g., album) or other source (e.g., a band website that hosts streams or
82 /// audio files).
83#[xml(child(default))]
84source: Option<Source>,
8586/// The title of the song or piece.
87#[xml(child(default))]
88title: Option<Title>,
8990/// A unique identifier for the tune; e.g., the track number within a collection or the
91 /// specific URI for the object (e.g., a stream or audio file).
92#[xml(child(default))]
93track: Option<Track>,
9495/// A URI or URL pointing to information about the song, collection, or artist.
96#[xml(child(default))]
97uri: Option<Uri>,
98}
99100impl PubSubPayload for Tune {}
101102impl Tune {
103/// Construct an empty `<tune/>` element.
104pub 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}
116117#[cfg(test)]
118mod tests {
119use super::*;
120use core::str::FromStr;
121use minidom::Element;
122123#[cfg(target_pointer_width = "32")]
124 #[test]
125fn test_size() {
126assert_size!(Tune, 68);
127assert_size!(Artist, 12);
128assert_size!(Length, 2);
129assert_size!(Rating, 1);
130assert_size!(Source, 12);
131assert_size!(Title, 12);
132assert_size!(Track, 12);
133assert_size!(Uri, 12);
134 }
135136#[cfg(target_pointer_width = "64")]
137 #[test]
138fn test_size() {
139assert_size!(Tune, 128);
140assert_size!(Artist, 24);
141assert_size!(Length, 2);
142assert_size!(Rating, 1);
143assert_size!(Source, 24);
144assert_size!(Title, 24);
145assert_size!(Track, 24);
146assert_size!(Uri, 24);
147 }
148149#[test]
150fn empty() {
151let elem: Element = "<tune xmlns='http://jabber.org/protocol/tune'/>"
152.parse()
153 .unwrap();
154let elem2 = elem.clone();
155let tune = Tune::try_from(elem).unwrap();
156assert!(tune.artist.is_none());
157assert!(tune.length.is_none());
158assert!(tune.rating.is_none());
159assert!(tune.source.is_none());
160assert!(tune.title.is_none());
161assert!(tune.track.is_none());
162assert!(tune.uri.is_none());
163164let elem3 = tune.into();
165assert_eq!(elem2, elem3);
166 }
167168#[test]
169fn full() {
170let 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();
173let tune = Tune::try_from(elem).unwrap();
174assert_eq!(tune.artist, Some(Artist::from_str("Yes").unwrap()));
175assert_eq!(tune.length, Some(Length(686)));
176assert_eq!(tune.rating, Some(Rating(8)));
177assert_eq!(tune.source, Some(Source::from_str("Yessongs").unwrap()));
178assert_eq!(
179 tune.title,
180Some(Title::from_str("Heart of the Sunrise").unwrap())
181 );
182assert_eq!(tune.track, Some(Track::from_str("3").unwrap()));
183assert_eq!(
184 tune.uri,
185Some(Uri::from_str("http://www.yesworld.com/lyrics/Fragile.html#9").unwrap())
186 );
187 }
188}