use std::fs;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicUsize, Ordering};
use super::XdgDirs;
pub(super) const MARKDOWN_XML: &str = r#"<?xml version="1.0" encoding="utf-8"?>
<mime-type xmlns="http://www.freedesktop.org/standards/shared-mime-info" type="text/markdown">
<!--Created automatically by update-mime-database. DO NOT EDIT!-->
<comment>Markdown document</comment>
<comment xml:lang="pt-BR">Documento Markdown</comment>
<comment xml:lang="pt">Documento Markdown (pt)</comment>
<comment xml:lang="tr">Markdown belgesi & not</comment>
<comment xml:lang="sr-Cyrl">Маркдаун документ</comment>
<sub-class-of type="text/plain"/>
<glob pattern="*.md"/>
</mime-type>
"#;
pub(super) const UNCLOSED_XML: &str =
"<mime-type type=\"text/markdown\">\n <comment>Markdown document\n</mime-type>\n";
static NEXT: AtomicUsize = AtomicUsize::new(0);
pub(super) struct Tree {
root: PathBuf,
}
impl Tree {
pub(super) fn new() -> Self {
let n = NEXT.fetch_add(1, Ordering::SeqCst);
let root = std::env::temp_dir().join(format!("qframe-desktop-{}-{n}", std::process::id()));
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(&root).expect("the temporary folder can be made");
Self { root }
}
pub(super) fn path(&self, rel: &str) -> PathBuf {
self.root.join(rel)
}
pub(super) fn write(&self, rel: &str, contents: impl AsRef<[u8]>) -> PathBuf {
let path = self.path(rel);
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).expect("the folder can be made");
}
fs::write(&path, contents).expect("the file can be written");
path
}
pub(super) fn program(&self, rel: &str) -> PathBuf {
let path = self.write(rel, "#!/bin/sh\n");
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
fs::set_permissions(&path, fs::Permissions::from_mode(0o755)).expect("mode can be set");
}
path
}
pub(super) fn dirs(&self) -> XdgDirs {
XdgDirs {
data_home: Some(self.path("home/data")),
data_dirs: vec![self.path("usr/local"), self.path("usr")],
config_home: Some(self.path("home/config")),
config_dirs: vec![self.path("etc")],
desktops: Vec::new(),
}
}
pub(super) fn root(&self) -> &Path {
&self.root
}
}
impl Drop for Tree {
fn drop(&mut self) {
let _ = fs::remove_dir_all(&self.root);
}
}