partymode 0.2.1

Keeps your system awake while playing media
Documentation
use crate::daemon::State;
use serde::{Deserialize, Serialize};
use zbus::zvariant::Type;
use zbus::{
    Connection, Result, interface, proxy,
    zvariant::{OwnedFd, OwnedValue},
};

#[proxy(
    interface = "org.freedesktop.DBus",
    default_service = "org.freedesktop.DBus",
    default_path = "/"
)]
pub trait DBus {
    fn list_names(&self) -> Result<Vec<String>>;
}

pub mod mpris {
    use super::*;

    #[derive(OwnedValue)]
    #[zvariant(signature = "s")]
    pub enum PlaybackStatus {
        Playing,
        Paused,
        Stopped,
    }

    #[proxy(
        interface = "org.mpris.MediaPlayer2",
        default_path = "/org/mpris/MediaPlayer2"
    )]
    pub trait MediaPlayer2 {
        #[zbus(property)]
        fn identity(&self) -> Result<String>;
    }

    #[proxy(
        interface = "org.mpris.MediaPlayer2.Player",
        default_path = "/org/mpris/MediaPlayer2"
    )]
    pub trait MediaPlayer2Player {
        #[zbus(property)]
        fn playback_status(&self) -> Result<PlaybackStatus>;
    }

    pub struct Player<'a> {
        iface_base: MediaPlayer2Proxy<'a>,
        iface_player: MediaPlayer2PlayerProxy<'a>,
        name: String,
    }

    impl Player<'_> {
        #[allow(dead_code)]
        pub async fn identity(&self) -> Result<String> {
            self.iface_base.identity().await
        }
        pub async fn playback_status(&self) -> Result<PlaybackStatus> {
            self.iface_player.playback_status().await
        }
        pub fn name(&self) -> &str {
            &self.name
        }
    }

    pub async fn find_players<'a>(connection: &'a Connection) -> Result<Vec<Player<'a>>> {
        let dbus_proxy = DBusProxy::new(connection).await?;
        let names = dbus_proxy.list_names().await?;
        let mut players = vec![];
        for name in names
            .into_iter()
            .filter(|name| name.starts_with("org.mpris.MediaPlayer2."))
        {
            let iface_base = MediaPlayer2Proxy::builder(connection)
                .destination(name.clone())?
                .build()
                .await?;

            let iface_player = MediaPlayer2PlayerProxy::builder(connection)
                .destination(name.clone())?
                .build()
                .await?;

            players.push(Player {
                name,
                iface_base,
                iface_player,
            })
        }

        Ok(players)
    }
}

pub mod logind {
    use super::*;

    #[proxy(
        interface = "org.freedesktop.login1.Manager",
        default_service = "org.freedesktop.login1",
        default_path = "/org/freedesktop/login1"
    )]
    pub trait LoginManager {
        fn inhibit(&self, what: &str, who: &str, why: &str, mode: &str) -> Result<OwnedFd>;
    }
}

pub mod partymode {

    use super::*;

    pub struct Partymode {
        state: State,
    }
    impl Partymode {
        pub fn new(state: State) -> Partymode {
            Partymode { state }
        }
    }

    #[derive(Type, Serialize, Deserialize)]
    pub struct DaemonStatus {
        pub partymode: bool,
    }

    #[interface(
        name = "dev.peppidesu.partymode",
        proxy(
            gen_blocking = false,
            default_path = "/dev/peppidesu/partymode",
            default_service = "dev.peppidesu.partymode",
        )
    )]
    impl Partymode {
        async fn status(&self) -> DaemonStatus {
            DaemonStatus {
                partymode: self
                    .state
                    .partymode
                    .load(std::sync::atomic::Ordering::SeqCst),
            }
        }

        async fn set(&self, enabled: bool) {
            self.state
                .partymode
                .store(enabled, std::sync::atomic::Ordering::SeqCst);
        }

        async fn toggle(&self) {
            let enabled = self
                .state
                .partymode
                .load(std::sync::atomic::Ordering::SeqCst);

            self.state
                .partymode
                .store(!enabled, std::sync::atomic::Ordering::SeqCst);
        }
    }
}