diff --git a/src/Rust/Cargo.lock b/src/Rust/Cargo.lock
index 062d7f62671251913aad66b659d0ebda110426fe..79912599051150568032984aec0e5c18cda8bf13 100644
--- a/src/Rust/Cargo.lock
+++ b/src/Rust/Cargo.lock
@@ -118,6 +118,15 @@ version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
 
+[[package]]
+name = "borsh"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed"
+dependencies = [
+ "cfg_aliases",
+]
+
 [[package]]
 name = "bstr"
 version = "1.10.0"
@@ -160,16 +169,16 @@ dependencies = [
  "quote",
  "serde",
  "serde_json",
- "syn 2.0.75",
+ "syn 2.0.77",
  "tempfile",
  "toml",
 ]
 
 [[package]]
 name = "cc"
-version = "1.1.13"
+version = "1.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
+checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b"
 dependencies = [
  "shlex",
 ]
@@ -180,6 +189,12 @@ version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
+[[package]]
+name = "cfg_aliases"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+
 [[package]]
 name = "ciborium"
 version = "0.2.2"
@@ -209,9 +224,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.16"
+version = "4.5.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019"
+checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -219,9 +234,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.15"
+version = "4.5.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
+checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73"
 dependencies = [
  "anstream",
  "anstyle",
@@ -232,9 +247,9 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.20"
+version = "4.5.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2aedc27e53da9ff495f5da6f4325390e71f46f886022b618303042e8ccf4bcac"
+checksum = "18d7f143a7e709cbe6c34853dcd3bb1370c7e1bb4d9e7310ca8cb40b490ae035"
 dependencies = [
  "clap",
 ]
@@ -248,7 +263,7 @@ dependencies = [
  "heck 0.5.0",
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -398,7 +413,7 @@ dependencies = [
  "convert_case",
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
  "unicode-xid",
 ]
 
@@ -432,9 +447,9 @@ dependencies = [
 
 [[package]]
 name = "fastrand"
-version = "2.1.0"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
 
 [[package]]
 name = "globset"
@@ -489,9 +504,9 @@ checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
 
 [[package]]
 name = "indexmap"
-version = "2.4.0"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
+checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -678,9 +693,9 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.36"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
 dependencies = [
  "proc-macro2",
 ]
@@ -748,9 +763,9 @@ checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3"
 
 [[package]]
 name = "rustix"
-version = "0.38.34"
+version = "0.38.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f"
 dependencies = [
  "bitflags",
  "errno",
@@ -782,29 +797,29 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
 
 [[package]]
 name = "serde"
-version = "1.0.208"
+version = "1.0.209"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
+checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.208"
+version = "1.0.209"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
+checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.125"
+version = "1.0.128"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed"
+checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
 dependencies = [
  "indexmap",
  "itoa",
@@ -836,10 +851,11 @@ checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e"
 
 [[package]]
 name = "smol_str"
-version = "0.2.2"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
+checksum = "66eaf762c5af19db3108300515c8aa7a50efc90ff745f4c62288052ebf9fdd25"
 dependencies = [
+ "borsh",
  "serde",
 ]
 
@@ -862,9 +878,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.75"
+version = "2.0.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
+checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -920,7 +936,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -1148,7 +1164,7 @@ dependencies = [
  "anyhow",
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -1204,9 +1220,7 @@ dependencies = [
 name = "vvs_xdg"
 version = "0.5.0"
 dependencies = [
- "anyhow",
  "log",
- "serde",
  "thiserror",
  "vvs_utils",
 ]
@@ -1243,7 +1257,7 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
  "wasm-bindgen-shared",
 ]
 
@@ -1265,7 +1279,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -1469,5 +1483,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
diff --git a/src/Rust/vvs_cli/src/config.rs b/src/Rust/vvs_cli/src/config.rs
index 5e51a9b215dc7e318907c40922bfdb19a660240d..25772ae6c976df7ded339d3161dccaa2ded71c4c 100644
--- a/src/Rust/vvs_cli/src/config.rs
+++ b/src/Rust/vvs_cli/src/config.rs
@@ -2,7 +2,6 @@ use crate::args::Args;
 use clap_complete::Shell;
 use serde::{Deserialize, Serialize};
 use std::path::PathBuf;
-use thiserror::Error;
 use vvs_utils::*;
 use vvs_xdg::XDGConfigFileSerde;
 
@@ -40,7 +39,7 @@ pub struct Config {
     pub includes: Vec<PathBuf>,
 }
 
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum ConfigFileError {
     #[error("deserialization error: {0}")]
     Deserialize(toml::de::Error),
diff --git a/src/Rust/vvs_cli/src/main.rs b/src/Rust/vvs_cli/src/main.rs
index 5c723d6b164f2a26e881aa98dba1c9bbb34febc2..6898acb3c307f83cd855f24b3962c25347ccc97a 100644
--- a/src/Rust/vvs_cli/src/main.rs
+++ b/src/Rust/vvs_cli/src/main.rs
@@ -9,13 +9,13 @@ use vvs_cli::{
     args::Args,
     config::{Config, ConfigFile},
 };
-use vvs_lang::*;
+use vvs_lang::{FrontendPipeline, SearchPath, SourceCode};
 use vvs_runtime::Runtime;
 use vvs_xdg::{file::TempFile, XDGConfig, XDGConfigMergedSilent};
 
 fn print_font(n: impl AsRef<Path>, f: &[u8]) -> Result<()> {
     let f = vvs_font::Font::try_from(f).with_context(|| format!("failed to parse font {}", n.as_ref().display()))?;
-    let ts = Vec::from_iter(f.font_types().into_iter().map(|ty| ty.to_string()));
+    let ts = Vec::from_iter(f.font_types().into_iter().map(Into::<String>::into));
     println!("###");
     println!("# Family Name:        {}", f.name().context("failed to get the font name")?);
     println!("# Name(s):            {}", f.family_names().join(", "));
@@ -62,10 +62,8 @@ fn main() -> Result<()> {
             &SearchPath::from_iter(includes)
                 .with_script_folder(script.parent().context("expected the script to have a parent folder")?),
         )
-        .options(options.as_ref())
-        .context("failed to parse option file")?
-        .run()
-        .context("failed to parse script files")?;
+        .options(options.as_ref())?
+        .run()?;
 
     if info {
         match ass_file {
diff --git a/src/Rust/vvs_font/src/font.rs b/src/Rust/vvs_font/src/font.rs
index 996ab5ed999cd9d220fd44a74e0f96b834f6e04d..fe18a2ee8277b54d5b589a6b463a7e2d4cb67cba 100644
--- a/src/Rust/vvs_font/src/font.rs
+++ b/src/Rust/vvs_font/src/font.rs
@@ -16,6 +16,12 @@ pub enum FontType {
     #[display("variable")]   Variable,
 }
 
+impl From<FontType> for String {
+    fn from(value: FontType) -> Self {
+        value.to_string()
+    }
+}
+
 /// Struct used to store informations we need about a font.
 #[derive(Debug)]
 pub struct Font<'a> {
diff --git a/src/Rust/vvs_xdg/Cargo.toml b/src/Rust/vvs_xdg/Cargo.toml
index 4389a7c498fb87731fdf1bde21f557f538eac42b..4063b04dc630548a7c7d87de6ed67e2b4ed6adb7 100644
--- a/src/Rust/vvs_xdg/Cargo.toml
+++ b/src/Rust/vvs_xdg/Cargo.toml
@@ -9,6 +9,4 @@ license.workspace = true
 [dependencies]
 vvs_utils.workspace = true
 thiserror.workspace = true
-anyhow.workspace    = true
-serde.workspace     = true
 log.workspace       = true
diff --git a/src/Rust/vvs_xdg/src/config.rs b/src/Rust/vvs_xdg/src/config.rs
index b48c6f60fd4f138b2c77ff448f2d1d01bc6a4e1c..c165222158b7227363055f4148b7e86870ca5fe2 100644
--- a/src/Rust/vvs_xdg/src/config.rs
+++ b/src/Rust/vvs_xdg/src/config.rs
@@ -6,17 +6,20 @@ use std::{fs, marker};
 
 /// Search configurations in all config folders and merge them.
 #[derive(Debug)]
+#[non_exhaustive]
 pub struct XDGConfigMerged;
 
 /// Only get the config file with higher priority, which means searching in order:
 /// 1. $XDG_CONFIG_HOME <- which has a default value.
 /// 2. $XDG_CONFIG_DIRS <- which has a default value.
 #[derive(Debug)]
+#[non_exhaustive]
 pub struct XDGConfigFirst;
 
 /// Search configurations in all config folders and merge them. If the parsing for a configuration
 /// file failed then log it and continue execution like normal, i.e. fail silently.
 #[derive(Debug)]
+#[non_exhaustive]
 pub struct XDGConfigMergedSilent;
 
 /// We will write one impl block for merged searches.
@@ -31,10 +34,12 @@ mod private_merged {
     impl Sealed for XDGConfigMergedSilent {
         fn try_read<Format: XDGConfigFileSerde>(config: &XDGConfig<Format, Self>) -> Result<Format, XDGError> {
             let mut result = config.search_files()?.into_iter().filter_map(|file| {
-                let file = Result::ok(fs::read_to_string(file)
-                    .map_err(|err| log::error!(target: "xdg", "{}", XDGError::ConfigIO(config.app.to_string(), config.get_file().to_string(), err))))?;
-                Result::ok(Format::deserialize(&file)
-                    .map_err(|e| log::error!(target: "xdg", "deserialize error for {} on file {}: {e}", config.app, config.get_file())))
+                let file = fs::read_to_string(file)
+                    .map_err(|e| log::error!(target: "xdg", "{}", XDGError::ConfigIO(config.app.to_string(), config.get_file().to_string(), e)))
+                    .ok()?;
+                Format::deserialize(&file)
+                    .map_err(|e| log::error!(target: "xdg", "deserialize error for {} on file {}: {e}", config.app, config.get_file()))
+                    .ok()
             });
 
             let mut first = result
@@ -50,12 +55,12 @@ mod private_merged {
             let mut result = Iterator::collect::<Result<Vec<_>, _>>(config.search_files()?.into_iter().map(|file| {
                 let file = fs::read_to_string(file)
                     .map_err(|err| XDGError::ConfigIO(config.app.to_string(), config.get_file().to_string(), err))?;
-                let file = Format::deserialize(&file).map_err(|err| {
+                Format::deserialize(&file).map_err(|err| {
                     log::error!(target: "xdg", "deserialize error for application {} on file {}: {err}", config.app, config.get_file());
                     XDGError::DeserializeError(config.app.to_string(), config.get_file().to_string())
-                })?;
-                Ok(file)
+                })
             }))?.into_iter();
+
             let mut first = result
                 .next()
                 .ok_or_else(|| XDGError::ConfigNotFound(config.app.to_string(), config.get_file().to_string()))?;
@@ -63,6 +68,22 @@ mod private_merged {
             Ok(first)
         }
     }
+
+    impl Sealed for XDGConfigFirst {
+        fn try_read<Format: XDGConfigFileSerde>(config: &XDGConfig<Format, Self>) -> Result<Format, XDGError> {
+            let file = config
+                .search_files()?
+                .into_first()
+                .ok_or_else(|| XDGError::ConfigNotFound(config.app.to_string(), config.get_file().to_string()))?;
+            let file = fs::read_to_string(file)
+                .map_err(|err| XDGError::ConfigIO(config.app.to_string(), config.get_file().to_string(), err))?;
+            Format::deserialize(&file)
+            .map_err(|err| {
+                log::error!(target: "xdg", "deserialize error on application {} on file {}: {err}", config.app, config.get_file());
+                XDGError::DeserializeError(config.app.to_string(), config.get_file().to_string())
+            })
+        }
+    }
 }
 
 /// A struct to contain informations about the app we are querying the config for. The behaviour of
@@ -81,7 +102,7 @@ mod private_merged {
 ///   then all the found files are parsed and then merged, an error is returned on the first
 ///   failure of the deserialization process.
 #[derive(Debug)]
-pub struct XDGConfig<'a, Format: XDGConfigFileSerde, Merged> {
+pub struct XDGConfig<'a, Format: XDGConfigFileSerde, Merged: private_merged::Sealed> {
     /// The application name.
     app: &'a str,
 
@@ -95,7 +116,7 @@ pub struct XDGConfig<'a, Format: XDGConfigFileSerde, Merged> {
     _merged: marker::PhantomData<Merged>,
 }
 
-impl<'a, Format: XDGConfigFileSerde, Merged> XDGConfig<'a, Format, Merged> {
+impl<'a, Format: XDGConfigFileSerde, Merged: private_merged::Sealed> XDGConfig<'a, Format, Merged> {
     /// By default we say that the default config file is ${FOLDER}/${APP}/config like many
     /// applications do.
     const DEFAULT_FILE: &'static str = "config";
@@ -103,14 +124,13 @@ impl<'a, Format: XDGConfigFileSerde, Merged> XDGConfig<'a, Format, Merged> {
     /// Create a new [XDGConfig] helper.
     #[inline]
     pub fn new(app: &'a str) -> Self {
-        Self { app, file: Default::default(), _type: Default::default(), _merged: Default::default() }
+        Self { app, file: Default::default(), _type: marker::PhantomData, _merged: marker::PhantomData }
     }
 
     /// Change the file to resolve.
     #[inline]
-    pub fn file(&mut self, file: &'a str) -> &mut Self {
-        self.file = Some(file);
-        self
+    pub fn file(self, file: &'a str) -> Self {
+        Self { file: Some(file), ..self }
     }
 
     /// Get the name of the config file that we will try to read. Returns the default if not set by
@@ -134,102 +154,7 @@ impl<'a, Format: XDGConfigFileSerde, Merged> XDGConfig<'a, Format, Merged> {
     pub fn prepare_folder(&self) -> impl IntoIterator<Item = <MaybeFolderList as IntoIterator>::Item> {
         XDGFolder::ConfigDirs.prepare_folder()
     }
-}
-
-impl<'a, Format: XDGConfigFileSerde> XDGConfig<'a, Format, XDGConfigFirst> {
-    /// Try to read the config file and deserialize it.
-    pub fn try_read(&self) -> Result<Format, XDGError> {
-        let Some(file) = self.search_files()?.into_first() else {
-            return Err(XDGError::ConfigNotFound(self.app.to_string(), self.get_file().to_string()));
-        };
-        let file = fs::read_to_string(file)
-            .map_err(|err| XDGError::ConfigIO(self.app.to_string(), self.get_file().to_string(), err))?;
-        Format::deserialize(&file)
-            .map_err(|err| {
-                log::error!(target: "xdg", "deserialize error on application {} on file {}: {err}", self.app, self.get_file());
-                XDGError::DeserializeError(self.app.to_string(), self.get_file().to_string())
-            })
-    }
-}
-
-impl<'a, Format: XDGConfigFileSerde> XDGConfig<'a, Format, XDGConfigFirst> {
-    /// Try to read the config file and deserialize it. If an error is encountred at any point, log
-    /// it and return the provided default. If needed the default value is written on the disk,
-    /// note that this operation may fail silently.
-    #[inline]
-    pub fn read_or(&self, default: Format) -> Format {
-        self.try_read().unwrap_or_else(|err| {
-            log::error!(target: "xdg", "read error, return default value to user: {err}");
-            self.write_silent(default)
-        })
-    }
-
-    /// Try to read the config file and deserialize it. If an error is encountred at any point, log
-    /// it and return the provided default. If needed the default value is written on the disk,
-    /// note that this operation may fail silently.
-    #[inline]
-    pub fn read_or_else(&self, cb: impl FnOnce() -> Format) -> Format {
-        self.try_read().unwrap_or_else(|err| {
-            log::error!(target: "xdg", "read error, return default value to user: {err}");
-            self.write_silent(cb())
-        })
-    }
-
-    /// Write a value to the default config file location, the one with the higher priority
-    /// (usually the user's one)
-    fn write(&self, value: &Format) -> Result<(), XDGError> {
-        let content = Format::serialize(value)
-            .map_err(|err| {
-                log::error!(target: "xdg", "serialize error for application {} on file {}: {err}", self.app, self.get_file());
-                XDGError::SerializeError(self.app.to_string(), self.get_file().to_string())
-            })?;
-
-        let path = XDGFolder::ConfigDirs
-            .find(self.app, self.get_file(), XDGFindBehaviour::FirstOrCreate)?
-            .into_first()
-            .expect("the user must have at least one location to place a config file, permission or fs quota problem?");
-
-        match fs::create_dir_all(
-            path.parent()
-                .ok_or(XDGError::ConfigFileHasNoParentFolder(self.app.to_string(), self.get_file().to_string()))?,
-        ) {
-            Err(err) if !matches!(err.kind(), std::io::ErrorKind::AlreadyExists) => {
-                return Err(XDGError::ConfigIO(self.app.to_string(), self.get_file().to_string(), err))
-            }
-            _ => {}
-        }
-
-        fs::write(path, content)
-            .map_err(|err| XDGError::ConfigIO(self.app.to_string(), self.get_file().to_string(), err))
-    }
-
-    /// Same as [XDGConfig::write] but log any error and fail silently, returning the value that
-    /// was attempted to be written to disk.
-    #[inline]
-    fn write_silent(&self, value: Format) -> Format {
-        if let Err(err) = self.write(&value) {
-            log::error!(target: "xdg", "failed to write default with err: {err}")
-        }
-        value
-    }
-}
 
-impl<'a, Format: XDGConfigFileSerde + Default> XDGConfig<'a, Format, XDGConfigFirst> {
-    /// Try to read the config file and deserialize it. If an error is encountred at any point, log
-    /// it and return the default. If needed the default value is written on the disk, note that
-    /// this operation may fail silently.
-    #[inline]
-    pub fn read_or_default(&self) -> Format {
-        self.try_read().unwrap_or_else(|err| {
-            log::error!(target: "xdg", "read error, return default value to user: {err}");
-            self.write_silent(Default::default())
-        })
-    }
-}
-
-// XDGConfigMerged + XDGConfigMergedSilent
-
-impl<'a, Format: XDGConfigFileSerde, Merged: private_merged::Sealed> XDGConfig<'a, Format, Merged> {
     /// When trying to read or write the default, we write the file with the same logic as the
     /// [XDGConfigFirst] variant, we add this function to reduce the code to write for the write
     /// logic...
@@ -248,9 +173,7 @@ impl<'a, Format: XDGConfigFileSerde, Merged: private_merged::Sealed> XDGConfig<'
     pub fn try_read(&self) -> Result<Format, XDGError> {
         Merged::try_read(self)
     }
-}
 
-impl<'a, Format: XDGConfigFileSerde, Merged: private_merged::Sealed> XDGConfig<'a, Format, Merged> {
     /// Try to read the config files and deserialize them. If an error is encountred at any point,
     /// log it and return the provided default if the merge was not silent, skip the file if it was
     /// silent. If needed the default value is written on the disk, note that this operation may
@@ -289,3 +212,43 @@ impl<'a, Format: XDGConfigFileSerde + Default, Merged: private_merged::Sealed> X
         })
     }
 }
+
+impl<'a, Format: XDGConfigFileSerde> XDGConfig<'a, Format, XDGConfigFirst> {
+    /// Write a value to the default config file location, the one with the higher priority
+    /// (usually the user's one)
+    fn write(&self, value: &Format) -> Result<(), XDGError> {
+        let content = Format::serialize(value)
+            .map_err(|err| {
+                log::error!(target: "xdg", "serialize error for application {} on file {}: {err}", self.app, self.get_file());
+                XDGError::SerializeError(self.app.to_string(), self.get_file().to_string())
+            })?;
+
+        let path = XDGFolder::ConfigDirs
+            .find(self.app, self.get_file(), XDGFindBehaviour::FirstOrCreate)?
+            .into_first()
+            .expect("the user must have at least one location to place a config file, permission or fs quota problem?");
+
+        match fs::create_dir_all(
+            path.parent()
+                .ok_or(XDGError::ConfigFileHasNoParentFolder(self.app.to_string(), self.get_file().to_string()))?,
+        ) {
+            Err(err) if !matches!(err.kind(), std::io::ErrorKind::AlreadyExists) => {
+                return Err(XDGError::ConfigIO(self.app.to_string(), self.get_file().to_string(), err))
+            }
+            _ => {}
+        }
+
+        fs::write(path, content)
+            .map_err(|err| XDGError::ConfigIO(self.app.to_string(), self.get_file().to_string(), err))
+    }
+
+    /// Same as [XDGConfig::write] but log any error and fail silently, returning the value that
+    /// was attempted to be written to disk.
+    #[inline]
+    fn write_silent(&self, value: Format) -> Format {
+        if let Err(err) = self.write(&value) {
+            log::error!(target: "xdg", "failed to write default with err: {err}")
+        }
+        value
+    }
+}
diff --git a/src/Rust/vvs_xdg/src/file/lock.rs b/src/Rust/vvs_xdg/src/file/lock.rs
index 54f80997df672b237845c0cb114d35dda4539b6b..992adb65c43e699e1625332630ded232ec566e86 100644
--- a/src/Rust/vvs_xdg/src/file/lock.rs
+++ b/src/Rust/vvs_xdg/src/file/lock.rs
@@ -3,16 +3,15 @@ use std::{
     collections::hash_map::DefaultHasher,
     fs,
     hash::{Hash, Hasher},
-    io::Error as IoError,
+    io::{Error as IoError, ErrorKind as IoErrorKind},
     path::Path,
 };
-use thiserror::Error;
 
 /// An error can be comming from the IO thing or the resource could be already locked.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum LockError {
     #[error("{0}")]
-    IO(std::io::Error),
+    IO(#[from] IoError),
 
     #[error("resource is already locked")]
     AlreadyLocked,
@@ -41,7 +40,7 @@ impl LockFile {
     #[inline]
     fn handle_io_error(err: IoError) -> LockError {
         match err.kind() {
-            std::io::ErrorKind::AlreadyExists => LockError::AlreadyLocked,
+            IoErrorKind::AlreadyExists => LockError::AlreadyLocked,
             _ => LockError::IO(err),
         }
     }
diff --git a/src/Rust/vvs_xdg/src/file/temp.rs b/src/Rust/vvs_xdg/src/file/temp.rs
index 514d496f46fe1ed276620defc0cd6b9bc3d56426..3481602447d8604596b53e199482b4f165a3884d 100644
--- a/src/Rust/vvs_xdg/src/file/temp.rs
+++ b/src/Rust/vvs_xdg/src/file/temp.rs
@@ -1,18 +1,17 @@
 use crate::*;
 use std::{
     fs::{self, File, OpenOptions},
-    io::Error as IoError,
+    io::{Error as IoError, ErrorKind as IoErrorKind},
     ops::{Deref, DerefMut},
     path::{Path, PathBuf},
 };
-use thiserror::Error;
 use vvs_utils::rand;
 
 /// An error can be comming from the IO thing or we have a collision with the temp file name.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum TempError {
     #[error("{0}")]
-    IO(#[from] std::io::Error),
+    IO(#[from] IoError),
 
     #[error("generated a duplicate temporary file")]
     Duplicate,
@@ -74,7 +73,7 @@ impl TempFile {
     #[inline]
     fn handle_io_error(err: IoError) -> TempError {
         match err.kind() {
-            std::io::ErrorKind::AlreadyExists => TempError::Duplicate,
+            IoErrorKind::AlreadyExists => TempError::Duplicate,
             _ => TempError::IO(err),
         }
     }
@@ -93,7 +92,7 @@ impl TempFile {
 
     #[cfg(not(unix))]
     fn create(app: impl AsRef<str>, file: impl AsRef<str>) -> TempResult<PathBuf> {
-        use std::{env, io::ErrorKind as IoErrorKind};
+        use std::env;
         let folder = env::var("TEMP")
             .map(PathBuf::from)
             .or_else(|_| {
diff --git a/src/Rust/vvs_xdg/src/folders.rs b/src/Rust/vvs_xdg/src/folders.rs
index 4f7364b9d77b92d0469c402e0bd48217590b412b..e3afb9b2a8a8ae65c095ddaf83b382f306e4410e 100644
--- a/src/Rust/vvs_xdg/src/folders.rs
+++ b/src/Rust/vvs_xdg/src/folders.rs
@@ -125,18 +125,17 @@ impl XDGFolder {
             }
         }
 
-        let home = crate::home_folder();
         match std::env::var(self.env_var_name()) {
             Ok(folder_list) if self.is_list() => MaybeFolderList::from_str_list(&folder_list, Self::SEPARATOR),
             Ok(folder) => MaybeFolderList::Folder(PathBuf::from(folder)),
             Err(_) => match self {
-                XDGFolder::DataHome => MaybeFolderList::Folder(home.join(".local/share")),
-                XDGFolder::ConfigHome => MaybeFolderList::Folder(home.join(".config")),
-                XDGFolder::StateHome => MaybeFolderList::Folder(home.join(".local/state")),
-                XDGFolder::CacheHome => MaybeFolderList::Folder(home.join(".cache")),
+                XDGFolder::DataHome => MaybeFolderList::Folder(crate::home_folder().join(".local/share")),
+                XDGFolder::ConfigHome => MaybeFolderList::Folder(crate::home_folder().join(".config")),
+                XDGFolder::StateHome => MaybeFolderList::Folder(crate::home_folder().join(".local/state")),
+                XDGFolder::CacheHome => MaybeFolderList::Folder(crate::home_folder().join(".cache")),
                 XDGFolder::RuntimeDir => panic!("failed to find the env variable $XDG_RUNTIME_DIR"),
-                XDGFolder::DataDirs => variables::data_dirs(&home),
-                XDGFolder::ConfigDirs => variables::config_dirs(&home),
+                XDGFolder::DataDirs => variables::data_dirs(crate::home_folder()),
+                XDGFolder::ConfigDirs => variables::config_dirs(crate::home_folder()),
             },
         }
     }
@@ -144,15 +143,12 @@ impl XDGFolder {
     /// Get the folders list of what you asked for, but try to create them and only return existing
     /// ones. The thing returned is a thing that can be iterate over to facilitate chaining.
     pub fn prepare_folder(&self) -> impl IntoIterator<Item = <MaybeFolderList as IntoIterator>::Item> {
-        self.get_folder().into_iter().filter_map(|folder| {
-            if folder.is_dir() {
-                Some(folder)
-            } else {
-                std::fs::create_dir_all(&folder)
-                    .map(|()| folder)
-                    .map_err(|err| log::error!(target: "xdg", "{err}"))
-                    .ok()
-            }
+        self.get_folder().into_iter().filter_map(|dir| match dir.is_dir() {
+            true => Some(dir),
+            false => std::fs::create_dir_all(&dir)
+                .map(|_| dir)
+                .map_err(|e| log::error!(target: "xdg", "{e}"))
+                .ok(),
         })
     }
 
@@ -207,26 +203,28 @@ impl XDGFolder {
 
         let (mut exists, mut can_create): (MaybeFolderList, MaybeFolderList) =
             matches.iter().partition(|m| matches!(m, FindState::Exists(_)));
-        use XDGFindBehaviour::*;
         match (exists.is_some(), can_create.is_some()) {
             // [XDGFindBehaviour::FirstOrCreate] case...
-            (true, false) if opt == FirstOrCreate => Ok(exists.into_first().into_iter().collect()),
-            (false, true) if opt == FirstOrCreate => Ok(can_create.into_first().into_iter().collect()),
+            (true, false) if opt == XDGFindBehaviour::FirstOrCreate => Ok(exists.into_first().into_iter().collect()),
+            (false, true) if opt == XDGFindBehaviour::FirstOrCreate => {
+                Ok(can_create.into_first().into_iter().collect())
+            }
 
             // Should we return the one list that is not empty?
-            (true, false) if matches!(opt, AllFiles | ExistingOnly) => Ok(exists),
-            (false, true) if matches!(opt, AllFiles | NonExistingOnly) => Ok(can_create),
+            (true, false) if matches!(opt, XDGFindBehaviour::AllFiles | XDGFindBehaviour::ExistingOnly) => Ok(exists),
+            (false, true) if matches!(opt, XDGFindBehaviour::AllFiles | XDGFindBehaviour::NonExistingOnly) => {
+                Ok(can_create)
+            }
 
             // Complicated case
             (true, true) => match opt {
-                AllFiles => {
+                XDGFindBehaviour::AllFiles => {
                     exists.append(&mut can_create);
                     Ok(exists)
                 }
-
-                FirstOrCreate => Ok(exists.into_first().into_iter().collect()),
-                ExistingOnly => Ok(exists),
-                NonExistingOnly => Ok(can_create),
+                XDGFindBehaviour::FirstOrCreate => Ok(exists.into_first().into_iter().collect()),
+                XDGFindBehaviour::ExistingOnly => Ok(exists),
+                XDGFindBehaviour::NonExistingOnly => Ok(can_create),
             },
 
             // The list that we want is empty, or all lists are empty, returns nothing -> should it
@@ -238,8 +236,7 @@ impl XDGFolder {
     /// Is this variable a folder list?
     #[inline]
     pub fn is_list(&self) -> bool {
-        use XDGFolder::*;
-        matches!(self, DataDirs | ConfigDirs)
+        matches!(self, XDGFolder::DataDirs | XDGFolder::ConfigDirs)
     }
 
     /// Get the env variable name associated with the folder or folder list.
diff --git a/src/Rust/vvs_xdg/src/lib.rs b/src/Rust/vvs_xdg/src/lib.rs
index 9183ddf8c07823a4421401da48a6618b58f587ae..cbfc9bce294f875425df0415bbc4ece7a3ed79ad 100644
--- a/src/Rust/vvs_xdg/src/lib.rs
+++ b/src/Rust/vvs_xdg/src/lib.rs
@@ -8,14 +8,11 @@ mod tests;
 
 mod config;
 mod folders;
-mod options;
 mod paths;
-mod traits;
 
-pub use self::{config::*, folders::*, options::*, paths::*, traits::*};
+pub use self::{config::*, folders::*, paths::*};
 
 use std::{io::Error as IoError, path::PathBuf};
-use thiserror::Error;
 
 /// Get the user's home folder. Panics if the env variable was not found or it can't be
 /// canonicalized.
@@ -26,7 +23,7 @@ pub fn home_folder() -> PathBuf {
         .expect("failed to canonicalize the $HOME folder path")
 }
 
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum XDGError {
     #[error("failed to find file {2} for application {1} with folder family {0}")]
     NotFound(XDGFolder, String, String),
@@ -46,3 +43,38 @@ pub enum XDGError {
     #[error("serialization failed on file {1} for application {0}")]
     SerializeError(String, String),
 }
+
+/// Control the behaviour of the [XDGFolder::find] function on conflicts.
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
+pub enum XDGFindBehaviour {
+    /// Returns only the files that already exists. If no file is found, returns the file with the
+    /// post priority that can be created, usually where the user want this file to exists. If you
+    /// don't want to merge config/data files/folders this can be a sane default.
+    #[default]
+    FirstOrCreate,
+
+    /// Returns only the files that already exists. If you want to merge config/data files/folders
+    /// this can be a sane default.
+    ExistingOnly,
+
+    /// Only returns files that don't already exists and may be created. Note that even if a file
+    /// can be created by the user, it won't necessarily means that you will be able to, keep in
+    /// mind that race conditions may occur here.
+    NonExistingOnly,
+
+    /// Returns all files, the ones that exist and the ones that may be created. The user will need
+    /// to handle the returned files as he sees fit.
+    AllFiles,
+}
+
+/// We force the user to choose a way to serialize and deserialize the config file. This way, we
+/// are format agnostique here and don't even depend on serde.
+pub trait XDGConfigFileSerde: Sized + Extend<Self> {
+    type Error: std::error::Error;
+
+    /// Read the content of the config file.
+    fn deserialize(input: &str) -> Result<Self, Self::Error>;
+
+    /// Write the config file to string, so that we can write it latter into a file.
+    fn serialize(&self) -> Result<String, Self::Error>;
+}
diff --git a/src/Rust/vvs_xdg/src/options.rs b/src/Rust/vvs_xdg/src/options.rs
deleted file mode 100644
index 3985de17e9e1be548a0cb8cecb9a8503eb473422..0000000000000000000000000000000000000000
--- a/src/Rust/vvs_xdg/src/options.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//! Options that can be passed to some functions to control the behaviour.
-
-/// Control the behaviour of the [XDGFolder::find] function on conflicts.
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
-pub enum XDGFindBehaviour {
-    /// Returns only the files that already exists. If no file is found, returns the file with the
-    /// post priority that can be created, usually where the user want this file to exists. If you
-    /// don't want to merge config/data files/folders this can be a sane default.
-    #[default]
-    FirstOrCreate,
-
-    /// Returns only the files that already exists. If you want to merge config/data files/folders
-    /// this can be a sane default.
-    ExistingOnly,
-
-    /// Only returns files that don't already exists and may be created. Note that even if a file
-    /// can be created by the user, it won't necessarily means that you will be able to, keep in
-    /// mind that race conditions may occur here.
-    NonExistingOnly,
-
-    /// Returns all files, the ones that exist and the ones that may be created. The user will need
-    /// to handle the returned files as he sees fit.
-    AllFiles,
-}
diff --git a/src/Rust/vvs_xdg/src/paths.rs b/src/Rust/vvs_xdg/src/paths.rs
index 7eec911df4add0c483c191671f06ac92f02fc4bb..326348c0632db12e42a698c5cb94b0c8744de26d 100644
--- a/src/Rust/vvs_xdg/src/paths.rs
+++ b/src/Rust/vvs_xdg/src/paths.rs
@@ -42,57 +42,51 @@ impl MaybeFolderList {
     /// Get the first folder, or the last folder. If no folder is present just returns [None].
     #[inline]
     pub fn first(&self) -> Option<&Path> {
-        use MaybeFolderList::*;
         match self {
-            Empty => None,
-            Folder(f) | Many(f, _) => Some(f.as_ref()),
+            MaybeFolderList::Empty => None,
+            MaybeFolderList::Folder(f) | MaybeFolderList::Many(f, _) => Some(f.as_ref()),
         }
     }
 
     /// Append another [MaybeFolderList] at the end of a [MaybeFolderList]. Empties the other
     /// variable and try to reuse memory.
     pub fn append(&mut self, other: &mut MaybeFolderList) {
-        use MaybeFolderList::*;
-
         match (self, other) {
-            (this @ Empty, other) => match other {
-                Empty => {}
-                Folder(f1) => {
-                    *this = Folder(mem::take(f1));
-                    *other = Empty;
-                }
-                Many(f1, fs) => {
-                    *this = Many(mem::take(f1), mem::take(fs));
-                    *other = Empty;
-                }
+            (this @ MaybeFolderList::Empty, other) => match mem::replace(other, MaybeFolderList::Empty) {
+                MaybeFolderList::Empty => {}
+                MaybeFolderList::Folder(f1) => *this = MaybeFolderList::Folder(f1),
+                MaybeFolderList::Many(f1, fs) => *this = MaybeFolderList::Many(f1, fs),
             },
 
-            (_, Empty) => {}
+            (_, MaybeFolderList::Empty) => {}
 
-            (Many(_, fs), other @ Folder(_)) => {
-                let Folder(f2) = other else { unreachable!() };
-                fs.push(mem::take(f2));
-                *other = Empty;
+            (MaybeFolderList::Many(_, fs), other @ MaybeFolderList::Folder(_)) => {
+                let MaybeFolderList::Folder(f2) = mem::replace(other, MaybeFolderList::Empty) else {
+                    unreachable!()
+                };
+                fs.push(f2);
             }
-            (Many(_, fs), other @ Many(_, _)) => {
-                let Many(f2, ref mut fs2) = other else { unreachable!() };
+            (MaybeFolderList::Many(_, fs), other @ MaybeFolderList::Many(..)) => {
+                let MaybeFolderList::Many(f2, ref mut fs2) = mem::replace(other, MaybeFolderList::Empty) else {
+                    unreachable!()
+                };
                 fs.reserve(fs2.len() + 1);
-                fs.push(mem::take(f2));
+                fs.push(f2);
                 fs.append(fs2);
-                *other = Empty;
             }
 
-            (this @ Folder(_), other) => {
-                let Folder(f1) = this else { unreachable!() };
-                match other {
-                    Empty => unreachable!(),
-                    Folder(f2) => *this = Many(mem::take(f1), vec![mem::take(f2)]),
-                    Many(f2, ref mut fs) => {
-                        fs.insert(0, mem::take(f2));
-                        *this = Many(mem::take(f1), mem::take(fs));
+            (this @ MaybeFolderList::Folder(_), other) => {
+                let MaybeFolderList::Folder(f1) = mem::take(this) else {
+                    unreachable!()
+                };
+                match mem::replace(other, MaybeFolderList::Empty) {
+                    MaybeFolderList::Empty => unreachable!(),
+                    MaybeFolderList::Folder(f2) => *this = MaybeFolderList::Many(f1, vec![f2]),
+                    MaybeFolderList::Many(f2, mut fs) => {
+                        fs.insert(0, f2);
+                        *this = MaybeFolderList::Many(f1, fs);
                     }
                 }
-                *other = Empty;
             }
         }
     }
@@ -102,10 +96,9 @@ impl MaybeFolderList {
     /// [MaybeFolderList].
     #[inline]
     pub fn into_first(self) -> Option<PathBuf> {
-        use MaybeFolderList::*;
         match self {
-            Empty => None,
-            Folder(f) | Many(f, _) => Some(f),
+            MaybeFolderList::Empty => None,
+            MaybeFolderList::Folder(f) | MaybeFolderList::Many(f, _) => Some(f),
         }
     }
 
@@ -133,28 +126,26 @@ impl MaybeFolderList {
 
 impl std::iter::Extend<PathBuf> for MaybeFolderList {
     fn extend<T: IntoIterator<Item = PathBuf>>(&mut self, iter: T) {
-        use MaybeFolderList::*;
-        let mut iter = iter.into_iter();
         match self {
-            Empty => {
+            MaybeFolderList::Empty => {
+                let mut iter = iter.into_iter();
                 if let Some(next) = iter.next() {
-                    *self = Many(next, iter.collect());
+                    *self = MaybeFolderList::Many(next, iter.collect());
                 }
             }
-            Folder(f1) => *self = Many(mem::take(f1), iter.collect()),
-            Many(_, fs) => fs.extend(iter),
+            MaybeFolderList::Folder(f1) => *self = MaybeFolderList::Many(mem::take(f1), iter.into_iter().collect()),
+            MaybeFolderList::Many(_, fs) => fs.extend(iter),
         }
     }
 }
 
 impl<'a> std::iter::Extend<&'a MaybeFolderList> for MaybeFolderList {
     fn extend<T: IntoIterator<Item = &'a MaybeFolderList>>(&mut self, iter: T) {
-        use MaybeFolderList::*;
-        let other = iter.into_iter().flat_map(|iter| iter.iter());
+        let other = iter.into_iter().flat_map(MaybeFolderList::iter);
         match self {
-            Empty => *self = other.collect(),
-            Folder(f1) => *self = Many(mem::take(f1), other.cloned().collect()),
-            Many(_, ref mut fs) => fs.extend(other.cloned()),
+            MaybeFolderList::Empty => *self = other.collect(),
+            MaybeFolderList::Folder(f1) => *self = MaybeFolderList::Many(mem::take(f1), other.cloned().collect()),
+            MaybeFolderList::Many(_, ref mut fs) => fs.extend(other.cloned()),
         }
     }
 }
diff --git a/src/Rust/vvs_xdg/src/traits.rs b/src/Rust/vvs_xdg/src/traits.rs
deleted file mode 100644
index 728ef7cf43135766c273e64a620b3c3a8e47c269..0000000000000000000000000000000000000000
--- a/src/Rust/vvs_xdg/src/traits.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-pub trait XDGConfigFileSerde: Sized + Extend<Self> {
-    type Error: std::error::Error;
-
-    fn deserialize(input: &str) -> Result<Self, Self::Error>;
-
-    fn serialize(&self) -> Result<String, Self::Error>;
-}