config: Add calloop feature to provide a calloop source (#102)

This should be useful for integrating cosmic-config into things using
calloop, like cosmic-comp.
This commit is contained in:
Ian Douglas Scott 2023-05-09 08:45:21 -07:00 committed by GitHub
parent b85c504d72
commit 355e5a9715
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 0 deletions

View file

@ -5,6 +5,7 @@ edition = "2021"
[dependencies]
atomicwrites = "0.4.0"
calloop = { version = "0.10.5", optional = true }
dirs = "4.0.0"
notify = "5.1.0"
ron = "0.8.0"

View file

@ -0,0 +1,63 @@
// TODO If possible, calloop could poll inotify/kqueue without a thread
use calloop::channel;
use crate::{Config, Error};
pub struct ConfigWatchSource {
channel: channel::Channel<(Config, Vec<String>)>,
_watcher: notify::RecommendedWatcher,
}
impl ConfigWatchSource {
pub fn new(config: &Config) -> Result<Self, Error> {
let (sender, channel) = channel::sync_channel(32);
let _watcher = config.watch(move |config, keys| {
let _ = sender.send((config.clone(), keys.to_owned()));
})?;
Ok(Self { channel, _watcher })
}
}
impl calloop::EventSource for ConfigWatchSource {
type Event = (Config, Vec<String>);
type Metadata = ();
type Ret = ();
type Error = calloop::channel::ChannelError;
fn process_events<F>(
&mut self,
readiness: calloop::Readiness,
token: calloop::Token,
mut cb: F,
) -> Result<calloop::PostAction, Self::Error>
where
F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
{
self.channel
.process_events(readiness, token, |event, ()| match event {
calloop::channel::Event::Msg(msg) => cb(msg, &mut ()),
calloop::channel::Event::Closed => {}
})
}
fn register(
&mut self,
poll: &mut calloop::Poll,
token_factory: &mut calloop::TokenFactory,
) -> Result<(), calloop::Error> {
self.channel.register(poll, token_factory)
}
fn reregister(
&mut self,
poll: &mut calloop::Poll,
token_factory: &mut calloop::TokenFactory,
) -> Result<(), calloop::Error> {
self.channel.reregister(poll, token_factory)
}
fn unregister(&mut self, poll: &mut calloop::Poll) -> Result<(), calloop::Error> {
self.channel.unregister(poll)
}
}

View file

@ -7,6 +7,9 @@ use std::{
sync::Mutex,
};
#[cfg(feature = "calloop")]
pub mod calloop;
#[derive(Debug)]
pub enum Error {
AtomicWrites(atomicwrites::Error<std::io::Error>),