av_stream_info_rust/
http_config.rs1use crate::request_error::RequestError;
2use crate::DecodeError;
3use crate::LatLong;
4use serde::de::{self, Deserializer, Unexpected};
5use serde::{Deserialize, Serialize};
6use std::convert::TryFrom;
7
8#[derive(Serialize, Deserialize, Debug, Clone)]
10pub struct MetaInfoFile {
11 #[serde(rename = "icy-index-metadata")]
12 #[serde(deserialize_with = "bool_from_int")]
13 pub index_metadata: bool,
14 #[serde(rename = "icy-version")]
15 pub version: u8,
16 #[serde(rename = "icy-main-stream-url")]
17 pub main_stream_url: Option<String>,
18 #[serde(rename = "icy-name")]
19 pub name: Option<String>,
20 #[serde(rename = "icy-description")]
21 pub description: Option<String>,
22 #[serde(rename = "icy-genre")]
23 pub genre: Option<String>,
24 #[serde(rename = "icy-language-codes")]
25 pub languages: Option<String>,
26 #[serde(rename = "icy-country-code")]
27 pub countrycode: Option<String>,
28 #[serde(rename = "icy-country-subdivision-code")]
29 pub country_subdivision_code: Option<String>,
30 #[serde(rename = "icy-logo")]
31 pub logo: Option<String>,
32 #[serde(rename = "icy-geo-lat-long")]
33 geo_lat_long: Option<String>,
34}
35
36impl MetaInfoFile {
37 pub fn get_lat_long(&self) -> Option<Result<LatLong, DecodeError>> {
39 self.geo_lat_long.clone().map(|x| LatLong::try_from(x))
40 }
41}
42
43#[cfg(feature = "blocking")]
44pub fn extract_from_homepage(homepage: &str) -> Result<MetaInfoFile, RequestError> {
45 use reqwest::blocking::get;
46 let stream_info_link = format!("{}/streaminfo.json", homepage);
47
48 trace!(
49 "extract_from_homepage({}) Download file '{}'",
50 homepage,
51 stream_info_link
52 );
53 let resp = get(&stream_info_link)?.text()?;
54 let deserialized: MetaInfoFile = serde_json::from_str(&resp)?;
55 Ok(deserialized)
56}
57
58pub async fn extract_from_homepage_async(homepage: &str) -> Result<MetaInfoFile, RequestError> {
59 use reqwest::get;
60 let stream_info_link = format!("{}/streaminfo.json", homepage);
61
62 trace!(
63 "extract_from_homepage({}) Download file '{}'",
64 homepage,
65 stream_info_link
66 );
67 let resp = get(&stream_info_link).await?.text().await?;
68 let deserialized: MetaInfoFile = serde_json::from_str(&resp)?;
69 Ok(deserialized)
70}
71
72fn bool_from_int<'de, D>(deserializer: D) -> Result<bool, D::Error>
73where
74 D: Deserializer<'de>,
75{
76 match u8::deserialize(deserializer)? {
77 0 => Ok(false),
78 1 => Ok(true),
79 other => Err(de::Error::invalid_value(
80 Unexpected::Unsigned(other as u64),
81 &"zero or one",
82 )),
83 }
84}