#![doc(
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png",
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png"
)]
#![warn(missing_docs, rust_2018_idioms)]
#![allow(clippy::deprecated_semver)]
use std::{
ffi::OsString,
fmt::Display,
path::{Path, PathBuf},
};
use semver::Version;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub mod acl;
pub mod assets;
pub mod config;
pub mod html;
pub mod io;
pub mod mime_type;
pub mod platform;
pub mod plugin;
#[cfg(feature = "resources")]
pub mod resources;
#[cfg(feature = "build")]
pub mod tokens;
#[cfg(feature = "build")]
pub mod build;
pub mod pattern;
#[derive(Debug, Clone)]
pub struct PackageInfo {
pub name: String,
pub version: Version,
pub authors: &'static str,
pub description: &'static str,
pub crate_name: &'static str,
}
#[allow(deprecated)]
mod window_effects {
use super::*;
#[derive(Debug, PartialEq, Eq, Clone, Copy, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "camelCase")]
pub enum WindowEffect {
#[deprecated(
since = "macOS 10.14",
note = "You should instead choose an appropriate semantic material."
)]
AppearanceBased,
#[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")]
Light,
#[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")]
Dark,
#[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")]
MediumLight,
#[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")]
UltraDark,
Titlebar,
Selection,
Menu,
Popover,
Sidebar,
HeaderView,
Sheet,
WindowBackground,
HudWindow,
FullScreenUI,
Tooltip,
ContentBackground,
UnderWindowBackground,
UnderPageBackground,
Mica,
MicaDark,
MicaLight,
Tabbed,
TabbedDark,
TabbedLight,
Blur,
Acrylic,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "camelCase")]
pub enum WindowEffectState {
FollowsWindowActiveState,
Active,
Inactive,
}
}
pub use window_effects::{WindowEffect, WindowEffectState};
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[non_exhaustive]
pub enum TitleBarStyle {
Visible,
Transparent,
Overlay,
}
impl Default for TitleBarStyle {
fn default() -> Self {
Self::Visible
}
}
impl Serialize for TitleBarStyle {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.to_string().as_ref())
}
}
impl<'de> Deserialize<'de> for TitleBarStyle {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(match s.to_lowercase().as_str() {
"transparent" => Self::Transparent,
"overlay" => Self::Overlay,
_ => Self::Visible,
})
}
}
impl Display for TitleBarStyle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Visible => "Visible",
Self::Transparent => "Transparent",
Self::Overlay => "Overlay",
}
)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[non_exhaustive]
pub enum Theme {
Light,
Dark,
}
impl Serialize for Theme {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.to_string().as_ref())
}
}
impl<'de> Deserialize<'de> for Theme {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(match s.to_lowercase().as_str() {
"dark" => Self::Dark,
_ => Self::Light,
})
}
}
impl Display for Theme {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Light => "light",
Self::Dark => "dark",
}
)
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct Env {
#[cfg(target_os = "linux")]
pub appimage: Option<std::ffi::OsString>,
#[cfg(target_os = "linux")]
pub appdir: Option<std::ffi::OsString>,
pub args_os: Vec<OsString>,
}
#[allow(clippy::derivable_impls)]
impl Default for Env {
fn default() -> Self {
let args_os = std::env::args_os().collect();
#[cfg(target_os = "linux")]
{
let env = Self {
#[cfg(target_os = "linux")]
appimage: std::env::var_os("APPIMAGE"),
#[cfg(target_os = "linux")]
appdir: std::env::var_os("APPDIR"),
args_os,
};
if env.appimage.is_some() || env.appdir.is_some() {
let is_temp = std::env::current_exe()
.map(|p| {
p.display()
.to_string()
.starts_with(&format!("{}/.mount_", std::env::temp_dir().display()))
})
.unwrap_or(true);
if !is_temp {
log::warn!("`APPDIR` or `APPIMAGE` environment variable found but this application was not detected as an AppImage; this might be a security issue.");
}
}
env
}
#[cfg(not(target_os = "linux"))]
{
Self { args_os }
}
}
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("Unable to determine target-architecture")]
Architecture,
#[error("Unable to determine target-os")]
Os,
#[error("Unable to determine target-environment")]
Environment,
#[error("Unsupported platform for reading resources")]
UnsupportedPlatform,
#[error("Could not get parent process")]
ParentProcess,
#[error("Could not get parent PID")]
ParentPid,
#[error("Could not get child process")]
ChildProcess,
#[error("{0}")]
Io(#[from] std::io::Error),
#[error("invalid pattern `{0}`. Expected either `brownfield` or `isolation`.")]
InvalidPattern(String),
#[cfg(feature = "resources")]
#[error("{0}")]
GlobPattern(#[from] glob::PatternError),
#[cfg(feature = "resources")]
#[error("`{0}`")]
Glob(#[from] glob::GlobError),
#[cfg(feature = "resources")]
#[error("glob pattern {0} path not found or didn't match any files.")]
GlobPathNotFound(String),
#[cfg(feature = "resources")]
#[error("{0}")]
WalkdirError(#[from] walkdir::Error),
#[cfg(feature = "resources")]
#[error("could not walk directory `{0}`, try changing `allow_walk` to true on the `ResourcePaths` constructor.")]
NotAllowedToWalkDir(std::path::PathBuf),
#[cfg(feature = "resources")]
#[error("resource path `{0}` doesn't exist")]
ResourcePathNotFound(std::path::PathBuf),
}
pub fn display_path<P: AsRef<Path>>(p: P) -> String {
dunce::simplified(&p.as_ref().components().collect::<PathBuf>())
.display()
.to_string()
}
pub fn write_if_changed<P, C>(path: P, content: C) -> std::io::Result<()>
where
P: AsRef<Path>,
C: AsRef<[u8]>,
{
if let Ok(existing) = std::fs::read(&path) {
if existing == content.as_ref() {
return Ok(());
}
}
std::fs::write(path, content)
}