1use std::fmt::Display;
2
3use owo_colors::OwoColorize;
4use serde::{Deserialize, Serialize};
5
6#[derive(Default, Debug, Clone, Deserialize, Serialize)]
7pub struct Device {
8 pub location: String,
9 pub device_type: String,
10 pub friendly_name: String,
11 pub manufacturer: String,
12 pub manufacturer_url: Option<String>,
13 pub model_description: Option<String>,
14 pub model_name: String,
15 pub model_number: Option<String>,
16 pub services: Vec<Service>,
17 pub udn: String,
18}
19
20#[derive(Default, Debug, Clone, Deserialize, Serialize)]
21pub struct Service {
22 pub service_type: String,
23 pub service_id: String,
24 pub control_url: String,
25 pub event_sub_url: String,
26 pub scpd_url: String,
27 pub actions: Vec<Action>,
28}
29
30#[derive(Default, Debug, Clone, Deserialize, Serialize)]
31pub struct Action {
32 pub name: String,
33 pub arguments: Vec<Argument>,
34}
35
36#[derive(Default, Debug, Clone, Deserialize, Serialize)]
37pub struct Argument {
38 pub name: String,
39 pub direction: String,
40 pub related_state_variable: String,
41}
42
43#[derive(Debug, Clone, Copy, Eq, PartialEq)]
44pub enum ObjectClass {
45 Audio,
46 Video,
47 Image,
48 Container,
49}
50
51impl From<&str> for ObjectClass {
52 fn from(value: &str) -> Self {
53 match value {
54 "object.item.audioItem.musicTrack" => ObjectClass::Audio,
55 "object.item.videoItem.movie" => ObjectClass::Video,
56 "object.item.imageItem.photo" => ObjectClass::Image,
57 "object.container" => ObjectClass::Container,
58 _ => ObjectClass::Container,
59 }
60 }
61}
62
63impl ObjectClass {
64 pub fn value(&self) -> &'static str {
65 match self {
66 ObjectClass::Audio => "object.item.audioItem.musicTrack",
67 ObjectClass::Video => "object.item.videoItem.movie",
68 ObjectClass::Image => "object.item.imageItem.photo",
69 ObjectClass::Container => "object.container",
70 }
71 }
72}
73
74#[derive(Debug, Clone, Default)]
75pub struct Metadata {
76 pub url: String,
77 pub title: String,
78 pub artist: Option<String>,
79 pub album: Option<String>,
80 pub album_art_uri: Option<String>,
81 pub genre: Option<String>,
82 pub protocol_info: String,
83}
84
85#[derive(Debug, Clone, Default)]
86pub struct LoadOptions {
87 pub dlna_features: Option<String>,
88 pub content_type: Option<String>,
89 pub object_class: Option<ObjectClass>,
90 pub metadata: Option<Metadata>,
91 pub autoplay: bool,
92}
93
94#[derive(Debug)]
95pub enum AVTransportEvent {
96 AVTransportURIMetaData {
97 sid: String,
98 url: String,
99 title: String,
100 artist: Option<String>,
101 album: Option<String>,
102 album_art_uri: Option<String>,
103 genre: Option<String>,
104 },
105 CurrentPlayMode {
106 sid: String,
107 play_mode: String,
108 },
109 CurrentTrackMetadata {
110 sid: String,
111 url: String,
112 title: String,
113 artist: Option<String>,
114 album: Option<String>,
115 album_art_uri: Option<String>,
116 genre: Option<String>,
117 },
118 TransportState {
119 sid: String,
120 transport_state: String,
121 },
122}
123
124#[derive(Debug)]
125pub enum Event {
126 AVTransport(AVTransportEvent),
127}
128
129impl Display for Event {
130 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131 match self {
132 Event::AVTransport(event) => match event {
133 AVTransportEvent::AVTransportURIMetaData {
134 sid,
135 url,
136 title,
137 artist,
138 album,
139 album_art_uri,
140 genre,
141 } => write!(
142 f,
143 "AVTransportEvent::AVTransportURIMetaData {{\n sid: {},\n url: {},\n title: {},\n artist: {:?},\n album: {:?},\n album_art_uri: {:?},\n genre: {:?}\n }}",
144 sid.bright_green(), url.bright_green(), title.bright_green(), artist.bright_green(), album.bright_green(), album_art_uri.bright_green(), genre.bright_green()
145 ),
146 AVTransportEvent::CurrentPlayMode { sid, play_mode } => {
147 write!(f, "AVTransportEvent::CurrentPlayMode {{\n sid: {}, play_mode: {}\n }}", sid.bright_green(), play_mode.bright_green())
148 }
149 AVTransportEvent::CurrentTrackMetadata {
150 sid,
151 url,
152 title,
153 artist,
154 album,
155 album_art_uri,
156 genre,
157 } => write!(
158 f,
159 "AVTransportEvent::CurrentTrackMetadata {{\n sid: {},\n url: {},\n title: {},\n artist: {:?},\n album: {:?},\n album_art_uri: {:?},\n genre: {:?}\n }}",
160 sid.bright_green(), url.bright_green(), title.bright_green(), artist.bright_green(), album.bright_green(), album_art_uri.bright_green(), genre.bright_green()
161 ),
162 AVTransportEvent::TransportState {
163 sid,
164 transport_state,
165 } => write!(
166 f,
167 "AVTransportEvent::TransportState {{\n sid: {},\n transport_state: {}\n }}",
168 sid.bright_green(), transport_state.bright_green()
169 ),
170 },
171 }
172 }
173}
174
175#[derive(Debug, Clone, Default)]
176pub struct Container {
177 pub id: String,
178 pub parent_id: String,
179 pub title: String,
180 pub creator: Option<String>,
181 pub restricted: bool,
182 pub searchable: bool,
183 pub child_count: Option<u32>,
184 pub album_art_uri: Option<String>,
185 pub album: Option<String>,
186 pub artist: Option<String>,
187 pub genre: Option<String>,
188 pub date: Option<String>,
189 pub original_track_number: Option<u32>,
190 pub protocol_info: Option<String>,
191 pub url: Option<String>,
192 pub object_class: Option<ObjectClass>,
193}
194
195#[derive(Debug, Clone, Default)]
196pub struct Item {
197 pub id: String,
198 pub parent_id: String,
199 pub title: String,
200 pub creator: Option<String>,
201 pub restricted: bool,
202 pub searchable: bool,
203 pub album_art_uri: Option<String>,
204 pub album: Option<String>,
205 pub artist: Option<String>,
206 pub genre: Option<String>,
207 pub date: Option<String>,
208 pub original_track_number: Option<u32>,
209 pub protocol_info: String,
210 pub url: String,
211 pub size: Option<u64>,
212 pub duration: Option<String>,
213 pub object_class: Option<ObjectClass>,
214}
215
216#[derive(Debug, Clone, Default)]
217pub struct TransportInfo {
218 pub current_transport_state: String,
219 pub current_transport_status: String,
220 pub current_speed: String,
221}