termusicplayback/backends/
mod.rs1use std::{error::Error, fmt::Display};
2
3use termusiclib::config::{v2::server::Backend as ConfigBackend, SharedServerSettings};
4
5use crate::{PlayerCmdSender, PlayerTrait};
6
7#[cfg(feature = "gst")]
8mod gstreamer;
9#[cfg(feature = "mpv")]
10mod mpv;
11pub(crate) mod rusty;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
15pub enum BackendSelect {
16 #[cfg(feature = "mpv")]
17 Mpv,
18 #[cfg(feature = "gst")]
19 GStreamer,
20 #[default]
21 Rusty,
22}
23
24#[derive(Debug, Clone, PartialEq)]
26pub enum BackendSelectConvertError {
27 UnavailableBackend(String),
28}
29
30impl Display for BackendSelectConvertError {
31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 match self {
33 BackendSelectConvertError::UnavailableBackend(backend) => {
34 write!(f, "Backend {backend} is unavailable")
35 }
36 }
37 }
38}
39
40impl Error for BackendSelectConvertError {}
41
42impl TryFrom<ConfigBackend> for BackendSelect {
43 type Error = BackendSelectConvertError;
44
45 fn try_from(value: ConfigBackend) -> Result<Self, Self::Error> {
46 Ok(match value {
47 #[cfg(feature = "gst")]
48 ConfigBackend::Gstreamer => Self::GStreamer,
49 #[cfg(feature = "mpv")]
50 ConfigBackend::Mpv => Self::Mpv,
51 ConfigBackend::Rusty => Self::Rusty,
52 #[allow(unreachable_patterns)] _ => {
54 return Err(BackendSelectConvertError::UnavailableBackend(
55 value.to_string(),
56 ))
57 }
58 })
59 }
60}
61
62#[non_exhaustive]
64pub enum Backend {
65 #[cfg(feature = "mpv")]
66 Mpv(mpv::MpvBackend),
67 Rusty(rusty::RustyBackend),
68 #[cfg(feature = "gst")]
69 GStreamer(gstreamer::GStreamerBackend),
70}
71
72impl Backend {
73 pub(crate) fn new_select(
75 backend: BackendSelect,
76 config: SharedServerSettings,
77 cmd_tx: PlayerCmdSender,
78 ) -> Self {
79 match backend {
80 #[cfg(feature = "mpv")]
81 BackendSelect::Mpv => Self::new_mpv(&config, cmd_tx),
82 #[cfg(feature = "gst")]
83 BackendSelect::GStreamer => Self::new_gstreamer(&config, cmd_tx),
84 BackendSelect::Rusty => Self::new_rusty(config, cmd_tx),
85 }
86 }
87
88 fn new_rusty(config: SharedServerSettings, cmd_tx: PlayerCmdSender) -> Self {
102 info!("Using Backend \"rusty\"");
103 Self::Rusty(rusty::RustyBackend::new(config, cmd_tx))
104 }
105
106 #[cfg(feature = "gst")]
108 fn new_gstreamer(config: &SharedServerSettings, cmd_tx: PlayerCmdSender) -> Self {
109 info!("Using Backend \"GStreamer\"");
110 let config_read = config.read();
111 Self::GStreamer(gstreamer::GStreamerBackend::new(&config_read, cmd_tx))
112 }
113
114 #[cfg(feature = "mpv")]
116 fn new_mpv(config: &SharedServerSettings, cmd_tx: PlayerCmdSender) -> Self {
117 info!("Using Backend \"mpv\"");
118 let config_read = config.read();
119 Self::Mpv(mpv::MpvBackend::new(&config_read, cmd_tx))
120 }
121
122 #[must_use]
123 pub fn as_player(&self) -> &dyn PlayerTrait {
124 match self {
125 #[cfg(feature = "mpv")]
126 Backend::Mpv(v) => v,
127 #[cfg(feature = "gst")]
128 Backend::GStreamer(v) => v,
129 Backend::Rusty(v) => v,
130 }
131 }
132
133 #[must_use]
134 pub fn as_player_mut(&mut self) -> &mut (dyn PlayerTrait + Send) {
135 match self {
136 #[cfg(feature = "mpv")]
137 Backend::Mpv(v) => v,
138 #[cfg(feature = "gst")]
139 Backend::GStreamer(v) => v,
140 Backend::Rusty(v) => v,
141 }
142 }
143}