Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Ian Douglas Scott
5c5460e93c WIP: config: Type safe API prototype
If we represent settings with types, we can provide an api to
get/set/monitor settings that guarantees we can only access settings
that exist with the right types, without seperate getter/setter/callback
functions like GTK would use.
2023-07-05 16:45:16 -07:00
3 changed files with 65 additions and 0 deletions

View file

@ -0,0 +1,27 @@
use cosmic_config::setting::{App, Setting, AppConfig};
struct ExampleApp;
impl App for ExampleApp {
const ID: &'static str = "com.Example.App";
const VERSION: u64 = 1;
}
struct DoFoo;
impl Setting<ExampleApp> for DoFoo {
const NAME: &'static str = "do-foo";
type Type = bool;
}
struct WhatBar;
impl Setting<ExampleApp> for WhatBar {
const NAME: &'static str = "what-bar";
type Type = String;
}
fn main() {
let config = AppConfig::<ExampleApp>::new().unwrap();
config.set::<DoFoo>(true).unwrap();
}

View file

@ -22,6 +22,8 @@ pub use cosmic_config_derive;
#[cfg(feature = "calloop")]
pub mod calloop;
pub mod setting;
#[derive(Debug)]
pub enum Error {
AtomicWrites(atomicwrites::Error<std::io::Error>),

View file

@ -0,0 +1,36 @@
use crate::{Config, ConfigGet, ConfigSet, Error};
pub trait App {
const ID: &'static str;
// XXX how to handle versioning?
const VERSION: u64;
}
pub trait Setting<A: App> {
const NAME: &'static str;
// TODO can't use &str to set? Need to serialize owned value.
type Type: serde::Serialize + serde::de::DeserializeOwned;
}
pub struct AppConfig<A: App> {
config: Config,
_app: std::marker::PhantomData<A>,
}
impl<A: App> AppConfig<A> {
pub fn new() -> Result<Self, Error> {
Ok(Self {
config: Config::new(A::ID, A::VERSION)?,
_app: std::marker::PhantomData,
})
}
// XXX default value, if none set?
pub fn get<S: Setting<A>>(&self) -> Result<S::Type, Error> {
self.config.get(S::NAME)
}
pub fn set<S: Setting<A>>(&self, value: S::Type) -> Result<(), Error> {
self.config.set(S::NAME, value)
}
}