anchorage 0.1.1

A stable wrapper (Tokio-Based) around Lavalink in Rust
Documentation
use super::str_to_u64;

use serde::{Deserialize, Serialize};
use serde_json::Value;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Severity {
    Common,
    Suspicious,
    Fault,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LoadType {
    Track,
    Playlist,
    Search,
    Empty,
    Error,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "loadType", content = "data")]
pub enum DataType {
    Track(Track),
    Playlist(TrackPlaylist),
    Search(Vec<Track>),
    Error(TrackLoadException),
    Empty(Option<Value>),
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PlaylistInfo {
    pub name: String,
    pub selected_track: i32,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TrackPlaylist {
    pub info: PlaylistInfo,
    pub plugin_info: Value,
    pub tracks: Vec<Track>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TrackLoadException {
    pub message: String,
    pub severity: Severity,
    pub cause: String,
}

#[derive(Default, Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LavalinkFilters {
    pub volume: Option<f64>,
    pub equalizer: Option<Vec<Equalizer>>,
    pub karaoke: Option<Karaoke>,
    pub timescale: Option<Timescale>,
    pub tremolo: Option<Tremolo>,
    pub vibrato: Option<Vibrato>,
    pub rotation: Option<Rotation>,
    pub distortion: Option<Distortion>,
    pub channel_mix: Option<ChannelMix>,
    pub low_pass: Option<LowPass>,
    pub plugin_filters: Option<Value>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Tremolo {
    pub frequency: Option<f64>,
    pub depth: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Vibrato {
    pub frequency: Option<f64>,
    pub depth: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Timescale {
    pub speed: Option<f64>,
    pub pitch: Option<f64>,
    pub rate: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Rotation {
    pub rotation_hz: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LowPass {
    pub smoothing: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Karaoke {
    pub level: Option<f64>,
    pub mono_level: Option<f64>,
    pub filter_band: Option<f64>,
    pub filter_width: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Equalizer {
    pub band: u16,
    pub gain: f64,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Distortion {
    pub sin_offset: Option<f64>,
    pub sin_scale: Option<f64>,
    pub cos_offset: Option<f64>,
    pub cos_scale: Option<f64>,
    pub tan_offset: Option<f64>,
    pub tan_scale: Option<f64>,
    pub offset: Option<f64>,
    pub scale: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChannelMix {
    pub left_to_left: Option<f64>,
    pub left_to_right: Option<f64>,
    pub right_to_left: Option<f64>,
    pub right_to_right: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LavalinkVoice {
    pub token: String,
    pub endpoint: String,
    pub session_id: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub connected: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub ping: Option<i32>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct LavalinkPlayerState {
    pub time: u64,
    pub position: u32,
    pub connected: bool,
    pub ping: Option<i32>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LavalinkPlayer {
    #[serde(deserialize_with = "str_to_u64")]
    pub guild_id: u64,
    pub track: Option<Track>,
    pub volume: u32,
    pub paused: bool,
    pub state: LavalinkPlayerState,
    pub voice: LavalinkVoice,
    pub filters: LavalinkFilters,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TrackInfo {
    pub identifier: String,
    pub is_seekable: bool,
    pub author: String,
    pub length: usize,
    pub is_stream: bool,
    pub position: usize,
    pub title: String,
    pub uri: Option<String>,
    pub artwork_url: Option<String>,
    pub isrc: Option<String>,
    pub source_name: String,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Track {
    pub encoded: String,
    pub info: TrackInfo,
    pub plugin_info: Value,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Exception {
    #[serde(deserialize_with = "str_to_u64")]
    pub guild_id: u64,
    pub message: Option<String>,
    pub severity: String,
    pub cause: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TrackStart {
    #[serde(deserialize_with = "str_to_u64")]
    pub guild_id: u64,
    pub track: Track,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TrackEnd {
    #[serde(deserialize_with = "str_to_u64")]
    pub guild_id: u64,
    pub track: Track,
    pub reason: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TrackException {
    #[serde(deserialize_with = "str_to_u64")]
    pub guild_id: u64,
    pub track: Track,
    pub exception: Exception,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TrackStuck {
    #[serde(deserialize_with = "str_to_u64")]
    pub guild_id: u64,
    pub track: Track,
    pub threshold_ms: usize,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WebSocketClosed {
    #[serde(deserialize_with = "str_to_u64")]
    pub guild_id: u64,
    pub code: usize,
    pub reason: String,
    pub by_remote: bool,
}

#[allow(clippy::enum_variant_names)]
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum PlayerEvents {
    TrackStartEvent(TrackStart),
    TrackEndEvent(TrackEnd),
    TrackExceptionEvent(TrackException),
    TrackStuckEvent(TrackStuck),
    WebSocketClosedEvent(WebSocketClosed),
}

#[derive(Default, Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UpdatePlayerTrack {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub encoded: Option<Value>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub identifier: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user_data: Option<Value>,
}

#[derive(Default, Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LavalinkPlayerOptions {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub track: Option<UpdatePlayerTrack>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub identifier: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub position: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub end_time: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub volume: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub paused: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub filters: Option<LavalinkFilters>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub voice: Option<LavalinkVoice>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum EventType {
    Player(Box<PlayerEvents>),
    Destroyed,
}

impl LavalinkFilters {
    pub fn merge(&mut self, other: LavalinkFilters) {
        self.volume = other.volume.or(self.volume);
        self.equalizer = other.equalizer.or(self.equalizer.clone());
        self.karaoke = other.karaoke.or(self.karaoke.clone());
        self.timescale = other.timescale.or(self.timescale.clone());
        self.tremolo = other.tremolo.or(self.tremolo.clone());
        self.vibrato = other.vibrato.or(self.vibrato.clone());
        self.rotation = other.rotation.or(self.rotation.clone());
        self.distortion = other.distortion.or(self.distortion.clone());
        self.channel_mix = other.channel_mix.or(self.channel_mix.clone());
        self.low_pass = other.low_pass.or(self.low_pass.clone());
        self.plugin_filters = other.plugin_filters.or(self.plugin_filters.clone());
    }
}