Debug pin macro (#118)

* debug pin macro

* Added debug pinning macro

* working on windows

* removed remaining box pins
This commit is contained in:
Wyatt Verchere
2023-05-18 10:31:52 -07:00
committed by GitHub
parent 0801d7a145
commit 16407060f0
35 changed files with 1133 additions and 990 deletions
Generated
+10
View File
@@ -3764,6 +3764,7 @@ dependencies = [
"sys-info",
"tauri",
"tempfile",
"theseus_macros",
"thiserror",
"tokio",
"tokio-stream",
@@ -3817,6 +3818,7 @@ dependencies = [
"tauri",
"tauri-build",
"theseus",
"theseus_macros",
"thiserror",
"tokio",
"tokio-stream",
@@ -3827,6 +3829,14 @@ dependencies = [
"uuid 1.3.0",
]
[[package]]
name = "theseus_macros"
version = "0.1.0"
dependencies = [
"quote",
"syn 1.0.109",
]
[[package]]
name = "theseus_playground"
version = "0.1.0"
+2 -1
View File
@@ -4,7 +4,8 @@ members = [
"theseus",
"theseus_cli",
"theseus_playground",
"theseus_gui/src-tauri"
"theseus_gui/src-tauri",
"theseus_macros"
]
# Optimize for speed and reduce size on release builds
+2
View File
@@ -7,6 +7,8 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
theseus_macros = { path = "../theseus_macros" }
bytes = "1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
+2
View File
@@ -32,6 +32,7 @@ pub async fn authenticate_await_complete_flow() -> crate::Result<Credentials> {
/// open a browser to the given URL and finally wait on the spawned future
/// with the ability to cancel in case the browser is closed before finishing
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn authenticate(
browser_url: oneshot::Sender<url::Url>,
) -> crate::Result<Credentials> {
@@ -60,6 +61,7 @@ pub async fn authenticate(
/// Refresh some credentials using Hydra, if needed
/// This is the primary desired way to get credentials, as it will also refresh them.
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn refresh(user: uuid::Uuid) -> crate::Result<Credentials> {
let state = State::get().await?;
let mut users = state.users.write().await;
+1 -4
View File
@@ -137,9 +137,8 @@ pub async fn find_java17_jres() -> crate::Result<Vec<JavaVersion>> {
.collect())
}
#[theseus_macros::debug_pin]
pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
Box::pin(
async move {
let state = State::get().await?;
let loading_bar = init_loading(
@@ -218,8 +217,6 @@ pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
java_version, std::env::consts::OS, std::env::consts::ARCH,
)).into())
}
}
).await
}
// Get all JREs that exist on the system
+11 -19
View File
@@ -76,13 +76,14 @@ enum PackDependency {
Minecraft,
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn install_pack_from_version_id(
version_id: String,
title: String,
icon_url: Option<String>,
) -> crate::Result<PathBuf> {
let state = State::get().await?;
Box::pin(async move {
let profile = crate::api::profile_create::profile_create(
title.clone(),
"1.19.4".to_string(),
@@ -143,8 +144,7 @@ pub async fn install_pack_from_version_id(
&state.fetch_semaphore,
)
.await?;
emit_loading(&loading_bar, 0.0, Some("Fetching project metadata"))
.await?;
emit_loading(&loading_bar, 0.0, Some("Fetching project metadata")).await?;
let project: ModrinthProject = fetch_json(
Method::GET,
@@ -158,8 +158,7 @@ pub async fn install_pack_from_version_id(
emit_loading(&loading_bar, 10.0, Some("Retrieving icon")).await?;
let icon = if let Some(icon_url) = project.icon_url {
let state = State::get().await?;
let icon_bytes =
fetch(&icon_url, None, &state.fetch_semaphore).await?;
let icon_bytes = fetch(&icon_url, None, &state.fetch_semaphore).await?;
let filename = icon_url.rsplit('/').next();
@@ -191,10 +190,10 @@ pub async fn install_pack_from_version_id(
profile,
)
.await
})
.await
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn install_pack_from_file(path: PathBuf) -> crate::Result<PathBuf> {
let file = fs::read(&path).await?;
@@ -228,6 +227,8 @@ pub async fn install_pack_from_file(path: PathBuf) -> crate::Result<PathBuf> {
.await
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
async fn install_pack(
file: bytes::Bytes,
icon: Option<PathBuf>,
@@ -239,12 +240,10 @@ async fn install_pack(
) -> crate::Result<PathBuf> {
let state = &State::get().await?;
Box::pin(async move {
let reader: Cursor<&bytes::Bytes> = Cursor::new(&file);
// Create zip reader around file
let mut zip_reader =
ZipFileReader::new(reader).await.map_err(|_| {
let mut zip_reader = ZipFileReader::new(reader).await.map_err(|_| {
crate::Error::from(crate::ErrorKind::InputError(
"Failed to read input modpack zip".to_string(),
))
@@ -391,14 +390,9 @@ async fn install_pack(
.next();
if let Some(path) = path {
match path {
Component::CurDir
| Component::Normal(_) => {
Component::CurDir | Component::Normal(_) => {
let path = profile.join(project.path);
write(
&path,
&file,
&state.io_semaphore,
)
write(&path, &file, &state.io_semaphore)
.await?;
}
_ => {}
@@ -503,6 +497,4 @@ async fn install_pack(
"No pack manifest found in mrpack".to_string(),
)))
}
})
.await
}
+5 -9
View File
@@ -123,8 +123,9 @@ pub async fn install(path: &Path) -> crate::Result<()> {
Ok(())
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn update_all(profile_path: &Path) -> crate::Result<()> {
Box::pin(async move {
if let Some(profile) = get(profile_path, None).await? {
let loading_bar = init_loading(
LoadingBarType::ProfileUpdate {
@@ -160,10 +161,10 @@ pub async fn update_all(profile_path: &Path) -> crate::Result<()> {
)
.as_error())
}
})
.await
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn update_project(
profile_path: &Path,
project_path: &Path,
@@ -304,7 +305,6 @@ pub async fn remove_project(
/// failing with an error if no credentials are available
#[tracing::instrument]
pub async fn run(path: &Path) -> crate::Result<Arc<RwLock<MinecraftChild>>> {
Box::pin(async move {
let state = State::get().await?;
// Get default account and refresh credentials (preferred way to log in)
@@ -322,18 +322,16 @@ pub async fn run(path: &Path) -> crate::Result<Arc<RwLock<MinecraftChild>>> {
}
};
run_credentials(path, &credentials).await
})
.await
}
/// Run Minecraft using a profile, and credentials for authentication
/// Returns Arc pointer to RwLock to Child
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn run_credentials(
path: &Path,
credentials: &auth::Credentials,
) -> crate::Result<Arc<RwLock<MinecraftChild>>> {
Box::pin(async move {
let state = State::get().await?;
let settings = state.settings.read().await;
let profile = get(path, None).await?.ok_or_else(|| {
@@ -411,6 +409,4 @@ pub async fn run_credentials(
)
.await?;
Ok(mc_process)
})
.await
}
+3 -3
View File
@@ -39,6 +39,7 @@ pub async fn profile_create_empty() -> crate::Result<PathBuf> {
// Creates a profile at the given filepath and adds it to the in-memory state
// Returns filepath at which it can be accessed in the State
#[tracing::instrument]
#[theseus_macros::debug_pin]
#[allow(clippy::too_many_arguments)]
pub async fn profile_create(
name: String, // the name of the profile, and relative path
@@ -52,7 +53,6 @@ pub async fn profile_create(
) -> crate::Result<PathBuf> {
trace!("Creating new profile. {}", name);
let state = State::get().await?;
Box::pin(async move {
let uuid = Uuid::new_v4();
let path = state.directories.profiles_dir().join(uuid.to_string());
if path.exists() {
@@ -134,10 +134,10 @@ pub async fn profile_create(
State::sync().await?;
Ok(path)
})
.await
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub(crate) async fn get_loader_version_from_loader(
game_version: String,
loader: ModLoader,
+4
View File
@@ -46,6 +46,7 @@ const CLI_PROGRESS_BAR_TOTAL: u64 = 1000;
// This will generate a LoadingBarId, which is used to refer to the loading bar uniquely.
// total is the total amount of work to be done- all emissions will be considered a fraction of this value (should be 1 or 100 for simplicity)
// title is the title of the loading bar
#[theseus_macros::debug_pin]
pub async fn init_loading(
bar_type: LoadingBarType,
total: f64,
@@ -134,6 +135,7 @@ pub async fn edit_loading(
// By convention, fraction is the fraction of the progress bar that is filled
#[allow(unused_variables)]
#[tracing::instrument(level = "debug")]
#[theseus_macros::debug_pin]
pub async fn emit_loading(
key: &LoadingBarId,
increment_frac: f64,
@@ -329,6 +331,8 @@ macro_rules! loading_join {
// Total is the total amount of progress that the loading bar should take up by all futures in this (will be split evenly amongst them).
// If message is Some(t) you will overwrite this loading bar's message with a custom one
// num_futs is the number of futures that will be run, which is needed as we allow Iterator to be passed in, which doesn't have a size
#[tracing::instrument(skip(stream, f))]
#[theseus_macros::debug_pin]
pub async fn loading_try_for_each_concurrent<I, F, Fut, T>(
stream: I,
limit: Option<usize>,
+9 -20
View File
@@ -54,6 +54,7 @@ pub async fn download_minecraft(
}
#[tracing::instrument(skip_all, fields(version = version.id.as_str(), loader = ?loader))]
#[theseus_macros::debug_pin]
pub async fn download_version_info(
st: &State,
version: &GameVersion,
@@ -61,10 +62,8 @@ pub async fn download_version_info(
force: Option<bool>,
loading_bar: Option<&LoadingBarId>,
) -> crate::Result<GameVersionInfo> {
Box::pin(async move {
let version_id = loader.map_or(version.id.clone(), |it| {
format!("{}-{}", version.id, it.id)
});
let version_id = loader
.map_or(version.id.clone(), |it| format!("{}-{}", version.id, it.id));
tracing::debug!("Loading version info for Minecraft {version_id}");
let path = st
.directories
@@ -77,15 +76,11 @@ pub async fn download_version_info(
.await
.and_then(|ref it| Ok(serde_json::from_slice(it)?))
} else {
tracing::info!(
"Downloading version info for version {}",
&version.id
);
tracing::info!("Downloading version info for version {}", &version.id);
let mut info = d::minecraft::fetch_version_info(version).await?;
if let Some(loader) = loader {
let partial =
d::modded::fetch_partial_version(&loader.url).await?;
let partial = d::modded::fetch_partial_version(&loader.url).await?;
info = d::modded::merge_partial_version(partial, info);
}
info.id = version_id.clone();
@@ -100,17 +95,15 @@ pub async fn download_version_info(
tracing::debug!("Loaded version info for Minecraft {version_id}");
Ok(res)
})
.await
}
#[tracing::instrument(skip_all)]
#[theseus_macros::debug_pin]
pub async fn download_client(
st: &State,
version_info: &GameVersionInfo,
loading_bar: Option<&LoadingBarId>,
) -> crate::Result<()> {
Box::pin(async move {
let version = &version_info.id;
tracing::debug!("Locating client for version {version}");
let client_download = version_info
@@ -143,11 +136,10 @@ pub async fn download_client(
tracing::debug!("Client loaded for version {version}!");
Ok(())
})
.await
}
#[tracing::instrument(skip_all)]
#[theseus_macros::debug_pin]
pub async fn download_assets_index(
st: &State,
version: &GameVersionInfo,
@@ -179,6 +171,7 @@ pub async fn download_assets_index(
}
#[tracing::instrument(skip(st, index))]
#[theseus_macros::debug_pin]
pub async fn download_assets(
st: &State,
with_legacy: bool,
@@ -186,7 +179,6 @@ pub async fn download_assets(
loading_bar: Option<&LoadingBarId>,
loading_amount: f64,
) -> crate::Result<()> {
Box::pin(async move {
tracing::debug!("Loading assets");
let num_futs = index.objects.len();
let assets = stream::iter(index.objects.iter())
@@ -238,10 +230,10 @@ pub async fn download_assets(
}).await?;
tracing::debug!("Done loading assets!");
Ok(())
}).await
}
#[tracing::instrument(skip(st, libraries))]
#[theseus_macros::debug_pin]
pub async fn download_libraries(
st: &State,
libraries: &[Library],
@@ -250,7 +242,6 @@ pub async fn download_libraries(
loading_amount: f64,
java_arch: &str,
) -> crate::Result<()> {
Box::pin(async move {
tracing::debug!("Loading libraries");
tokio::try_join! {
@@ -344,6 +335,4 @@ pub async fn download_libraries(
tracing::debug!("Done loading libraries!");
Ok(())
}).await
}
+19 -17
View File
@@ -92,11 +92,11 @@ async fn get_java_version_from_profile(
}
#[tracing::instrument(skip(profile))]
#[theseus_macros::debug_pin]
pub async fn install_minecraft(
profile: &Profile,
existing_loading_bar: Option<LoadingBarId>,
) -> crate::Result<()> {
Box::pin(async move {
let loading_bar = init_or_edit_loading(
existing_loading_bar,
LoadingBarType::MinecraftDownload {
@@ -149,10 +149,17 @@ pub async fn install_minecraft(
)
.await?;
let java_version = get_java_version_from_profile(profile, &version_info).await?;
let java_version =
get_java_version_from_profile(profile, &version_info).await?;
// Download minecraft (5-90)
download::download_minecraft(&state, &version_info, &loading_bar, &java_version.architecture).await?;
download::download_minecraft(
&state,
&version_info,
&loading_bar,
&java_version.architecture,
)
.await?;
if let Some(processors) = &version_info.processors {
let client_path = state
@@ -201,7 +208,7 @@ pub async fn install_minecraft(
.arg(args::get_class_paths_jar(
&state.directories.libraries_dir(),
&cp,
&java_version.architecture
&java_version.architecture,
)?)
.arg(
args::get_processor_main_class(args::get_lib_path(
@@ -258,17 +265,13 @@ pub async fn install_minecraft(
})
.await?;
State::sync().await?;
emit_loading(
&loading_bar,
1.0,
Some("Finished installing"),
)
.await?;
emit_loading(&loading_bar, 1.0, Some("Finished installing")).await?;
Ok(())
}).await
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
#[allow(clippy::too_many_arguments)]
pub async fn launch_minecraft(
java_args: &[String],
@@ -280,7 +283,6 @@ pub async fn launch_minecraft(
post_exit_hook: Option<Command>,
profile: &Profile,
) -> crate::Result<Arc<tokio::sync::RwLock<MinecraftChild>>> {
Box::pin(async move {
if profile.install_stage == ProfileInstallStage::PackInstalling
|| profile.install_stage == ProfileInstallStage::Installing
{
@@ -325,7 +327,8 @@ pub async fn launch_minecraft(
)
.await?;
let java_version = get_java_version_from_profile(profile, &version_info).await?;
let java_version =
get_java_version_from_profile(profile, &version_info).await?;
let client_path = state
.directories
@@ -365,12 +368,12 @@ pub async fn launch_minecraft(
&state.directories.libraries_dir(),
version_info.libraries.as_slice(),
&client_path,
&java_version.architecture
&java_version.architecture,
)?,
&version_jar,
*memory,
Vec::from(java_args),
&java_version.architecture
&java_version.architecture,
)?
.into_iter()
.collect::<Vec<_>>(),
@@ -388,7 +391,7 @@ pub async fn launch_minecraft(
&state.directories.assets_dir(),
&version.type_,
*resolution,
&java_version.architecture
&java_version.architecture,
)?
.into_iter()
.collect::<Vec<_>>(),
@@ -431,5 +434,4 @@ pub async fn launch_minecraft(
post_exit_hook,
)
.await
}).await
}
+5
View File
@@ -38,6 +38,9 @@ impl Children {
// Runs the command in process, inserts a child process to keep track of, and returns a reference to the container struct MinecraftChild
// The threads for stdout and stderr are spawned here
// Unlike a Hashmap's 'insert', this directly returns the reference to the MinecraftChild rather than any previously stored MinecraftChild that may exist
#[tracing::instrument(skip(self))]
#[theseus_macros::debug_pin]
pub async fn insert_process(
&mut self,
uuid: Uuid,
@@ -110,6 +113,8 @@ impl Children {
// Spawns a new child process and inserts it into the hashmap
// Also, as the process ends, it spawns the follow-up process if it exists
// By convention, ExitStatus is last command's exit status, and we exit on the first non-zero exit status
#[tracing::instrument]
#[theseus_macros::debug_pin]
async fn sequential_process_manager(
uuid: Uuid,
post_command: Option<Command>,
+2
View File
@@ -54,6 +54,8 @@ impl Metadata {
}
// Attempt to fetch metadata and store in sled DB
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn init(
dirs: &DirectoryInfo,
io_semaphore: &IoSemaphore,
+3 -3
View File
@@ -82,6 +82,8 @@ pub struct State {
impl State {
/// Get the current launcher state, initializing it if needed
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn get() -> crate::Result<Arc<Self>> {
LAUNCHER_STATE
.get_or_try_init(|| {
@@ -166,9 +168,9 @@ impl State {
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
/// Synchronize in-memory state with persistent state
pub async fn sync() -> crate::Result<()> {
Box::pin(async move {
let state = Self::get().await?;
let sync_settings = async {
let state = Arc::clone(&state);
@@ -195,8 +197,6 @@ impl State {
tokio::try_join!(sync_settings, sync_profiles)?;
Ok(())
})
.await
}
/// Reset IO semaphore to default values
+12
View File
@@ -249,6 +249,8 @@ impl Profile {
Ok(files)
}
#[tracing::instrument(skip(watcher))]
#[theseus_macros::debug_pin]
pub async fn watch_fs(
profile_path: &Path,
watcher: &mut Debouncer<RecommendedWatcher>,
@@ -285,6 +287,8 @@ impl Profile {
Ok(())
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn add_project_version(
&self,
version_id: String,
@@ -330,6 +334,8 @@ impl Profile {
Ok((path, version))
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn add_project_bytes(
&self,
file_name: &str,
@@ -398,6 +404,8 @@ impl Profile {
Ok(path)
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn toggle_disable_project(
&self,
path: &Path,
@@ -471,6 +479,7 @@ impl Profile {
impl Profiles {
#[tracing::instrument(skip(file_watcher))]
#[theseus_macros::debug_pin]
pub async fn init(
dirs: &DirectoryInfo,
file_watcher: &mut Debouncer<RecommendedWatcher>,
@@ -501,6 +510,8 @@ impl Profiles {
Ok(Self(profiles))
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn update_projects() {
let res = async {
let state = State::get().await?;
@@ -553,6 +564,7 @@ impl Profiles {
}
#[tracing::instrument(skip(self))]
#[theseus_macros::debug_pin]
pub async fn insert(&mut self, profile: Profile) -> crate::Result<&Self> {
emit_profile(
profile.uuid,
+4
View File
@@ -200,6 +200,8 @@ pub enum ProjectMetadata {
Unknown,
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
async fn read_icon_from_file(
icon_path: Option<String>,
cache_dir: &Path,
@@ -249,6 +251,8 @@ async fn read_icon_from_file(
Ok(None)
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn infer_data_from_files(
profile: Profile,
paths: Vec<PathBuf>,
+2
View File
@@ -68,6 +68,8 @@ impl Settings {
}
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn update_java() {
let res = async {
let state = State::get().await?;
+4
View File
@@ -20,6 +20,8 @@ pub struct Tags {
}
impl Tags {
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn init(
dirs: &DirectoryInfo,
io_semaphore: &IoSemaphore,
@@ -50,6 +52,8 @@ impl Tags {
}
}
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn update() {
let res = async {
let state = crate::State::get().await?;
+2
View File
@@ -66,6 +66,7 @@ where
/// Downloads a file with retry and checksum functionality
#[tracing::instrument(skip(json_body, semaphore))]
#[theseus_macros::debug_pin]
pub async fn fetch_advanced(
method: Method,
url: &str,
@@ -158,6 +159,7 @@ pub async fn fetch_advanced(
/// Downloads a file from specified mirrors
#[tracing::instrument(skip(semaphore))]
#[theseus_macros::debug_pin]
pub async fn fetch_mirrors(
mirrors: &[&str],
sha1: Option<&str>,
+2
View File
@@ -185,6 +185,7 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
// Gets all JREs from the PATH env variable
#[tracing::instrument]
#[theseus_macros::debug_pin]
async fn get_all_autoinstalled_jre_path() -> Result<HashSet<PathBuf>, JREError>
{
Box::pin(async move {
@@ -247,6 +248,7 @@ pub async fn check_java_at_filepaths(
// For example filepath 'path', attempt to resolve it and get a Java version at this path
// If no such path exists, or no such valid java at this path exists, returns None
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn check_java_at_filepath(path: &Path) -> Option<JavaVersion> {
// Attempt to canonicalize the potential java filepath
// If it fails, this path does not exist and None is returned (no Java here)
+1
View File
@@ -16,6 +16,7 @@ regex = "1.5"
[dependencies]
theseus = { path = "../../theseus", features = ["tauri"] }
theseus_macros = { path = "../../theseus_macros" }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
+7 -2
View File
@@ -4,6 +4,7 @@ use theseus::prelude::*;
/// Authenticate a user with Hydra - part 1
/// This begins the authentication flow quasi-synchronously, returning a URL to visit (that the user will sign in at)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn auth_authenticate_begin_flow() -> Result<url::Url> {
Ok(auth::authenticate_begin_flow().await?)
}
@@ -12,6 +13,7 @@ pub async fn auth_authenticate_begin_flow() -> Result<url::Url> {
/// This completes the authentication flow quasi-synchronously, returning the sign-in credentials
/// (and also adding the credentials to the state)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn auth_authenticate_await_completion() -> Result<Credentials> {
Ok(auth::authenticate_await_complete_flow().await?)
}
@@ -19,13 +21,13 @@ pub async fn auth_authenticate_await_completion() -> Result<Credentials> {
/// Refresh some credentials using Hydra, if needed
// invoke('auth_refresh',user)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn auth_refresh(user: uuid::Uuid) -> Result<Credentials> {
Ok(auth::refresh(user).await?)
}
/// Remove a user account from the database
// invoke('auth_remove_user',user)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn auth_remove_user(user: uuid::Uuid) -> Result<()> {
Ok(auth::remove_user(user).await?)
}
@@ -33,6 +35,7 @@ pub async fn auth_remove_user(user: uuid::Uuid) -> Result<()> {
/// Check if a user exists in Theseus
// invoke('auth_has_user',user)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn auth_has_user(user: uuid::Uuid) -> Result<bool> {
Ok(auth::has_user(user).await?)
}
@@ -40,6 +43,7 @@ pub async fn auth_has_user(user: uuid::Uuid) -> Result<bool> {
/// Get a copy of the list of all user credentials
// invoke('auth_users',user)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn auth_users() -> Result<Vec<Credentials>> {
Ok(auth::users().await?)
}
@@ -48,6 +52,7 @@ pub async fn auth_users() -> Result<Vec<Credentials>> {
/// Prefer to use refresh instead, as it will refresh the credentials as well
// invoke('auth_users',user)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn auth_get_user(user: uuid::Uuid) -> Result<Credentials> {
Ok(auth::get_user(user).await?)
}
+9
View File
@@ -6,24 +6,28 @@ use theseus::prelude::*;
/// Get all JREs that exist on the system
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn jre_get_all_jre() -> Result<Vec<JavaVersion>> {
Ok(jre::get_all_jre().await?)
}
// Finds the isntallation of Java 7, if it exists
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn jre_find_jre_8_jres() -> Result<Vec<JavaVersion>> {
Ok(jre::find_java8_jres().await?)
}
// finds the installation of Java 17, if it exists
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn jre_find_jre_17_jres() -> Result<Vec<JavaVersion>> {
Ok(jre::find_java17_jres().await?)
}
// Finds the highest version of Java 18+, if it exists
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn jre_find_jre_18plus_jres() -> Result<Vec<JavaVersion>> {
Ok(jre::find_java18plus_jres().await?)
}
@@ -31,6 +35,7 @@ pub async fn jre_find_jre_18plus_jres() -> Result<Vec<JavaVersion>> {
// Autodetect Java globals, by searching the users computer.
// Returns a *NEW* JavaGlobals that can be put into Settings
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn jre_autodetect_java_globals() -> Result<JavaGlobals> {
Ok(jre::autodetect_java_globals().await?)
}
@@ -38,6 +43,7 @@ pub async fn jre_autodetect_java_globals() -> Result<JavaGlobals> {
// Validates java globals, by checking if the paths exist
// If false, recommend to direct them to reassign, or to re-guess
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn jre_validate_globals() -> Result<bool> {
Ok(jre::validate_globals().await?)
}
@@ -45,18 +51,21 @@ pub async fn jre_validate_globals() -> Result<bool> {
// Validates JRE at a given path
// Returns None if the path is not a valid JRE
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn jre_get_jre(path: PathBuf) -> Result<Option<JavaVersion>> {
jre::check_jre(path).await.map_err(|e| e.into())
}
// Auto installs java for the given java version
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn jre_auto_install_java(java_version: u32) -> Result<PathBuf> {
Ok(jre::auto_install_java(java_version).await?)
}
// Gets the maximum memory a system has available.
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn jre_get_max_memory() -> Result<u64> {
Ok(jre::get_max_memory().await?)
}
+6
View File
@@ -14,6 +14,7 @@ pub struct Logs {
/// Get all Logs for a profile, sorted by datetime
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn logs_get_logs(
profile_uuid: Uuid,
clear_contents: Option<bool>,
@@ -29,6 +30,7 @@ pub async fn logs_get_logs(
/// Get a Log struct for a profile by profile id and datetime string
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn logs_get_logs_by_datetime(
profile_uuid: Uuid,
datetime_string: String,
@@ -38,6 +40,7 @@ pub async fn logs_get_logs_by_datetime(
/// Get the stdout for a profile by profile id and datetime string
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn logs_get_stdout_by_datetime(
profile_uuid: Uuid,
datetime_string: String,
@@ -47,6 +50,7 @@ pub async fn logs_get_stdout_by_datetime(
/// Get the stderr for a profile by profile id and datetime string
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn logs_get_stderr_by_datetime(
profile_uuid: Uuid,
datetime_string: String,
@@ -56,12 +60,14 @@ pub async fn logs_get_stderr_by_datetime(
/// Delete all logs for a profile by profile id
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn logs_delete_logs(profile_uuid: Uuid) -> Result<()> {
Ok(logs::delete_logs(profile_uuid).await?)
}
/// Delete a log for a profile by profile id and datetime string
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn logs_delete_logs_by_datetime(
profile_uuid: Uuid,
datetime_string: String,
@@ -4,24 +4,28 @@ use daedalus::modded::Manifest;
/// Gets the game versions from daedalus
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn metadata_get_game_versions() -> Result<VersionManifest> {
Ok(theseus::metadata::get_minecraft_versions().await?)
}
/// Gets the fabric versions from daedalus
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn metadata_get_fabric_versions() -> Result<Manifest> {
Ok(theseus::metadata::get_fabric_versions().await?)
}
/// Gets the forge versions from daedalus
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn metadata_get_forge_versions() -> Result<Manifest> {
Ok(theseus::metadata::get_forge_versions().await?)
}
/// Gets the quilt versions from daedalus
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn metadata_get_quilt_versions() -> Result<Manifest> {
Ok(theseus::metadata::get_quilt_versions().await?)
}
+1
View File
@@ -47,6 +47,7 @@ where
// Create a new HashMap with the same keys
// Values provided should not be used directly, as they are not guaranteed to be up-to-date
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn progress_bars_list(
) -> Result<std::collections::HashMap<uuid::Uuid, theseus::LoadingBar>> {
let res = theseus::EventState::list_progress_bars().await?;
+2
View File
@@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
use theseus::prelude::*;
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn pack_install_version_id(
version_id: String,
pack_title: String,
@@ -15,6 +16,7 @@ pub async fn pack_install_version_id(
}
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn pack_install_file(path: &Path) -> Result<PathBuf> {
let res = pack::install_pack_from_file(path.to_path_buf()).await?;
Ok(res)
+11
View File
@@ -6,12 +6,14 @@ use uuid::Uuid;
// Checks if a process has finished by process UUID
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_has_finished_by_uuid(uuid: Uuid) -> Result<bool> {
Ok(process::has_finished_by_uuid(&uuid).await?)
}
// Gets process exit status by process UUID
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_get_exit_status_by_uuid(
uuid: Uuid,
) -> Result<Option<i32>> {
@@ -20,18 +22,21 @@ pub async fn process_get_exit_status_by_uuid(
// Gets all process UUIDs
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_get_all_uuids() -> Result<Vec<Uuid>> {
Ok(process::get_all_uuids().await?)
}
// Gets all running process UUIDs
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_get_all_running_uuids() -> Result<Vec<Uuid>> {
Ok(process::get_all_running_uuids().await?)
}
// Gets all process UUIDs by profile path
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_get_uuids_by_profile_path(
profile_path: &Path,
) -> Result<Vec<Uuid>> {
@@ -40,36 +45,42 @@ pub async fn process_get_uuids_by_profile_path(
// Gets the Profile paths of each *running* stored process in the state
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_get_all_running_profile_paths() -> Result<Vec<PathBuf>> {
Ok(process::get_all_running_profile_paths().await?)
}
// Gets the Profiles (cloned) of each *running* stored process in the state
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_get_all_running_profiles() -> Result<Vec<Profile>> {
Ok(process::get_all_running_profiles().await?)
}
// Gets process stderr by process UUID
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_get_stderr_by_uuid(uuid: Uuid) -> Result<String> {
Ok(process::get_stderr_by_uuid(&uuid).await?)
}
// Gets process stdout by process UUID
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_get_stdout_by_uuid(uuid: Uuid) -> Result<String> {
Ok(process::get_stdout_by_uuid(&uuid).await?)
}
// Kill a process by process UUID
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_kill_by_uuid(uuid: Uuid) -> Result<()> {
Ok(process::kill_by_uuid(&uuid).await?)
}
// Wait for a process to finish by process UUID
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn process_wait_for_by_uuid(uuid: Uuid) -> Result<()> {
Ok(process::wait_for_by_uuid(&uuid).await?)
}
+16
View File
@@ -8,6 +8,7 @@ use uuid::Uuid;
// Remove a profile
// invoke('profile_add_path',path)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_remove(path: &Path) -> Result<()> {
profile::remove(path).await?;
Ok(())
@@ -16,6 +17,7 @@ pub async fn profile_remove(path: &Path) -> Result<()> {
// Get a profile by path
// invoke('profile_add_path',path)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_get(
path: &Path,
clear_projects: Option<bool>,
@@ -27,6 +29,7 @@ pub async fn profile_get(
// Get a copy of the profile set
// invoke('profile_list')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_list(
clear_projects: Option<bool>,
) -> Result<std::collections::HashMap<PathBuf, Profile>> {
@@ -35,6 +38,7 @@ pub async fn profile_list(
}
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_check_installed(
path: &Path,
project_id: String,
@@ -57,6 +61,7 @@ pub async fn profile_check_installed(
/// Installs/Repairs a profile
/// invoke('profile_install')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_install(path: &Path) -> Result<()> {
profile::install(path).await?;
Ok(())
@@ -65,6 +70,7 @@ pub async fn profile_install(path: &Path) -> Result<()> {
/// Updates all of the profile's projects
/// invoke('profile_update_all')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_update_all(path: &Path) -> Result<()> {
profile::update_all(path).await?;
Ok(())
@@ -73,6 +79,7 @@ pub async fn profile_update_all(path: &Path) -> Result<()> {
/// Updates a specified project
/// invoke('profile_update_project')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_update_project(
path: &Path,
project_path: &Path,
@@ -84,6 +91,7 @@ pub async fn profile_update_project(
// Adds a project to a profile from a version ID
// invoke('profile_add_project_from_version')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_add_project_from_version(
path: &Path,
version_id: String,
@@ -95,6 +103,7 @@ pub async fn profile_add_project_from_version(
// Adds a project to a profile from a path
// invoke('profile_add_project_from_path')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_add_project_from_path(
path: &Path,
project_path: &Path,
@@ -108,6 +117,7 @@ pub async fn profile_add_project_from_path(
// Toggles disabling a project from its path
// invoke('profile_toggle_disable_project')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_toggle_disable_project(
path: &Path,
project_path: &Path,
@@ -119,6 +129,7 @@ pub async fn profile_toggle_disable_project(
// Removes a project from a profile
// invoke('profile_remove_project')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_remove_project(
path: &Path,
project_path: &Path,
@@ -131,6 +142,7 @@ pub async fn profile_remove_project(
// for the actual Child in the state.
// invoke('profile_run', path)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_run(path: &Path) -> Result<Uuid> {
let minecraft_child = profile::run(path).await?;
let uuid = minecraft_child.read().await.uuid;
@@ -140,6 +152,7 @@ pub async fn profile_run(path: &Path) -> Result<Uuid> {
// Run Minecraft using a profile using the default credentials, and wait for the result
// invoke('profile_run_wait', path)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_run_wait(path: &Path) -> Result<()> {
let proc_lock = profile::run(path).await?;
let mut proc = proc_lock.write().await;
@@ -151,6 +164,7 @@ pub async fn profile_run_wait(path: &Path) -> Result<()> {
// for the actual Child in the state.
// invoke('profile_run_credentials', {path, credentials})')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_run_credentials(
path: &Path,
credentials: Credentials,
@@ -163,6 +177,7 @@ pub async fn profile_run_credentials(
// Run Minecraft using a profile using the chosen credentials, and wait for the result
// invoke('profile_run_wait', {path, credentials)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_run_wait_credentials(
path: &Path,
credentials: Credentials,
@@ -192,6 +207,7 @@ pub struct EditProfileMetadata {
// Edits a profile
// invoke('profile_edit', {path, editProfile})
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_edit(
path: &Path,
edit_profile: EditProfile,
@@ -5,6 +5,7 @@ use theseus::prelude::*;
// Generic basic profile creation tool.
// Creates an essentially empty dummy profile with profile_create
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_create_empty() -> Result<PathBuf> {
let res = profile_create::profile_create_empty().await?;
Ok(res)
@@ -13,6 +14,7 @@ pub async fn profile_create_empty() -> Result<PathBuf> {
// Creates a profile at the given filepath and adds it to the in-memory state
// invoke('profile_add',profile)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn profile_create(
name: String, // the name of the profile, and relative path
game_version: String, // the game version of the profile
@@ -23,6 +23,7 @@ pub struct FrontendSettings {
// Get full settings
// invoke('settings_get')
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn settings_get() -> Result<FrontendSettings> {
let backend_settings = settings::get().await?;
let frontend_settings = FrontendSettings {
@@ -50,6 +51,7 @@ pub async fn settings_get() -> Result<FrontendSettings> {
// Set full settings
// invoke('settings_set', settings)
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn settings_set(settings: FrontendSettings) -> Result<()> {
let custom_env_args: Vec<(String, String)> = settings
.custom_env_args
+6
View File
@@ -3,36 +3,42 @@ use theseus::tags::{Category, DonationPlatform, GameVersion, Loader, Tags};
/// Gets cached category tags from the database
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn tags_get_categories() -> Result<Vec<Category>> {
Ok(theseus::tags::get_category_tags().await?)
}
/// Gets cached report type tags from the database
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn tags_get_report_types() -> Result<Vec<String>> {
Ok(theseus::tags::get_report_type_tags().await?)
}
/// Gets cached loader tags from the database
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn tags_get_loaders() -> Result<Vec<Loader>> {
Ok(theseus::tags::get_loader_tags().await?)
}
/// Gets cached game version tags from the database
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn tags_get_game_versions() -> Result<Vec<GameVersion>> {
Ok(theseus::tags::get_game_version_tags().await?)
}
/// Gets cached donation platform tags from the database
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn tags_get_donation_platforms() -> Result<Vec<DonationPlatform>> {
Ok(theseus::tags::get_donation_platform_tags().await?)
}
/// Gets cached tag bundle from the database
#[tauri::command]
#[theseus_macros::debug_pin]
pub async fn tags_get_tag_bundle() -> Result<Tags> {
Ok(theseus::tags::get_tag_bundle().await?)
}
+3
View File
@@ -13,6 +13,7 @@ mod error;
// Should be called in launcher initialization
#[tauri::command]
#[theseus_macros::debug_pin]
async fn initialize_state(app: tauri::AppHandle) -> api::Result<()> {
theseus::EventState::init(app).await?;
State::get().await?;
@@ -24,6 +25,7 @@ async fn initialize_state(app: tauri::AppHandle) -> api::Result<()> {
// disables mouseover and fixes a random crash error only fixed by recent versions of macos
#[cfg(target_os = "macos")]
#[tauri::command]
#[theseus_macros::debug_pin]
async fn should_disable_mouseover() -> bool {
// We try to match version to 12.2 or higher. If unrecognizable to pattern or lower, we default to the css with disabled mouseover for safety
let os = os_info::get();
@@ -37,6 +39,7 @@ async fn should_disable_mouseover() -> bool {
}
#[cfg(not(target_os = "macos"))]
#[tauri::command]
#[theseus_macros::debug_pin]
async fn should_disable_mouseover() -> bool {
false
}
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "theseus_macros"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
syn = { version = "1.0", features = ["full"] }
quote = "1.0"
+36
View File
@@ -0,0 +1,36 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemFn};
#[proc_macro_attribute]
pub fn debug_pin(_attr: TokenStream, item: TokenStream) -> TokenStream {
// Parse the input tokens into a syntax tree
let input = parse_macro_input!(item as ItemFn);
let attrs = &input.attrs;
let vis = &input.vis; // visibility modifier
let sig = &input.sig; // function signature
let body = &input.block;
// Use cfg attribute for conditional compilation
let result = quote! {
#[cfg(debug_assertions)]
#(#attrs) *
#vis #sig {
Box::pin(async move {
#body
}).await
}
#[cfg(not(debug_assertions))]
#(#attrs) *
#vis #sig {
#body
}
};
// Hand the output tokens back to the compiler
TokenStream::from(result)
}