2019-09-05 13:37:34 +00:00
// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
2024-07-28 16:13:01 +00:00
use xso ::{ AsXml , FromXml } ;
2019-09-05 13:37:34 +00:00
use crate ::ns ;
2019-10-22 23:32:41 +00:00
use crate ::pubsub ::PubSubPayload ;
2019-09-05 13:37:34 +00:00
generate_elem_id! (
/// The artist or performer of the song or piece.
2019-10-22 23:32:41 +00:00
Artist ,
" artist " ,
TUNE
2019-09-05 13:37:34 +00:00
) ;
generate_elem_id! (
/// The duration of the song or piece in seconds.
2019-10-22 23:32:41 +00:00
Length ,
" length " ,
TUNE ,
2019-09-05 13:37:34 +00:00
u16
) ;
generate_elem_id! (
/// The user's rating of the song or piece, from 1 (lowest) to 10 (highest).
2019-10-22 23:32:41 +00:00
Rating ,
" rating " ,
TUNE ,
2019-09-05 13:37:34 +00:00
u8
) ;
generate_elem_id! (
/// The collection (e.g., album) or other source (e.g., a band website that hosts streams or
/// audio files).
2019-10-22 23:32:41 +00:00
Source ,
" source " ,
TUNE
2019-09-05 13:37:34 +00:00
) ;
generate_elem_id! (
/// The title of the song or piece.
2019-10-22 23:32:41 +00:00
Title ,
" title " ,
TUNE
2019-09-05 13:37:34 +00:00
) ;
generate_elem_id! (
/// A unique identifier for the tune; e.g., the track number within a collection or the
/// specific URI for the object (e.g., a stream or audio file).
2019-10-22 23:32:41 +00:00
Track ,
" track " ,
TUNE
2019-09-05 13:37:34 +00:00
) ;
generate_elem_id! (
/// A URI or URL pointing to information about the song, collection, or artist.
2019-10-22 23:32:41 +00:00
Uri ,
" uri " ,
TUNE
2019-09-05 13:37:34 +00:00
) ;
/// Container for formatted text.
2024-07-28 16:13:01 +00:00
#[ derive(FromXml, AsXml, Debug, Clone, PartialEq) ]
#[ xml(namespace = ns::TUNE, name = " tune " ) ]
2019-09-05 13:37:34 +00:00
pub struct Tune {
/// The artist or performer of the song or piece.
2024-07-28 16:13:01 +00:00
#[ xml(child(default)) ]
2019-09-05 13:37:34 +00:00
artist : Option < Artist > ,
/// The duration of the song or piece in seconds.
2024-07-28 16:13:01 +00:00
#[ xml(child(default)) ]
2019-09-05 13:37:34 +00:00
length : Option < Length > ,
/// The user's rating of the song or piece, from 1 (lowest) to 10 (highest).
2024-07-28 16:13:01 +00:00
#[ xml(child(default)) ]
2019-09-05 13:37:34 +00:00
rating : Option < Rating > ,
/// The collection (e.g., album) or other source (e.g., a band website that hosts streams or
/// audio files).
2024-07-28 16:13:01 +00:00
#[ xml(child(default)) ]
2019-09-05 13:37:34 +00:00
source : Option < Source > ,
/// The title of the song or piece.
2024-07-28 16:13:01 +00:00
#[ xml(child(default)) ]
2019-09-05 13:37:34 +00:00
title : Option < Title > ,
/// A unique identifier for the tune; e.g., the track number within a collection or the
/// specific URI for the object (e.g., a stream or audio file).
2024-07-28 16:13:01 +00:00
#[ xml(child(default)) ]
2019-09-05 13:37:34 +00:00
track : Option < Track > ,
/// A URI or URL pointing to information about the song, collection, or artist.
2024-07-28 16:13:01 +00:00
#[ xml(child(default)) ]
2019-09-05 13:37:34 +00:00
uri : Option < Uri > ,
}
impl PubSubPayload for Tune { }
impl Tune {
2024-07-28 16:13:01 +00:00
/// Construct an empty `<tune/>` element.
pub fn new ( ) -> Tune {
2019-09-05 13:37:34 +00:00
Tune {
artist : None ,
length : None ,
rating : None ,
source : None ,
title : None ,
track : None ,
uri : None ,
}
}
}
#[ cfg(test) ]
mod tests {
use super ::* ;
2024-07-28 16:13:01 +00:00
use minidom ::Element ;
2019-09-05 13:37:34 +00:00
use std ::str ::FromStr ;
#[ cfg(target_pointer_width = " 32 " ) ]
#[ test ]
fn test_size ( ) {
2020-10-29 17:39:22 +00:00
assert_size! ( Tune , 68 ) ;
2019-09-05 15:58:45 +00:00
assert_size! ( Artist , 12 ) ;
assert_size! ( Length , 2 ) ;
assert_size! ( Rating , 1 ) ;
assert_size! ( Source , 12 ) ;
assert_size! ( Title , 12 ) ;
assert_size! ( Track , 12 ) ;
assert_size! ( Uri , 12 ) ;
2019-09-05 13:37:34 +00:00
}
#[ cfg(target_pointer_width = " 64 " ) ]
#[ test ]
fn test_size ( ) {
assert_size! ( Tune , 128 ) ;
2019-09-05 15:58:45 +00:00
assert_size! ( Artist , 24 ) ;
assert_size! ( Length , 2 ) ;
assert_size! ( Rating , 1 ) ;
assert_size! ( Source , 24 ) ;
assert_size! ( Title , 24 ) ;
assert_size! ( Track , 24 ) ;
assert_size! ( Uri , 24 ) ;
2019-09-05 13:37:34 +00:00
}
#[ test ]
fn empty ( ) {
let elem : Element = " <tune xmlns='http://jabber.org/protocol/tune'/> "
. parse ( )
. unwrap ( ) ;
let elem2 = elem . clone ( ) ;
let tune = Tune ::try_from ( elem ) . unwrap ( ) ;
assert! ( tune . artist . is_none ( ) ) ;
assert! ( tune . length . is_none ( ) ) ;
assert! ( tune . rating . is_none ( ) ) ;
assert! ( tune . source . is_none ( ) ) ;
assert! ( tune . title . is_none ( ) ) ;
assert! ( tune . track . is_none ( ) ) ;
assert! ( tune . uri . is_none ( ) ) ;
let elem3 = tune . into ( ) ;
assert_eq! ( elem2 , elem3 ) ;
}
#[ test ]
fn full ( ) {
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> "
. parse ( )
. unwrap ( ) ;
let tune = Tune ::try_from ( elem ) . unwrap ( ) ;
assert_eq! ( tune . artist , Some ( Artist ::from_str ( " Yes " ) . unwrap ( ) ) ) ;
assert_eq! ( tune . length , Some ( Length ( 686 ) ) ) ;
assert_eq! ( tune . rating , Some ( Rating ( 8 ) ) ) ;
assert_eq! ( tune . source , Some ( Source ::from_str ( " Yessongs " ) . unwrap ( ) ) ) ;
2019-10-22 23:32:41 +00:00
assert_eq! (
tune . title ,
Some ( Title ::from_str ( " Heart of the Sunrise " ) . unwrap ( ) )
) ;
2019-09-05 13:37:34 +00:00
assert_eq! ( tune . track , Some ( Track ::from_str ( " 3 " ) . unwrap ( ) ) ) ;
2019-10-22 23:32:41 +00:00
assert_eq! (
tune . uri ,
Some ( Uri ::from_str ( " http://www.yesworld.com/lyrics/Fragile.html#9 " ) . unwrap ( ) )
) ;
2019-09-05 13:37:34 +00:00
}
}