xspf 0.4.2

straightforward pure rust implementation of the Xml Sharable Playlist Format
Documentation
use crate::common::{Track, Playlist, Meta};

macro_rules! fn_add {
	($name:ident, $field:ident) => (
		/// requires the `setters` crate feature,
		/// see crate-level documentation for more info.
		pub fn $name<S: ToString>(&mut self, s: S) -> &mut Self {
		self.$field.push(s.to_string());
		return self;
	});
}

macro_rules! fn_set {
	($name:ident, $field:ident) => (
		/// requires the `setters` crate feature,
		/// see crate-level documentation for more info.
		pub fn $name<S: ToString>(&mut self, s: S) -> &mut Self {
		self.$field = Some(s.to_string());
		return self;
	});
}

macro_rules! fn_meta {
	($name:ident, $field:ident) => (
		/// requires the `setters` crate feature,
		/// see crate-level documentation for more info.
		pub fn $name<S: ToString>(&mut self, rel: S, content: S) -> &mut Self {
			self.$field.push(Meta{
				rel: rel.to_string(),
				content: content.to_string(),
			});
			return self;
		});
}

impl Track {
	fn_add!(add_location, location);
	fn_add!(add_identifier, identifier);
	fn_set!(set_title, title);
	fn_set!(set_creator, creator);
	fn_set!(set_annotation, annotation);
	fn_set!(set_info, info);
	fn_set!(set_image, image);
	fn_set!(set_album, album);

	/// requires the `setters` crate feature,
	/// see crate-level documentation for more info.
	pub fn set_track_num(&mut self, n: u64) -> &mut Self {
		self.track_num = Some(n);
		self
	}
	
	/// requires the `setters` crate feature,
	/// see crate-level documentation for more info.
	pub fn set_duration(&mut self, n: u64) -> &mut Self {
		self.duration = Some(n);
		self
	}

	fn_meta!(add_meta, meta);
	fn_meta!(add_link, link);
}

impl Playlist {
	fn_set!(set_title, title);
	fn_set!(set_creator, creator);
	fn_set!(set_annotation, annotation);
	fn_set!(set_info, info);
	fn_set!(set_location, location);
	fn_set!(set_identifier, identifier);
	fn_set!(set_image, image);
	fn_set!(set_date, date);
	fn_set!(set_license, license);
	fn_meta!(add_meta, meta);
	fn_meta!(add_link, link);

	/// clones the given track and appends it to `track_list`.
	///
	/// requires the `setters` crate feature,
	/// see crate-level documentation for more info.
	pub fn add_track<'a>(&'a mut self, track: &Track) -> &'a mut Self {
		self.track_list.push(track.clone());
		self
	}
}


#[cfg(test)]
mod tests {
	use super::*;

	#[test]
	fn construct() {
		let tr = Track::default()
			.set_title("test track 1")
			.set_info("https://example.org/track1")
			.clone();
		assert_eq!(tr.title, Some("test track 1".to_string()));
		assert_eq!(tr.info, Some("https://example.org/track1".to_string()));
		let pl = Playlist::default()
			.set_title("Test Playlist")
			.add_track(
				Track::default()
					.set_title("test track 2"))
			.clone();
		assert_eq!(pl.title.unwrap(), "Test Playlist");
		assert_eq!(pl.track_list.len(), 1);
	}
}