Linux: determining app: and app-storage: directories

⚓ Rust    📅 2025-09-03    👤 surdeus    👁️ 1      

surdeus

Follow-up. In my file system API:

  • The app: URL resolves to a file (an "asset") in the app's installation directory.
  • The app-storage: URL resolves to a file/directory in the app's data/settings directory. (E.g. store databases, cookies, ... pretty much compatible with the web Origin Private File System)

I had a ready implementation, but didn't support Linux AppImage, FlatPak and ?Steam?.

I've put a FIXME in this code for what needs to be changed to a something else: (e.g. PathBuf::from(&std::env::var("HOME").unwrap()).join(".local/share"))

I determined if the app is running in Flatpak/AppImage/Snap according to this.

use std::path::PathBuf;
use cfg_if::cfg_if;

/// System-wide app: directory.
pub fn system_wide_app_dir() -> PathBuf {
    cfg_if! {
        if #[cfg(target_os = "windows")] {
            // Windows
            std::env::current_exe().unwrap().parent().unwrap().to_owned()
        } else if #[cfg(target_os = "macos")] {
            // Mac
            std::env::current_exe().unwrap().parent().unwrap().to_owned()
        } else {
            // Linux
            if std::env::var("container").is_ok() {
                // FlatPak (system-wide installation)
                PathBuf::from(FIXME).join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            } else if std::env::var("APPIMAGE").is_ok() {
                // AppImage
                std::env::current_exe().unwrap().parent().unwrap().to_owned()
            } else if std::env::var("SNAP").is_ok() {
                // Snap
                PathBuf::from(FIXME).join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            } else {
                // System-wide installation through scratch-made installer
                PathBuf::from("/usr/local/share").join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            }
        }
    }
}

/// User app: directory.
pub fn user_app_dir() -> PathBuf {
    cfg_if! {
        if #[cfg(target_os = "windows")] {
            // Windows
            std::env::current_exe().unwrap().parent().unwrap().to_owned()
        } else if #[cfg(target_os = "macos")] {
            // Mac
            std::env::current_exe().unwrap().parent().unwrap().to_owned()
        } else {
            // Linux
            if std::env::var("container").is_ok() {
                // FlatPak (system-wide installation)
                PathBuf::from(FIXME).join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            } else if std::env::var("APPIMAGE").is_ok() {
                // AppImage
                std::env::current_exe().unwrap().parent().unwrap().to_owned()
            } else if std::env::var("SNAP").is_ok() {
                // Snap
                PathBuf::from(FIXME).join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            } else {
                // User installation through scratch-made installer
                dirs::data_dir().unwrap().join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            }
        }
    }
}

/// General app-storage: directory (Windows, Linux, Mac)
pub fn general_app_storage_dir() -> PathBuf {
    cfg_if! {
        if #[cfg(target_os = "linux")] {
            // Linux
            if std::env::var("container").is_ok() {
                // FlatPak
                PathBuf::from(FIXME).join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            } else if std::env::var("APPIMAGE").is_ok() {
                // AppImage
                dirs::config_dir().unwrap().join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            } else if std::env::var("SNAP").is_ok() {
                // Snap
                PathBuf::from(FIXME).join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            } else {
                // app-storage: directory after scratch-made installer
                dirs::config_dir().unwrap().join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
            }
        } else {
            // (Windows, Mac)
            dirs::config_dir().unwrap().join(unsafe { crate::application::bootstrap::APPLICATION_ID.unwrap() })
        }
    }
}

Basically I just need to know:

  • The system-wide app: in...
    • FlatPak
    • ?Snap?
  • The user app: directory in...
    • FlatPak
    • ?Snap?
  • The app-storage: directory (always user-specific) in
    • FlatPak
    • ?Snap?

I'm not sure I need Snap

2 posts - 1 participant

Read full topic

🏷️ Rust_feed