common: move types into separate files
This commit is contained in:
288
src/common.rs
288
src/common.rs
@@ -1,286 +1,2 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub type SongPosition = u32;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum AbsouluteRelativeSongPosition {
|
||||
Absolute(SongPosition),
|
||||
RelativePlus(SongPosition),
|
||||
RelativeMinus(SongPosition),
|
||||
}
|
||||
|
||||
impl FromStr for AbsouluteRelativeSongPosition {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
s if s.starts_with('+') => Self::RelativePlus(s[1..].parse().map_err(|_| ())?),
|
||||
s if s.starts_with('-') => Self::RelativeMinus(s[1..].parse().map_err(|_| ())?),
|
||||
s => Self::Absolute(s.parse().map_err(|_| ())?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type SongId = u32;
|
||||
pub type Seconds = u32;
|
||||
pub type TimeWithFractions = f64;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum OneOrRange {
|
||||
One(SongPosition),
|
||||
Range(SongPosition, SongPosition),
|
||||
}
|
||||
|
||||
impl FromStr for OneOrRange {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split(':');
|
||||
let start = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||
Ok(match parts.next() {
|
||||
Some(end) => Self::Range(start, end.parse().map_err(|_| ())?),
|
||||
None => Self::One(start),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct WindowRange {
|
||||
pub start: SongPosition,
|
||||
pub end: Option<SongPosition>,
|
||||
}
|
||||
|
||||
impl FromStr for WindowRange {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split(':');
|
||||
let start = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||
let end = parts.next().map(|s| s.parse().map_err(|_| ()));
|
||||
Ok(Self {
|
||||
start,
|
||||
end: end.transpose()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct TimeInterval {
|
||||
pub start: Option<TimeWithFractions>,
|
||||
pub end: Option<TimeWithFractions>,
|
||||
}
|
||||
|
||||
impl FromStr for TimeInterval {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split(':');
|
||||
let start = parts.next().map(|s| s.parse().map_err(|_| ()));
|
||||
let end = parts.next().map(|s| s.parse().map_err(|_| ()));
|
||||
Ok(Self {
|
||||
start: start.transpose()?,
|
||||
end: end.transpose()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type Priority = u8;
|
||||
pub type PlaylistName = String;
|
||||
pub type Offset = u32;
|
||||
|
||||
// TODO: use a proper types
|
||||
pub type TagName = String;
|
||||
pub type TagValue = String;
|
||||
pub type Uri = String;
|
||||
pub type Path = String;
|
||||
pub type Sort = String;
|
||||
pub type Version = String;
|
||||
pub type Feature = String;
|
||||
pub type PartitionName = String;
|
||||
pub type AudioOutputId = String;
|
||||
pub type ChannelName = String;
|
||||
pub type StickerType = String;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum Tag {
|
||||
/// The artist name. Its meaning is not well-defined; see “composer” and “performer” for more specific tags.
|
||||
Artist(String),
|
||||
/// Same as artist, but for sorting. This usually omits prefixes such as “The”.
|
||||
ArtistSort(String),
|
||||
/// The album name.
|
||||
Album(String),
|
||||
/// Same as album, but for sorting.
|
||||
AlbumSort(String),
|
||||
/// On multi-artist albums, this is the artist name which shall be used for the whole album. The exact meaning of this tag is not well-defined.
|
||||
AlbumArtist(String),
|
||||
/// Same as albumartist, but for sorting.
|
||||
AlbumArtistSort(String),
|
||||
/// The song title.
|
||||
Title(String),
|
||||
/// Same as title, but for sorting.
|
||||
TitleSort(String),
|
||||
/// The decimal track number within the album.
|
||||
Track(String),
|
||||
/// A name for this song. This is not the song title. The exact meaning of this tag is not well-defined. It is often used by badly configured internet radio stations with broken tags to squeeze both the artist name and the song title in one tag.
|
||||
Name(String),
|
||||
/// The music genre.
|
||||
Genre(String),
|
||||
/// The mood of the audio with a few keywords.
|
||||
Mood(String),
|
||||
/// The song's release date. This is usually a 4-digit year.
|
||||
Date(String),
|
||||
/// The song's original release date.
|
||||
OriginalDate(String),
|
||||
/// The artist who composed the song.
|
||||
Composer(String),
|
||||
/// Same as composer, but for sorting.
|
||||
ComposerSort(String),
|
||||
/// The artist who performed the song.
|
||||
Performer(String),
|
||||
/// The conductor who conducted the song.
|
||||
Conductor(String),
|
||||
/// “a work is a distinct intellectual or artistic creation, which can be expressed in the form of one or more audio recordings”
|
||||
Work(String),
|
||||
/// The ensemble performing this song, e.g. “Wiener Philharmoniker”.
|
||||
Ensemble(String),
|
||||
/// Name of the movement, e.g. “Andante con moto”.
|
||||
Movement(String),
|
||||
/// Movement number, e.g. “2” or “II”.
|
||||
MovementNumber(String),
|
||||
/// If this tag is set to “1” players supporting this tag will display the work, movement, and movementnumber` instead of the track title.
|
||||
ShowMovement(String),
|
||||
/// Location of the recording, e.g. “Royal Albert Hall”.
|
||||
Location(String),
|
||||
/// “used if the sound belongs to a larger category of sounds/music” (from the IDv2.4.0 TIT1 description).
|
||||
Grouping(String),
|
||||
/// A human-readable comment about this song. The exact meaning of this tag is not well-defined.
|
||||
Comment(String),
|
||||
/// The decimal disc number in a multi-disc album.
|
||||
Disc(String),
|
||||
/// The name of the label or publisher.
|
||||
Label(String),
|
||||
/// The artist id in the MusicBrainz database.
|
||||
MusicBrainzArtistId(String),
|
||||
/// The album id in the MusicBrainz database.
|
||||
MusicBrainzAlbumId(String),
|
||||
/// The album artist id in the MusicBrainz database.
|
||||
MusicBrainzAlbumArtistId(String),
|
||||
/// The track id in the MusicBrainz database.
|
||||
MusicBrainzTrackId(String),
|
||||
/// The release group id in the MusicBrainz database.
|
||||
MusicBrainzReleaseGroupId(String),
|
||||
/// The release track id in the MusicBrainz database.
|
||||
MusicBrainzReleaseTrackId(String),
|
||||
/// The work id in the MusicBrainz database.
|
||||
MusicBrainzWorkId(String),
|
||||
|
||||
/// Other tags not covered by the above
|
||||
Other(String, String),
|
||||
}
|
||||
|
||||
/// These are different parts of the canonical MPD server.
|
||||
/// They are mostly used in the protocol with the `idle` command,
|
||||
/// signalling that the client is waiting for changes in any, one or multiple of these subsystems.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum SubSystem {
|
||||
/// The song database has been modified after update.
|
||||
Database,
|
||||
/// A database update has started or finished. If the database was modified during the update, the database event is also emitted.
|
||||
Update,
|
||||
/// A stored playlist has been modified, renamed, created or deleted
|
||||
StoredPlaylist,
|
||||
/// The queue (i.e. the current playlist) has been modified
|
||||
Playlist,
|
||||
/// The player has been started, stopped or seeked or tags of the currently playing song have changed (e.g. received from stream)
|
||||
Player,
|
||||
/// The volume has been changed
|
||||
Mixer,
|
||||
/// An audio output has been added, removed or modified (e.g. renamed, enabled or disabled)
|
||||
Output,
|
||||
/// Options like repeat, random, crossfade, replay gain
|
||||
Options,
|
||||
/// A partition was added, removed or changed
|
||||
Partition,
|
||||
/// The sticker database has been modified.
|
||||
Sticker,
|
||||
/// A client has subscribed or unsubscribed to a channel
|
||||
Subscription,
|
||||
/// A message was received on a channel this client is subscribed to; this event is only emitted when the client’s message queue is empty
|
||||
Message,
|
||||
/// A neighbor was found or lost
|
||||
Neighbor,
|
||||
/// The mount list has changed
|
||||
Mount,
|
||||
|
||||
/// Other subsystems not covered by the above
|
||||
Other(String),
|
||||
}
|
||||
|
||||
impl FromStr for SubSystem {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"database" => Self::Database,
|
||||
"update" => Self::Update,
|
||||
"stored_playlist" => Self::StoredPlaylist,
|
||||
"playlist" => Self::Playlist,
|
||||
"player" => Self::Player,
|
||||
"mixer" => Self::Mixer,
|
||||
"output" => Self::Output,
|
||||
"options" => Self::Options,
|
||||
"partition" => Self::Partition,
|
||||
"sticker" => Self::Sticker,
|
||||
"subscription" => Self::Subscription,
|
||||
"message" => Self::Message,
|
||||
"neighbor" => Self::Neighbor,
|
||||
"mount" => Self::Mount,
|
||||
other => Self::Other(other.to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Audio {
|
||||
pub sample_rate: u64,
|
||||
pub bits: u8,
|
||||
pub channels: u8,
|
||||
}
|
||||
|
||||
impl FromStr for Audio {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split(':');
|
||||
let sample_rate = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||
let bits = u8::from_str_radix(parts.next().ok_or(())?, 16).map_err(|_| ())? + 1;
|
||||
let channels = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||
Ok(Self {
|
||||
sample_rate,
|
||||
bits,
|
||||
channels,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum BoolOrOneshot {
|
||||
True,
|
||||
False,
|
||||
Oneshot,
|
||||
}
|
||||
|
||||
impl FromStr for BoolOrOneshot {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"0" => Self::False,
|
||||
"1" => Self::True,
|
||||
"oneshot" => Self::Oneshot,
|
||||
_ => return Err(()),
|
||||
})
|
||||
}
|
||||
}
|
||||
mod types;
|
||||
pub use types::*;
|
||||
|
||||
38
src/common/types.rs
Normal file
38
src/common/types.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
mod absolute_relative_song_position;
|
||||
mod audio;
|
||||
mod bool_or_oneshot;
|
||||
mod one_or_range;
|
||||
mod subsystem;
|
||||
mod tag;
|
||||
mod time_interval;
|
||||
mod window_range;
|
||||
|
||||
pub use absolute_relative_song_position::AbsouluteRelativeSongPosition;
|
||||
pub use audio::Audio;
|
||||
pub use bool_or_oneshot::BoolOrOneshot;
|
||||
pub use one_or_range::OneOrRange;
|
||||
pub use subsystem::SubSystem;
|
||||
pub use tag::Tag;
|
||||
pub use time_interval::TimeInterval;
|
||||
pub use window_range::WindowRange;
|
||||
|
||||
pub type SongPosition = u32;
|
||||
pub type SongId = u32;
|
||||
pub type Seconds = u32;
|
||||
pub type TimeWithFractions = f64;
|
||||
pub type Priority = u8;
|
||||
pub type PlaylistName = String;
|
||||
pub type Offset = u32;
|
||||
|
||||
// TODO: use a proper types
|
||||
pub type TagName = String;
|
||||
pub type TagValue = String;
|
||||
pub type Uri = String;
|
||||
pub type Path = String;
|
||||
pub type Sort = String;
|
||||
pub type Version = String;
|
||||
pub type Feature = String;
|
||||
pub type PartitionName = String;
|
||||
pub type AudioOutputId = String;
|
||||
pub type ChannelName = String;
|
||||
pub type StickerType = String;
|
||||
25
src/common/types/absolute_relative_song_position.rs
Normal file
25
src/common/types/absolute_relative_song_position.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::SongPosition;
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum AbsouluteRelativeSongPosition {
|
||||
Absolute(SongPosition),
|
||||
RelativePlus(SongPosition),
|
||||
RelativeMinus(SongPosition),
|
||||
}
|
||||
|
||||
impl FromStr for AbsouluteRelativeSongPosition {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
s if s.starts_with('+') => Self::RelativePlus(s[1..].parse().map_err(|_| ())?),
|
||||
s if s.starts_with('-') => Self::RelativeMinus(s[1..].parse().map_err(|_| ())?),
|
||||
s => Self::Absolute(s.parse().map_err(|_| ())?),
|
||||
})
|
||||
}
|
||||
}
|
||||
27
src/common/types/audio.rs
Normal file
27
src/common/types/audio.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Audio {
|
||||
pub sample_rate: u64,
|
||||
pub bits: u8,
|
||||
pub channels: u8,
|
||||
}
|
||||
|
||||
impl FromStr for Audio {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split(':');
|
||||
let sample_rate = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||
let bits = u8::from_str_radix(parts.next().ok_or(())?, 16).map_err(|_| ())? + 1;
|
||||
let channels = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||
Ok(Self {
|
||||
sample_rate,
|
||||
bits,
|
||||
channels,
|
||||
})
|
||||
}
|
||||
}
|
||||
23
src/common/types/bool_or_oneshot.rs
Normal file
23
src/common/types/bool_or_oneshot.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum BoolOrOneshot {
|
||||
True,
|
||||
False,
|
||||
Oneshot,
|
||||
}
|
||||
|
||||
impl FromStr for BoolOrOneshot {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"0" => Self::False,
|
||||
"1" => Self::True,
|
||||
"oneshot" => Self::Oneshot,
|
||||
_ => return Err(()),
|
||||
})
|
||||
}
|
||||
}
|
||||
24
src/common/types/one_or_range.rs
Normal file
24
src/common/types/one_or_range.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::SongPosition;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum OneOrRange {
|
||||
One(SongPosition),
|
||||
Range(SongPosition, SongPosition),
|
||||
}
|
||||
|
||||
impl FromStr for OneOrRange {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split(':');
|
||||
let start = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||
Ok(match parts.next() {
|
||||
Some(end) => Self::Range(start, end.parse().map_err(|_| ())?),
|
||||
None => Self::One(start),
|
||||
})
|
||||
}
|
||||
}
|
||||
66
src/common/types/subsystem.rs
Normal file
66
src/common/types/subsystem.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
/// These are different parts of the canonical MPD server.
|
||||
/// They are mostly used in the protocol with the `idle` command,
|
||||
/// signalling that the client is waiting for changes in any, one or multiple of these subsystems.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum SubSystem {
|
||||
/// The song database has been modified after update.
|
||||
Database,
|
||||
/// A database update has started or finished. If the database was modified during the update, the database event is also emitted.
|
||||
Update,
|
||||
/// A stored playlist has been modified, renamed, created or deleted
|
||||
StoredPlaylist,
|
||||
/// The queue (i.e. the current playlist) has been modified
|
||||
Playlist,
|
||||
/// The player has been started, stopped or seeked or tags of the currently playing song have changed (e.g. received from stream)
|
||||
Player,
|
||||
/// The volume has been changed
|
||||
Mixer,
|
||||
/// An audio output has been added, removed or modified (e.g. renamed, enabled or disabled)
|
||||
Output,
|
||||
/// Options like repeat, random, crossfade, replay gain
|
||||
Options,
|
||||
/// A partition was added, removed or changed
|
||||
Partition,
|
||||
/// The sticker database has been modified.
|
||||
Sticker,
|
||||
/// A client has subscribed or unsubscribed to a channel
|
||||
Subscription,
|
||||
/// A message was received on a channel this client is subscribed to; this event is only emitted when the client’s message queue is empty
|
||||
Message,
|
||||
/// A neighbor was found or lost
|
||||
Neighbor,
|
||||
/// The mount list has changed
|
||||
Mount,
|
||||
|
||||
/// Other subsystems not covered by the above
|
||||
Other(String),
|
||||
}
|
||||
|
||||
impl FromStr for SubSystem {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"database" => Self::Database,
|
||||
"update" => Self::Update,
|
||||
"stored_playlist" => Self::StoredPlaylist,
|
||||
"playlist" => Self::Playlist,
|
||||
"player" => Self::Player,
|
||||
"mixer" => Self::Mixer,
|
||||
"output" => Self::Output,
|
||||
"options" => Self::Options,
|
||||
"partition" => Self::Partition,
|
||||
"sticker" => Self::Sticker,
|
||||
"subscription" => Self::Subscription,
|
||||
"message" => Self::Message,
|
||||
"neighbor" => Self::Neighbor,
|
||||
"mount" => Self::Mount,
|
||||
other => Self::Other(other.to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
121
src/common/types/tag.rs
Normal file
121
src/common/types/tag.rs
Normal file
@@ -0,0 +1,121 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum Tag {
|
||||
/// The artist name. Its meaning is not well-defined; see “composer” and “performer” for more specific tags.
|
||||
Artist(String),
|
||||
/// Same as artist, but for sorting. This usually omits prefixes such as “The”.
|
||||
ArtistSort(String),
|
||||
/// The album name.
|
||||
Album(String),
|
||||
/// Same as album, but for sorting.
|
||||
AlbumSort(String),
|
||||
/// On multi-artist albums, this is the artist name which shall be used for the whole album. The exact meaning of this tag is not well-defined.
|
||||
AlbumArtist(String),
|
||||
/// Same as albumartist, but for sorting.
|
||||
AlbumArtistSort(String),
|
||||
/// The song title.
|
||||
Title(String),
|
||||
/// Same as title, but for sorting.
|
||||
TitleSort(String),
|
||||
/// The decimal track number within the album.
|
||||
Track(String),
|
||||
/// A name for this song. This is not the song title. The exact meaning of this tag is not well-defined. It is often used by badly configured internet radio stations with broken tags to squeeze both the artist name and the song title in one tag.
|
||||
Name(String),
|
||||
/// The music genre.
|
||||
Genre(String),
|
||||
/// The mood of the audio with a few keywords.
|
||||
Mood(String),
|
||||
/// The song's release date. This is usually a 4-digit year.
|
||||
Date(String),
|
||||
/// The song's original release date.
|
||||
OriginalDate(String),
|
||||
/// The artist who composed the song.
|
||||
Composer(String),
|
||||
/// Same as composer, but for sorting.
|
||||
ComposerSort(String),
|
||||
/// The artist who performed the song.
|
||||
Performer(String),
|
||||
/// The conductor who conducted the song.
|
||||
Conductor(String),
|
||||
/// “a work is a distinct intellectual or artistic creation, which can be expressed in the form of one or more audio recordings”
|
||||
Work(String),
|
||||
/// The ensemble performing this song, e.g. “Wiener Philharmoniker”.
|
||||
Ensemble(String),
|
||||
/// Name of the movement, e.g. “Andante con moto”.
|
||||
Movement(String),
|
||||
/// Movement number, e.g. “2” or “II”.
|
||||
MovementNumber(String),
|
||||
/// If this tag is set to “1” players supporting this tag will display the work, movement, and movementnumber` instead of the track title.
|
||||
ShowMovement(String),
|
||||
/// Location of the recording, e.g. “Royal Albert Hall”.
|
||||
Location(String),
|
||||
/// “used if the sound belongs to a larger category of sounds/music” (from the IDv2.4.0 TIT1 description).
|
||||
Grouping(String),
|
||||
/// A human-readable comment about this song. The exact meaning of this tag is not well-defined.
|
||||
Comment(String),
|
||||
/// The decimal disc number in a multi-disc album.
|
||||
Disc(String),
|
||||
/// The name of the label or publisher.
|
||||
Label(String),
|
||||
/// The artist id in the MusicBrainz database.
|
||||
MusicBrainzArtistId(String),
|
||||
/// The album id in the MusicBrainz database.
|
||||
MusicBrainzAlbumId(String),
|
||||
/// The album artist id in the MusicBrainz database.
|
||||
MusicBrainzAlbumArtistId(String),
|
||||
/// The track id in the MusicBrainz database.
|
||||
MusicBrainzTrackId(String),
|
||||
/// The release group id in the MusicBrainz database.
|
||||
MusicBrainzReleaseGroupId(String),
|
||||
/// The release track id in the MusicBrainz database.
|
||||
MusicBrainzReleaseTrackId(String),
|
||||
/// The work id in the MusicBrainz database.
|
||||
MusicBrainzWorkId(String),
|
||||
|
||||
/// Other tags not covered by the above
|
||||
Other(String, String),
|
||||
}
|
||||
|
||||
impl Tag {
|
||||
pub fn new(key: String, value: String) -> Tag {
|
||||
match key.as_str() {
|
||||
"Artist" => Self::Artist(value),
|
||||
"ArtistSort" => Self::ArtistSort(value),
|
||||
"Album" => Self::Album(value),
|
||||
"AlbumSort" => Self::AlbumSort(value),
|
||||
"AlbumArtist" => Self::AlbumArtist(value),
|
||||
"AlbumArtistSort" => Self::AlbumArtistSort(value),
|
||||
"Title" => Self::Title(value),
|
||||
"TitleSort" => Self::TitleSort(value),
|
||||
"Track" => Self::Track(value),
|
||||
"Name" => Self::Name(value),
|
||||
"Genre" => Self::Genre(value),
|
||||
"Mood" => Self::Mood(value),
|
||||
"Date" => Self::Date(value),
|
||||
"OriginalDate" => Self::OriginalDate(value),
|
||||
"Composer" => Self::Composer(value),
|
||||
"ComposerSort" => Self::ComposerSort(value),
|
||||
"Performer" => Self::Performer(value),
|
||||
"Conductor" => Self::Conductor(value),
|
||||
"Work" => Self::Work(value),
|
||||
"Ensemble" => Self::Ensemble(value),
|
||||
"Movement" => Self::Movement(value),
|
||||
"MovementNumber" => Self::MovementNumber(value),
|
||||
"ShowMovement" => Self::ShowMovement(value),
|
||||
"Location" => Self::Location(value),
|
||||
"Grouping" => Self::Grouping(value),
|
||||
"Comment" => Self::Comment(value),
|
||||
"Disc" => Self::Disc(value),
|
||||
"Label" => Self::Label(value),
|
||||
"MusicBrainzArtistId" => Self::MusicBrainzArtistId(value),
|
||||
"MusicBrainzAlbumId" => Self::MusicBrainzAlbumId(value),
|
||||
"MusicBrainzAlbumArtistId" => Self::MusicBrainzAlbumArtistId(value),
|
||||
"MusicBrainzTrackId" => Self::MusicBrainzTrackId(value),
|
||||
"MusicBrainzReleaseGroupId" => Self::MusicBrainzReleaseGroupId(value),
|
||||
"MusicBrainzReleaseTrackId" => Self::MusicBrainzReleaseTrackId(value),
|
||||
"MusicBrainzWorkId" => Self::MusicBrainzWorkId(value),
|
||||
other => Self::Other(other.to_string(), value),
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/common/types/time_interval.rs
Normal file
25
src/common/types/time_interval.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::TimeWithFractions;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct TimeInterval {
|
||||
pub start: Option<TimeWithFractions>,
|
||||
pub end: Option<TimeWithFractions>,
|
||||
}
|
||||
|
||||
impl FromStr for TimeInterval {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split(':');
|
||||
let start = parts.next().map(|s| s.parse().map_err(|_| ()));
|
||||
let end = parts.next().map(|s| s.parse().map_err(|_| ()));
|
||||
Ok(Self {
|
||||
start: start.transpose()?,
|
||||
end: end.transpose()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
26
src/common/types/window_range.rs
Normal file
26
src/common/types/window_range.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::SongPosition;
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct WindowRange {
|
||||
pub start: SongPosition,
|
||||
pub end: Option<SongPosition>,
|
||||
}
|
||||
|
||||
impl FromStr for WindowRange {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split(':');
|
||||
let start = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||
let end = parts.next().map(|s| s.parse().map_err(|_| ()));
|
||||
Ok(Self {
|
||||
start,
|
||||
end: end.transpose()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user