1use std::str::FromStr;
2
3use serde::{Deserialize, Serialize};
4
5pub enum Category {
6 ByLocation,
7 ByLanguage,
8 Sports,
9 Talk,
10 Music,
11 LocalRadio,
12 Podcasts,
13}
14
15pub trait CategoryTrait {
16 fn to_id(&self) -> String;
17}
18
19impl CategoryTrait for Category {
20 fn to_id(&self) -> String {
21 match self {
22 Category::ByLocation => "r0".to_string(),
23 Category::ByLanguage => "lang".to_string(),
24 Category::Sports => "sports".to_string(),
25 Category::Talk => "talk".to_string(),
26 Category::Music => "music".to_string(),
27 Category::LocalRadio => "local".to_string(),
28 Category::Podcasts => "podcast".to_string(),
29 }
30 }
31}
32
33impl ToString for Category {
34 fn to_string(&self) -> String {
35 match self {
36 Category::ByLocation => "By Location".to_string(),
37 Category::ByLanguage => "By Language".to_string(),
38 Category::Sports => "Sports".to_string(),
39 Category::Talk => "Talk".to_string(),
40 Category::Music => "Music".to_string(),
41 Category::LocalRadio => "Local Radio".to_string(),
42 Category::Podcasts => "Podcasts".to_string(),
43 }
44 }
45}
46
47impl FromStr for Category {
48 type Err = String;
49
50 fn from_str(s: &str) -> Result<Self, Self::Err> {
51 match s {
52 "By Location" => Ok(Category::ByLocation),
53 "By Language" => Ok(Category::ByLanguage),
54 "Sports" => Ok(Category::Sports),
55 "Talk" => Ok(Category::Talk),
56 "Music" => Ok(Category::Music),
57 "Local Radio" => Ok(Category::LocalRadio),
58 "Podcasts" => Ok(Category::Podcasts),
59 _ => Err(format!("{} is not a valid category", s)),
60 }
61 }
62}
63
64#[derive(Debug, Serialize, Deserialize, Clone)]
65pub struct CategoryDetails {
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub r#type: Option<String>,
68 pub text: String,
69 #[serde(rename = "URL", skip_serializing_if = "Option::is_none")]
70 pub url: Option<String>,
71 #[serde(skip_serializing_if = "Option::is_none")]
72 pub guide_id: Option<String>,
73 #[serde(skip_serializing_if = "Option::is_none")]
74 pub key: Option<String>,
75 #[serde(skip_serializing_if = "Option::is_none")]
76 pub element: Option<String>,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub children: Option<Vec<Box<SearchResult>>>,
79}
80
81#[derive(Debug, Deserialize, Clone)]
82pub struct Head {
83 pub status: String,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 pub title: Option<String>,
86}
87
88#[derive(Debug, Deserialize, Clone)]
89pub struct CategoriesResponse {
90 pub head: Head,
91 pub body: Vec<CategoryDetails>,
92}
93
94#[derive(Debug, Deserialize, Clone)]
95pub struct CategoryResponse {
96 pub head: Head,
97 pub body: Vec<Station>,
98}
99
100#[derive(Debug, Serialize, Deserialize, Clone)]
101pub struct SearchResult {
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub r#type: Option<String>,
104 pub element: String,
105 pub text: String,
106 #[serde(rename = "URL", skip_serializing_if = "Option::is_none")]
107 pub url: Option<String>,
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub bitrate: Option<String>,
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub reliability: Option<String>,
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub guide_id: Option<String>,
114 #[serde(skip_serializing_if = "Option::is_none")]
115 pub subtext: Option<String>,
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub genre_id: Option<String>,
118 #[serde(skip_serializing_if = "Option::is_none")]
119 pub formats: Option<String>,
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub playing: Option<String>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub playing_image: Option<String>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub item: Option<String>,
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub image: Option<String>,
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub now_playing_id: Option<String>,
130 #[serde(skip_serializing_if = "Option::is_none")]
131 pub preset_id: Option<String>,
132 #[serde(skip_serializing_if = "Option::is_none")]
133 pub children: Option<Vec<Box<SearchResult>>>,
134}
135
136#[derive(Debug, Deserialize, Clone)]
137pub struct SearchResponse {
138 pub head: Head,
139 pub body: Vec<SearchResult>,
140}
141
142#[derive(Debug, Serialize, Deserialize, Clone)]
143pub struct Station {
144 #[serde(rename = "URL", skip_serializing_if = "Option::is_none")]
145 pub url: Option<String>,
146 #[serde(skip_serializing_if = "Option::is_none")]
147 pub bitrate: Option<String>,
148 pub element: String,
149 #[serde(skip_serializing_if = "Option::is_none")]
150 pub formats: Option<String>,
151 #[serde(skip_serializing_if = "Option::is_none")]
152 pub genre_id: Option<String>,
153 #[serde(skip_serializing_if = "Option::is_none")]
154 pub guide_id: Option<String>,
155 #[serde(skip_serializing_if = "Option::is_none")]
156 pub image: Option<String>,
157 #[serde(skip_serializing_if = "Option::is_none")]
158 pub item: Option<String>,
159 #[serde(skip_serializing_if = "Option::is_none")]
160 pub now_playing_id: Option<String>,
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub playing: Option<String>,
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub playing_image: Option<String>,
165 #[serde(skip_serializing_if = "Option::is_none")]
166 pub preset_id: Option<String>,
167 #[serde(skip_serializing_if = "Option::is_none")]
168 pub reliability: Option<String>,
169 #[serde(skip_serializing_if = "Option::is_none")]
170 pub subtext: Option<String>,
171 pub text: String,
172 #[serde(skip_serializing_if = "Option::is_none")]
173 pub r#type: Option<String>,
174 #[serde(skip_serializing_if = "Option::is_none")]
175 pub children: Option<Vec<Box<Station>>>,
176}
177
178#[derive(Debug, Serialize, Deserialize, Clone)]
179pub struct StationLinkDetails {
180 pub bitrate: u32,
181 pub element: String,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 pub is_ad_clipped_content_enabled: Option<String>,
184 pub is_direct: bool,
185 pub is_hls_advanced: String,
186 pub live_seek_stream: String,
187 pub media_type: String,
188 pub player_height: u32,
189 pub player_width: u32,
190 #[serde(skip_serializing_if = "Option::is_none")]
191 pub playlist_type: Option<String>,
192 pub position: u32,
193 pub reliability: u32,
194 pub url: String,
195}
196
197#[derive(Debug, Deserialize, Clone)]
198pub struct StationResponse {
199 pub head: Head,
200 pub body: Vec<StationLinkDetails>,
201}