icecast-stats 0.2.3

Decode icecast server information from JSON
Documentation
use serde::{Deserialize, Serialize};

#[cfg(feature = "chrono")]
use crate::parser::parse_datetime;
#[cfg(feature = "chrono")]
use chrono::{DateTime, FixedOffset};

/// A streaming source
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct IcecastStatsSource {
    artist: Option<String>,
    title: Option<String>,
    audio_bitrate: Option<u32>,
    audio_channels: Option<u8>,
    audio_samplerate: Option<u32>,
    frame_rate: Option<f32>,
    frame_size: Option<String>,
    bitrate: Option<u32>,
    genre: Option<String>,
    #[serde(rename = "ice-bitrate")]
    ice_bitrate: Option<u32>,
    #[serde(rename = "ice-samplerate")]
    ice_samplerate: Option<u32>,
    #[serde(rename = "ice-channels")]
    ice_channels: Option<u8>,
    listener_peak: Option<u32>,
    listeners: Option<u32>,
    listenurl: Option<String>,
    server_description: Option<String>,
    server_name: Option<String>,
    server_type: Option<String>,
    subtype: Option<String>,
    stream_start_iso8601: Option<String>,
    stream_start: Option<String>,
    total_bytes_read: Option<u32>,
    total_bytes_sent: Option<u32>,
    user_agent: Option<String>,
    video_bitrate: Option<u32>,
    video_quality: Option<u32>,
}

impl IcecastStatsSource {
    /// Artist of the current song
    /// Metadata set by source client
    pub fn artist(&self) -> Option<&String> {
        self.artist.as_ref()
    }

    /// Title of the current song
    /// Metadata set by source client
    pub fn title(&self) -> Option<&String> {
        self.title.as_ref()
    }

    /// Audio bitrate in bits/s
    /// Can be set by source client
    /// Example: 128000
    pub fn audio_bitrate(&self) -> &Option<u32> {
        &self.audio_bitrate
    }

    /// Audio bitrate in bits/s
    /// Can be set by source client
    /// Example: 1
    pub fn audio_channels(&self) -> &Option<u8> {
        &self.audio_channels
    }

    /// Information about the samplerate of the stream.
    /// Can be set by source client
    /// Example: 48000
    pub fn audio_samplerate(&self) -> &Option<u32> {
        &self.audio_samplerate
    }

    /// Audio bitrate of the source in bits/s
    /// Can be set by source client
    /// Example: 128000
    pub fn audio_bitrate_source(&self) -> &Option<u32> {
        &self.ice_bitrate
    }

    /// Audio bitrate of the source in bits/s
    /// Can be set by source client
    /// Example: 1
    pub fn audio_channels_source(&self) -> &Option<u8> {
        &self.ice_channels
    }

    /// Information about the samplerate of the stream source.
    /// Can be set by source client
    /// Example: 48000
    pub fn audio_samplerate_source(&self) -> &Option<u32> {
        &self.ice_samplerate
    }

    /// Example: 25.00
    pub fn frame_rate(&self) -> &Option<f32> {
        &self.frame_rate
    }

    /// Example: 720 x 576
    pub fn frame_size(&self) -> Option<&String> {
        self.frame_size.as_ref()
    }

    /// Example: 128
    pub fn bitrate(&self) -> &Option<u32> {
        &self.bitrate
    }

    /// Example: jazz, classical
    pub fn genre(&self) -> Option<&String> {
        self.genre.as_ref()
    }

    /// Example: 128
    pub fn ice_bitrate(&self) -> &Option<u32> {
        &self.ice_bitrate
    }

    /// Example: 234
    pub fn listener_peak(&self) -> &Option<u32> {
        &self.listener_peak
    }

    /// Currently Active Listeners.
    ///
    /// Example: 23
    pub fn listeners(&self) -> &Option<u32> {
        &self.listeners
    }

    /// Example: http://localhost:8000/test2
    pub fn listenurl(&self) -> Option<&String> {
        self.listenurl.as_ref()
    }

    /// Example: Unspecified description
    pub fn server_description(&self) -> Option<&String> {
        self.server_description.as_ref()
    }

    /// Example: Unspecified name
    pub fn server_name(&self) -> Option<&String> {
        self.server_name.as_ref()
    }

    /// MIME-type for the stream currently active on this mountpoint.
    ///
    /// Example: application/ogg
    pub fn server_type(&self) -> Option<&String> {
        self.server_type.as_ref()
    }

    /// MIME-subtype, can be e.g. codecs like Opus, Vorbis, Theora.
    /// Separated with /.
    ///
    /// Example: application/ogg
    pub fn subtype(&self) -> Option<&String> {
        self.subtype.as_ref()
    }

    /// Example: 2021-04-09T21:49:52+0200
    pub fn stream_start(&self) -> Option<&String> {
        if self.stream_start_iso8601.is_some() {
            return self.stream_start_iso8601.as_ref();
        }
        self.stream_start.as_ref()
    }

    /// Timestamp of server startup as decoded Chrono object
    ///
    #[cfg(feature = "chrono")]
    pub fn stream_start_decoded(
        &self,
    ) -> Option<Result<DateTime<FixedOffset>, chrono::ParseError>> {
        self.stream_start().clone().map(|x| parse_datetime(&x))
    }

    /// HTTP user agent string as sent by the source client.
    pub fn user_agent(&self) -> Option<&String> {
        self.user_agent.as_ref()
    }
    /// Example: 200000
    pub fn video_bitrate(&self) -> Option<u32> {
        self.video_bitrate
    }

    /// Example: 0
    pub fn video_quality(&self) -> &Option<u32> {
        &self.video_quality
    }

    /// Generate simple name
    pub fn generate_name(&self) -> String {
        let mut result = String::new();
        if let Some(server_name) = self.server_name() {
            result.push_str(&server_name);
        }
        if let Some(title) = self.title() {
            result.push_str(&format!(" / {}", title));
        }
        if let Some(bitrate) = self.bitrate() {
            result.push_str(&format!(" / {} kBit", bitrate));
        }
        result
    }
}