├── .envrc ├── src ├── cli │ ├── mod.rs │ └── clap.rs ├── consts │ ├── mod.rs │ └── defaults.rs ├── state │ ├── mod.rs │ └── options.rs ├── server │ ├── routes │ │ ├── index.rs │ │ ├── mod.rs │ │ ├── winecfg.rs │ │ ├── winetricks.rs │ │ ├── open.rs │ │ └── init.rs │ ├── mod.rs │ ├── serve.rs │ └── router.rs ├── lib.rs ├── client │ ├── mod.rs │ ├── request.rs │ ├── get_target_machine.rs │ ├── desktop.rs │ ├── ctrlc.rs │ ├── xauth.rs │ ├── icon.rs │ └── exec.rs ├── util.rs └── main.rs ├── .gitignore ├── nix ├── shell.nix ├── osu.nix ├── module.nix └── package.nix ├── .github ├── SECURITY.md ├── dependabot.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── ci.yml ├── tests ├── xauth.rs ├── options.rs ├── icon.rs └── release.rs ├── flake.lock ├── flake.nix ├── Cargo.toml ├── LICENSE ├── README.md └── Cargo.lock /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /src/cli/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod clap; 2 | pub use clap::*; 3 | -------------------------------------------------------------------------------- /src/consts/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod defaults; 2 | pub use defaults::*; 3 | -------------------------------------------------------------------------------- /src/state/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod options; 2 | 3 | pub use options::*; 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | result 3 | 4 | *.exe 5 | *.ico 6 | *.png 7 | 8 | .direnv 9 | -------------------------------------------------------------------------------- /src/server/routes/index.rs: -------------------------------------------------------------------------------- 1 | pub async fn index() -> String { 2 | "sakaya".to_string() 3 | } 4 | -------------------------------------------------------------------------------- /nix/shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs }: 2 | 3 | { 4 | buildInputs = [ 5 | (pkgs.callPackage ./osu.nix { }) 6 | ]; 7 | } 8 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod cli; 2 | pub mod client; 3 | pub mod consts; 4 | pub mod server; 5 | pub mod state; 6 | pub mod util; 7 | -------------------------------------------------------------------------------- /src/server/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod router; 2 | pub mod routes; 3 | pub mod serve; 4 | 5 | pub use router::*; 6 | pub use serve::*; 7 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting a Vulnerability 2 | 3 | To privately report a security issue, use the contact information available on . 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "cargo" 5 | directory: "/" 6 | schedule: 7 | interval: "monthly" 8 | -------------------------------------------------------------------------------- /tests/xauth.rs: -------------------------------------------------------------------------------- 1 | use sakaya::client::make_xauth; 2 | use std::path::Path; 3 | 4 | #[test] 5 | #[ignore] 6 | fn xauth() { 7 | make_xauth(); 8 | 9 | assert!(Path::new("/tmp/.X11-unix/Xauthority").exists()); 10 | } 11 | -------------------------------------------------------------------------------- /tests/options.rs: -------------------------------------------------------------------------------- 1 | use sakaya::state::Options; 2 | 3 | #[test] 4 | #[ignore] 5 | fn options_default() { 6 | let options: Options = Default::default(); 7 | 8 | assert_eq!(options.wine_prefix, "/mnt/wine32"); 9 | } 10 | -------------------------------------------------------------------------------- /src/server/routes/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod index; 2 | pub mod init; 3 | pub mod open; 4 | pub mod winecfg; 5 | pub mod winetricks; 6 | 7 | pub use index::*; 8 | pub use init::*; 9 | pub use open::*; 10 | pub use winecfg::*; 11 | pub use winetricks::*; 12 | -------------------------------------------------------------------------------- /src/consts/defaults.rs: -------------------------------------------------------------------------------- 1 | pub const DEFAULT_WINE32_PREFIX: &str = "/mnt/wine32"; 2 | pub const DEFAULT_WINE64_PREFIX: &str = "/mnt/wine64"; 3 | pub const DEFAULT_PORT: u16 = 39493; 4 | pub const DEFAULT_ADDRESS: &str = "0.0.0.0:39493"; 5 | pub const DEFAULT_LOCALE: &str = "ja_JP.UTF-8"; 6 | pub const DEFAULT_TIMEZONE: &str = "Asia/Tokyo"; 7 | -------------------------------------------------------------------------------- /src/server/serve.rs: -------------------------------------------------------------------------------- 1 | use std::net::SocketAddrV4; 2 | use tokio::net::TcpListener; 3 | 4 | use super::router; 5 | 6 | pub async fn serve(address: SocketAddrV4) { 7 | let router = router(); 8 | let listener = TcpListener::bind(address).await.unwrap(); 9 | 10 | axum::serve(listener, router).await.unwrap(); 11 | } 12 | -------------------------------------------------------------------------------- /src/client/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod ctrlc; 2 | pub mod desktop; 3 | pub mod exec; 4 | pub mod get_target_machine; 5 | pub mod icon; 6 | pub mod request; 7 | pub mod xauth; 8 | 9 | pub use ctrlc::*; 10 | pub use desktop::*; 11 | pub use exec::*; 12 | pub use get_target_machine::*; 13 | pub use icon::*; 14 | pub use request::*; 15 | pub use xauth::*; 16 | -------------------------------------------------------------------------------- /src/server/router.rs: -------------------------------------------------------------------------------- 1 | use axum::routing::{get, post}; 2 | use axum::Router; 3 | 4 | use super::routes; 5 | 6 | pub fn router() -> Router { 7 | Router::new() 8 | .route("/", get(routes::index)) 9 | .route("/open", post(routes::open)) 10 | .route("/init", post(routes::init)) 11 | .route("/winecfg", post(routes::winecfg)) 12 | .route("/winetricks", post(routes::winetricks)) 13 | } 14 | -------------------------------------------------------------------------------- /nix/osu.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenvNoCC, 3 | fetchzip, 4 | }: 5 | 6 | stdenvNoCC.mkDerivation { 7 | pname = "osu"; 8 | version = "0-unstable-2023-12-19"; 9 | 10 | src = fetchzip { 11 | url = "https://osekai.net/snapshots/versions/b20231219.2/b20231219.2.zip"; 12 | hash = "sha256-7c1czJFuw+KAr7HoPUBRBieMUtr4hH805UzcEIcD1ok="; 13 | stripRoot = false; 14 | }; 15 | 16 | postInstall = '' 17 | install -Dm755 osu!.exe $out/bin/osu!.exe 18 | ''; 19 | } 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Did you run into an issue while using sakaya? 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Bug Report 11 | 12 | ## Environment 13 | 14 | - Output of `uname -a`: 15 | - Output of `sakaya -V`: 16 | 17 | ## Expected Behavior 18 | Tell us what should have happened. 19 | 20 | ## Current Behavior 21 | Tell us what happens instead of the expected behavior. 22 | 23 | ## Step to Reproduce 24 | Please provide the steps to reproduce the issue. 25 | -------------------------------------------------------------------------------- /src/util.rs: -------------------------------------------------------------------------------- 1 | use notify_rust::Notification; 2 | use std::fs; 3 | 4 | /// Checks if we're inside a container 5 | pub fn is_container() -> bool { 6 | fs::read("/run/systemd/container").is_ok() 7 | } 8 | 9 | /// Notifies the user of an event 10 | pub fn notify(body: &str, mut icon: Option<&str>) { 11 | println!("{body}"); 12 | 13 | Notification::new() 14 | .summary("酒屋") 15 | .body(body) 16 | .icon(icon.get_or_insert("sakaya")) 17 | .timeout(3000) 18 | .show() 19 | .unwrap(); 20 | } 21 | -------------------------------------------------------------------------------- /src/client/request.rs: -------------------------------------------------------------------------------- 1 | use std::net::SocketAddrV4; 2 | 3 | use crate::state::Options; 4 | 5 | /// Sends a request to start an application inside a container 6 | pub fn request( 7 | address: SocketAddrV4, 8 | path: &str, 9 | wine_prefix: &str, 10 | arguments: &[String], 11 | command: &str, 12 | ) -> Result<(), minreq::Error> { 13 | let opts = Options::new(path, wine_prefix, arguments); 14 | 15 | let url = format!("http://{address}/{command}"); 16 | let response = minreq::post(url).with_json(&opts)?.send()?; 17 | 18 | print!("{}", response.as_str()?); 19 | 20 | Ok(()) 21 | } 22 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "nixpkgs": { 4 | "locked": { 5 | "lastModified": 1745930157, 6 | "narHash": "sha256-y3h3NLnzRSiUkYpnfvnS669zWZLoqqI6NprtLQ+5dck=", 7 | "owner": "nixos", 8 | "repo": "nixpkgs", 9 | "rev": "46e634be05ce9dc6d4db8e664515ba10b78151ae", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "owner": "nixos", 14 | "ref": "nixos-unstable", 15 | "repo": "nixpkgs", 16 | "type": "github" 17 | } 18 | }, 19 | "root": { 20 | "inputs": { 21 | "nixpkgs": "nixpkgs" 22 | } 23 | } 24 | }, 25 | "root": "root", 26 | "version": 7 27 | } 28 | -------------------------------------------------------------------------------- /src/client/get_target_machine.rs: -------------------------------------------------------------------------------- 1 | use pelite::{ 2 | image::{IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_I386}, 3 | FileMap, PeFile, 4 | }; 5 | 6 | /// Gets whether the exe is 32 or 64-bit 7 | /// 8 | /// https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src/Debug/pe-format.md#machine-types 9 | pub fn get_target_machine(input_bin: &str) -> u8 { 10 | let map = FileMap::open(input_bin).expect("Error opening the binary"); 11 | let file = PeFile::from_bytes(&map).expect("Error parsing the binary"); 12 | let target_machine = file.file_header().Machine; 13 | 14 | match target_machine { 15 | IMAGE_FILE_MACHINE_I386 => 32, 16 | IMAGE_FILE_MACHINE_AMD64 => 64, 17 | _ => 0, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project. 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Feature Request 11 | 12 | ## Summary 13 | Briefly describe what this feature request is about. 14 | 15 | ## Motivation 16 | Why should this feature be implemented? How will it benefit the project and its users? 17 | 18 | ## Detailed Description 19 | Please provide a detailed description of the proposed feature, including any suggestions you have for how it could be implemented. 20 | 21 | ## Additional Context 22 | Add any other context or screenshots about the feature request here. If this feature request is related to a problem, please describe it. 23 | -------------------------------------------------------------------------------- /src/client/desktop.rs: -------------------------------------------------------------------------------- 1 | use home::home_dir; 2 | use std::fs::write; 3 | 4 | /// Makes a desktop file for the application 5 | pub fn make_desktop_file(file_name: &str, full_path: &str) { 6 | let home = home_dir().unwrap(); 7 | let home = home.to_str().unwrap(); 8 | 9 | let output_location = &format!("{home}/.local/share/applications/{file_name}.desktop"); 10 | 11 | let mut output: String = "[Desktop Entry]".to_owned() + "\n"; 12 | 13 | output.push_str("Type=Application\n"); 14 | output.push_str(&("Name=".to_owned() + file_name + "\n")); 15 | output.push_str(&("Icon=".to_owned() + file_name + "\n")); 16 | output.push_str(&("Exec=sakaya \"".to_owned() + full_path + "\"\n")); 17 | 18 | let _ = write(output_location, output); 19 | } 20 | -------------------------------------------------------------------------------- /src/server/routes/winecfg.rs: -------------------------------------------------------------------------------- 1 | use axum::extract::Json; 2 | use std::process::{Command, Output}; 3 | 4 | use crate::state::Options; 5 | 6 | pub async fn winecfg(Json(options): Json) -> Result { 7 | let Ok(Output { stdout, stderr, .. }) = Command::new("winecfg") 8 | .envs(Options::vars(&options)) 9 | .arg(options.path) 10 | .args(options.arguments) 11 | .output() 12 | else { 13 | return Err("Error while trying to run winecfg."); 14 | }; 15 | 16 | let Ok(stdout) = String::from_utf8(stdout) else { 17 | return Err("winecfg returned invalid stdout."); 18 | }; 19 | 20 | let Ok(stderr) = String::from_utf8(stderr) else { 21 | return Err("winecfg returned invalid stderr."); 22 | }; 23 | 24 | Ok(format!("stdout:\n{stdout}\nstderr:\n{stderr}")) 25 | } 26 | -------------------------------------------------------------------------------- /src/server/routes/winetricks.rs: -------------------------------------------------------------------------------- 1 | use axum::extract::Json; 2 | use std::process::{Command, Output}; 3 | 4 | use crate::state::Options; 5 | 6 | pub async fn winetricks(Json(options): Json) -> Result { 7 | let Ok(Output { stdout, stderr, .. }) = Command::new("winetricks") 8 | .envs(Options::vars(&options)) 9 | .arg(options.path) 10 | .args(options.arguments) 11 | .output() 12 | else { 13 | return Err("Error while trying to run winetricks."); 14 | }; 15 | 16 | let Ok(stdout) = String::from_utf8(stdout) else { 17 | return Err("winetricks returned invalid stdout."); 18 | }; 19 | 20 | let Ok(stderr) = String::from_utf8(stderr) else { 21 | return Err("winetricks returned invalid stderr."); 22 | }; 23 | 24 | Ok(format!("stdout:\n{stdout}\nstderr:\n{stderr}")) 25 | } 26 | -------------------------------------------------------------------------------- /src/client/ctrlc.rs: -------------------------------------------------------------------------------- 1 | use std::process::{Command, Output}; 2 | use std::sync::mpsc; 3 | use std::thread; 4 | 5 | use crate::util::notify; 6 | 7 | pub fn ctrlc(file_name: String) { 8 | thread::spawn(move || -> anyhow::Result<()> { 9 | let (tx, rx) = mpsc::channel(); 10 | 11 | ctrlc::set_handler(move || tx.send(()).unwrap())?; 12 | 13 | rx.recv()?; 14 | 15 | println!(); 16 | 17 | if let Ok(Output { .. }) = Command::new("killall").arg(&file_name).output() { 18 | notify(&format!("Kill request received for {}.", &file_name), None); 19 | 20 | return Ok(()); 21 | } 22 | 23 | notify( 24 | &format!( 25 | "Error while trying to kill {}. Try killing from htop.", 26 | &file_name 27 | ), 28 | None, 29 | ); 30 | 31 | Ok(()) 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /src/server/routes/open.rs: -------------------------------------------------------------------------------- 1 | use axum::extract::Json; 2 | use std::process::{Command, Output}; 3 | 4 | use crate::state::Options; 5 | 6 | /// Open an executable in wine 7 | pub async fn open(Json(options): Json) -> Result { 8 | let Ok(Output { stdout, stderr, .. }) = Command::new("wineconsole") 9 | .envs(Options::vars(&options)) 10 | .arg(options.path) 11 | .args(options.arguments) 12 | .output() 13 | else { 14 | return Err("Error while trying to run the wine command."); 15 | }; 16 | 17 | let Ok(stdout) = String::from_utf8(stdout) else { 18 | return Err("The program returned invalid stdout."); 19 | }; 20 | 21 | let Ok(stderr) = String::from_utf8(stderr) else { 22 | return Err("The program returned invalid stderr."); 23 | }; 24 | 25 | Ok(format!("stdout:\n{stdout}\nstderr:\n{stderr}")) 26 | } 27 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Run native wine applications inside declarative systemd-nspawn containers"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 6 | }; 7 | 8 | outputs = 9 | { nixpkgs, ... }: 10 | let 11 | pkgs = nixpkgs.legacyPackages.x86_64-linux; 12 | 13 | inherit (pkgs) nixfmt-rfc-style callPackage; 14 | in 15 | { 16 | formatter.x86_64-linux = nixfmt-rfc-style; 17 | 18 | packages.x86_64-linux = { 19 | osu = callPackage ./nix/osu.nix { }; 20 | sakaya = callPackage ./nix/package.nix { }; 21 | default = callPackage ./nix/package.nix { }; 22 | }; 23 | 24 | nixosModules = { 25 | sakaya = import ./nix/module.nix; 26 | default = import ./nix/module.nix; 27 | }; 28 | 29 | devShells.x86_64-linux.default = pkgs.mkShell (import ./nix/shell.nix { 30 | inherit pkgs; 31 | }); 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /tests/icon.rs: -------------------------------------------------------------------------------- 1 | use sakaya::client::convert_largest_square_image_in_ico_to_png; 2 | use sakaya::client::get_first_ico_file; 3 | 4 | #[test] 5 | #[ignore] 6 | fn gets_ico_from_osu_exe() { 7 | // https://m1.ppy.sh/r/osu!install.exe 8 | assert!( 9 | get_first_ico_file("./in-out/osu!install.exe").is_some(), 10 | "osu!install.exe returns an ico group" 11 | ); 12 | } 13 | 14 | #[test] 15 | #[ignore] 16 | fn gets_largest_osu_icon() { 17 | if let Some(ico) = get_first_ico_file("./in-out/osu!install.exe") { 18 | assert!( 19 | convert_largest_square_image_in_ico_to_png(ico, "./in-out/osu!install.png").is_ok() 20 | ); 21 | } 22 | } 23 | 24 | #[test] 25 | #[ignore] 26 | fn gets_the_first_icon_if_there_is_only_one() { 27 | if let Some(ico) = get_first_ico_file("./in-out/test.exe") { 28 | assert!(convert_largest_square_image_in_ico_to_png(ico, "./in-out/test.png").is_ok()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/client/xauth.rs: -------------------------------------------------------------------------------- 1 | use std::env::var; 2 | use std::process::{Command, Stdio}; 3 | 4 | pub fn make_xauth() { 5 | let display = var("DISPLAY").unwrap(); 6 | let xauth_file = "/tmp/.X11-unix/Xauthority"; 7 | 8 | let xauth_child = Command::new("xauth") 9 | .arg("nextract") 10 | .arg("-") 11 | .arg(display) 12 | .stdout(Stdio::piped()) 13 | .spawn() 14 | .unwrap() 15 | .stdout 16 | .unwrap(); 17 | 18 | let sed_child = Command::new("sed") 19 | .arg("-e") 20 | .arg("s/^..../ffff/") 21 | .stdin(Stdio::from(xauth_child)) 22 | .stdout(Stdio::piped()) 23 | .spawn() 24 | .unwrap() 25 | .stdout 26 | .unwrap(); 27 | 28 | Command::new("xauth") 29 | .arg("-f") 30 | .arg(xauth_file) 31 | .arg("nmerge") 32 | .arg("-") 33 | .stdin(Stdio::from(sed_child)) 34 | .stdout(Stdio::piped()) 35 | .spawn() 36 | .unwrap() 37 | .wait_with_output() 38 | .unwrap(); 39 | } 40 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sakaya" 3 | description = "Run native wine applications inside declarative systemd-nspawn containers." 4 | version = "0.1.0" 5 | authors = ["Copyright (C) 2023-2025 Donovan Glover "] 6 | repository = "https://github.com/donovanglover/sakaya" 7 | license = "MIT" 8 | edition = "2021" 9 | 10 | [dependencies] 11 | anyhow = "1.0.98" 12 | axum = "0.8.1" 13 | clap = { version = "4.5.31", features = ["derive"] } 14 | ctrlc = { version = "3.4.6", features = ["termination"] } 15 | home = "0.5.11" 16 | ico = "0.4.0" 17 | local-ip-address = "0.6.3" 18 | minreq = { version = "2.13.2", features = ["json-using-serde"] } 19 | notify-rust = "4.11.5" 20 | pelite = "0.10.0" 21 | serde = "1.0.218" 22 | tokio = { version = "1.43.0", features = ["full"] } 23 | urlencoding = "2.1.3" 24 | 25 | [build-dependencies] 26 | clap = { version = "4.5.31", features = ["derive"] } 27 | clap_complete = "4.5.46" 28 | clap_mangen = "0.2.26" 29 | 30 | [dev-dependencies] 31 | assert_cmd = "2.0.16" 32 | rustympkglib = "0.1.1" 33 | serde = "1.0.218" 34 | toml = "0.8.15" 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2023-2025 Donovan Glover 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | RUSTFLAGS: -Dwarnings 12 | 13 | jobs: 14 | build: 15 | name: cargo build 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v3 19 | - run: cargo build 20 | test: 21 | name: cargo test 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v3 25 | - run: cargo test 26 | format: 27 | name: cargo fmt --check 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@v3 31 | - run: cargo fmt --check 32 | clippy: 33 | name: cargo clippy 34 | runs-on: ubuntu-latest 35 | steps: 36 | - uses: actions/checkout@v3 37 | - run: cargo clippy 38 | nix_check: 39 | name: nix flake check 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v3 43 | - uses: cachix/install-nix-action@v22 44 | - run: nix flake check 45 | nix_build: 46 | name: nix build 47 | runs-on: ubuntu-latest 48 | steps: 49 | - uses: actions/checkout@v3 50 | - uses: cachix/install-nix-action@v22 51 | - run: nix build 52 | -------------------------------------------------------------------------------- /nix/module.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | 3 | let 4 | inherit (lib) mkEnableOption mkOption mkIf; 5 | inherit (lib.types) port str bool; 6 | 7 | package = pkgs.callPackage ./package.nix { }; 8 | 9 | cfg = config.sakaya; 10 | in 11 | { 12 | options.sakaya = { 13 | enable = mkEnableOption "sakaya server"; 14 | 15 | openFirewall = mkOption { 16 | type = bool; 17 | default = true; 18 | description = "Whether to automatically open the specified port in the firewall."; 19 | }; 20 | 21 | username = mkOption { 22 | type = str; 23 | default = "user"; 24 | description = "The user to run sakaya under."; 25 | }; 26 | 27 | port = mkOption { 28 | type = port; 29 | default = 39493; 30 | description = "The port to listen on for HTTP requests."; 31 | }; 32 | }; 33 | 34 | config = mkIf cfg.enable { 35 | systemd.services.sakaya = { 36 | enable = true; 37 | description = "sakaya server"; 38 | unitConfig.Type = "simple"; 39 | path = with pkgs; [ su ]; 40 | serviceConfig.ExecStart = "/usr/bin/env su ${cfg.username} --command='${package}/bin/sakaya server --port ${toString cfg.port}'"; 41 | wantedBy = [ "multi-user.target" ]; 42 | }; 43 | 44 | networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ]; 45 | }; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/server/routes/init.rs: -------------------------------------------------------------------------------- 1 | use axum::extract::Json; 2 | use std::{collections::HashMap, path::Path, process::Command}; 3 | 4 | use crate::{state::Options, util::notify}; 5 | 6 | /// Create a wine prefix 7 | pub async fn init(Json(options): Json) -> Result { 8 | let envs = Options::vars(&options); 9 | 10 | if Path::new(&options.wine_prefix).exists() { 11 | return Ok("Prefix already exists.\n".to_string()); 12 | } 13 | 14 | notify("Initializing wine prefix...", None); 15 | 16 | Command::new("wineboot").envs(&envs).output().unwrap(); 17 | 18 | let commands = [ 19 | "dotnet461", 20 | "mfc42", 21 | "vcrun2022", 22 | "lavfilters", 23 | "dxvk", 24 | "directshow", 25 | "wmp10", 26 | ]; 27 | 28 | winetricks(&commands, envs); 29 | 30 | Ok("Created successfully.\n".to_string()) 31 | } 32 | 33 | fn winetricks(commands: &[&str], envs: HashMap<&str, String>) { 34 | let len = commands.len(); 35 | let mut i = 1; 36 | 37 | for command in commands { 38 | notify( 39 | &format!("Running winetricks {command}... ({i}/{len})"), 40 | None, 41 | ); 42 | 43 | Command::new("winetricks") 44 | .arg("-q") 45 | .arg(command) 46 | .envs(&envs) 47 | .output() 48 | .unwrap(); 49 | 50 | i += 1; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /nix/package.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | rustPlatform, 4 | makeDesktopItem, 5 | installShellFiles, 6 | copyDesktopItems, 7 | makeWrapper, 8 | samba, # some windows programs require samba 9 | killall, 10 | }: 11 | 12 | rustPlatform.buildRustPackage { 13 | pname = "sakaya"; 14 | version = "0.1.0"; 15 | 16 | src = builtins.path { 17 | path = ../.; 18 | name = "sakaya"; 19 | }; 20 | 21 | cargoLock = { 22 | lockFile = ../Cargo.lock; 23 | }; 24 | 25 | nativeBuildInputs = [ 26 | installShellFiles 27 | copyDesktopItems 28 | makeWrapper 29 | ]; 30 | 31 | postInstall = '' 32 | installManPage target/man/sakaya.1 33 | 34 | installShellCompletion --cmd sakaya \ 35 | --bash target/completions/sakaya.bash \ 36 | --fish target/completions/sakaya.fish \ 37 | --zsh target/completions/_sakaya 38 | 39 | wrapProgram $out/bin/sakaya \ 40 | --prefix PATH ":" "${ 41 | lib.makeBinPath [ 42 | samba 43 | killall 44 | ] 45 | }" 46 | ''; 47 | 48 | desktopItems = [ 49 | (makeDesktopItem { 50 | name = "sakaya"; 51 | desktopName = "sakaya"; 52 | icon = "wine"; 53 | exec = "sakaya %U"; 54 | mimeTypes = [ 55 | "application/x-ms-dos-executable" 56 | "application/octet-stream" 57 | ]; 58 | }) 59 | ]; 60 | 61 | meta = with lib; { 62 | description = "Run native wine applications inside declarative systemd-nspawn containers"; 63 | homepage = "https://github.com/donovanglover/sakaya"; 64 | license = licenses.mit; 65 | maintainers = with maintainers; [ donovanglover ]; 66 | mainProgram = "sakaya"; 67 | platforms = platforms.linux; 68 | }; 69 | } 70 | -------------------------------------------------------------------------------- /src/client/icon.rs: -------------------------------------------------------------------------------- 1 | use pelite::{FileMap, PeFile}; 2 | use std::fs::File; 3 | use std::io::Cursor; 4 | 5 | /// Given an .exe file, return the first .ico file inside it 6 | pub fn get_first_ico_file(input_bin: &str) -> Option>> { 7 | let map = FileMap::open(input_bin).expect("Error opening the binary"); 8 | let file = PeFile::from_bytes(&map).expect("Error parsing the binary"); 9 | let resources = file 10 | .resources() 11 | .expect("Error binary does not have resources"); 12 | 13 | if let Some((_, group)) = resources.icons().find_map(Result::ok) { 14 | let mut contents = Vec::new(); 15 | group.write(&mut contents).unwrap(); 16 | 17 | return Some(Cursor::new(contents)); 18 | } 19 | 20 | None 21 | } 22 | 23 | /// Given an .ico with multiple images, return the largest one that's a square 24 | pub fn convert_largest_square_image_in_ico_to_png( 25 | buf: Cursor>, 26 | output_path: &str, 27 | ) -> Result<(), std::io::Error> { 28 | let icondir = ico::IconDir::read(buf)?; 29 | let mut largest_size = 0; 30 | let mut largest_index = 0; 31 | 32 | for (i, image) in icondir.entries().iter().enumerate() { 33 | let width = image.width(); 34 | 35 | if width == image.height() && width > largest_size { 36 | largest_size = width; 37 | largest_index = i; 38 | } 39 | } 40 | 41 | let image = icondir.entries()[largest_index].decode()?; 42 | let out_file = File::create(output_path).unwrap(); 43 | 44 | image.write_png(out_file) 45 | } 46 | 47 | /// Makes an icon for the application 48 | pub fn make_icon(input_bin: &str, file_name: &str) -> String { 49 | let home = home::home_dir().unwrap(); 50 | let home = home.to_str().unwrap(); 51 | 52 | let output_path = &format!("{home}/.local/share/icons/{file_name}.png"); 53 | 54 | if let Some(icon) = get_first_ico_file(input_bin) { 55 | let _ = convert_largest_square_image_in_ico_to_png(icon, output_path); 56 | } 57 | 58 | output_path.to_string() 59 | } 60 | -------------------------------------------------------------------------------- /src/state/options.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | use serde::Serialize; 3 | use std::collections::HashMap; 4 | use std::env::var; 5 | 6 | use crate::consts::DEFAULT_LOCALE; 7 | use crate::consts::DEFAULT_TIMEZONE; 8 | use crate::consts::DEFAULT_WINE32_PREFIX; 9 | 10 | #[derive(Serialize, Deserialize)] 11 | pub struct Options { 12 | pub wine_prefix: String, 13 | pub path: String, 14 | pub wayland_display: String, 15 | pub xdg_runtime_dir: String, 16 | pub display: String, 17 | pub locale: String, 18 | pub timezone: String, 19 | pub arguments: Vec, 20 | } 21 | 22 | impl Options { 23 | pub fn new(path: &str, wine_prefix: &str, arguments: &[String]) -> Self { 24 | Self { 25 | path: path.to_string(), 26 | wine_prefix: wine_prefix.to_string(), 27 | arguments: arguments.to_vec(), 28 | ..Default::default() 29 | } 30 | } 31 | 32 | pub fn vars(&self) -> HashMap<&str, String> { 33 | let wine_arch = match self.wine_prefix.contains("64") { 34 | true => "win64", 35 | false => "win32", 36 | }; 37 | 38 | HashMap::from([ 39 | ("WINEPREFIX", self.wine_prefix.to_string()), 40 | ("WAYLAND_DISPLAY", self.wayland_display.to_string()), 41 | ("XDG_RUNTIME_DIR", self.xdg_runtime_dir.to_string()), 42 | ("DISPLAY", self.display.to_string()), 43 | ("XAUTHORITY", "/tmp/.X11-unix/Xauthority".to_string()), 44 | ("LC_ALL", self.locale.to_string()), 45 | ("TZ", self.timezone.to_string()), 46 | ("WINEARCH", wine_arch.to_string()), 47 | ]) 48 | } 49 | } 50 | 51 | impl Default for Options { 52 | fn default() -> Self { 53 | Self { 54 | wine_prefix: DEFAULT_WINE32_PREFIX.to_string(), 55 | path: "/tmp/sakaya".to_string(), 56 | wayland_display: var("WAYLAND_DISPLAY").unwrap_or_default(), 57 | xdg_runtime_dir: var("XDG_RUNTIME_DIR").unwrap(), 58 | display: var("DISPLAY").unwrap(), 59 | locale: DEFAULT_LOCALE.to_string(), 60 | timezone: DEFAULT_TIMEZONE.to_string(), 61 | arguments: vec![], 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/cli/clap.rs: -------------------------------------------------------------------------------- 1 | use clap::builder::styling::{AnsiColor, Effects, Styles}; 2 | use clap::{Parser, Subcommand}; 3 | use std::net::SocketAddrV4; 4 | use std::path::PathBuf; 5 | 6 | use crate::consts::{ 7 | DEFAULT_ADDRESS, DEFAULT_LOCALE, DEFAULT_PORT, DEFAULT_TIMEZONE, DEFAULT_WINE32_PREFIX, 8 | DEFAULT_WINE64_PREFIX, 9 | }; 10 | 11 | fn styles() -> Styles { 12 | Styles::styled() 13 | .header(AnsiColor::Red.on_default() | Effects::BOLD) 14 | .usage(AnsiColor::Red.on_default() | Effects::BOLD) 15 | .literal(AnsiColor::Blue.on_default() | Effects::BOLD) 16 | .placeholder(AnsiColor::Green.on_default()) 17 | } 18 | 19 | #[derive(Parser)] 20 | #[command(author, version, about, styles = styles())] 21 | pub struct Cli { 22 | /// Path to the executable to run. 23 | pub file: Option, 24 | 25 | /// Address of the server to request 26 | #[arg(short, long, default_value = DEFAULT_ADDRESS)] 27 | pub address: SocketAddrV4, 28 | 29 | /// Host directory mounted to /mnt inside the container (default 3 levels deep to file path) 30 | #[arg(short, long)] 31 | pub directory: Option, 32 | 33 | /// $WINEPREFIX for 32-bit applications (i386) 34 | #[arg(short, long, default_value = DEFAULT_WINE32_PREFIX)] 35 | pub wine32: String, 36 | 37 | /// $WINEPREFIX for 64-bit applications (amd64) 38 | #[arg(short = 'W', long, default_value = DEFAULT_WINE64_PREFIX)] 39 | pub wine64: String, 40 | 41 | /// Locale to run programs with 42 | #[arg(short, long, default_value = DEFAULT_LOCALE)] 43 | pub locale: String, 44 | 45 | /// Timezone to run programs with 46 | #[arg(short, long, default_value = DEFAULT_TIMEZONE)] 47 | pub timezone: String, 48 | 49 | /// Force using the 64-bit $WINEPREFIX for 32-bit applications 50 | #[arg(short, long)] 51 | pub force64: bool, 52 | 53 | /// Arguments to pass to [FILE] 54 | #[arg(trailing_var_arg = true)] 55 | pub arguments: Vec, 56 | 57 | #[command(subcommand)] 58 | pub command: Option, 59 | } 60 | 61 | #[derive(Subcommand, PartialEq)] 62 | pub enum Commands { 63 | /// Start a sakaya server instead of a client 64 | /// 65 | /// You shouldn't need to use this unless you want to start a sakaya server outside 66 | /// of a systemd-nspawn container. 67 | Server { 68 | /// Port number to use for the sakaya server 69 | #[arg(short, long, default_value_t = DEFAULT_PORT)] 70 | port: u16, 71 | }, 72 | } 73 | -------------------------------------------------------------------------------- /tests/release.rs: -------------------------------------------------------------------------------- 1 | use assert_cmd::Command; 2 | use serde::Deserialize; 3 | use std::fs; 4 | 5 | #[derive(Debug, Deserialize)] 6 | struct Config { 7 | package: Option, 8 | } 9 | 10 | #[derive(Debug, Deserialize)] 11 | struct PackageConfig { 12 | version: Option, 13 | authors: Option>, 14 | description: Option, 15 | } 16 | 17 | #[test] 18 | /// Ensures that the copyright year is updated in both files if the LICENSE is updated 19 | fn copyright_is_the_same() { 20 | let license = &fs::read_to_string("LICENSE").unwrap(); 21 | let license = license.split("\n").collect::>()[0]; 22 | 23 | let cargo = &fs::read_to_string("Cargo.toml").unwrap(); 24 | let cargo: Config = toml::from_str(cargo).unwrap(); 25 | let cargo = &cargo.package.unwrap().authors.unwrap()[0]; 26 | 27 | assert!( 28 | cargo.starts_with(license), 29 | "Cargo.toml should have the same copyright year as LICENSE" 30 | ); 31 | } 32 | 33 | #[test] 34 | /// Ensures that the usage code block in the README is the same as the output of sakaya -h 35 | fn usage_is_the_same() { 36 | let cargo_description = &fs::read_to_string("Cargo.toml").unwrap(); 37 | let cargo_description: Config = toml::from_str(cargo_description).unwrap(); 38 | let cargo_description = cargo_description.package.unwrap().description.unwrap(); 39 | 40 | let readme = &fs::read_to_string("README.md").unwrap(); 41 | let mut inside_code_block = false; 42 | 43 | // Initialize with cargo_description since we don't duplicate this in the README 44 | let mut readme_usage: String = format!("{cargo_description}\n\n"); 45 | 46 | for line in readme.lines() { 47 | if line == "```" { 48 | inside_code_block = false; 49 | continue; 50 | } 51 | 52 | if inside_code_block { 53 | readme_usage.push_str(&(line.to_owned() + "\n")); 54 | continue; 55 | } 56 | 57 | if line == "```man" { 58 | inside_code_block = true; 59 | } 60 | } 61 | 62 | let mut cmd = Command::cargo_bin("sakaya").unwrap(); 63 | cmd.arg("-h").assert().stdout(readme_usage); 64 | } 65 | 66 | #[test] 67 | /// Ensures that the correct version of sakaya is found in the README 68 | fn current_version_is_used() { 69 | let cargo_version = &fs::read_to_string("Cargo.toml").unwrap(); 70 | let cargo_version: Config = toml::from_str(cargo_version).unwrap(); 71 | let cargo_version = cargo_version.package.unwrap().version.unwrap(); 72 | 73 | let readme = &fs::read_to_string("README.md").unwrap(); 74 | 75 | assert!( 76 | readme.contains(&("--tag ".to_owned() + cargo_version.as_str())), 77 | "should have the correct tag version in the README" 78 | ) 79 | } 80 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use sakaya::cli::Cli; 3 | use sakaya::cli::Commands; 4 | use sakaya::util::is_container; 5 | use sakaya::util::notify; 6 | use sakaya::{client, server}; 7 | use std::net::Ipv4Addr; 8 | use std::net::SocketAddrV4; 9 | use std::path::Component; 10 | 11 | /// The main function is in charge of either starting a `sakaya-server` or 12 | /// starting a `sakaya-client` that connects to a `sakaya-server`. 13 | /// 14 | /// It does this by checking if the `server` command was passed. It also defaults 15 | /// to starting a `sakaya-server` if ran inside a systemd-nspawn container. 16 | #[tokio::main] 17 | async fn main() { 18 | let Cli { 19 | address, 20 | command, 21 | file, 22 | directory, 23 | arguments, 24 | .. 25 | } = Cli::parse(); 26 | 27 | let ip = Ipv4Addr::new(0, 0, 0, 0); 28 | 29 | match &command { 30 | Some(Commands::Server { port }) => start_server(ip, *port).await, 31 | 32 | None => { 33 | if is_container() { 34 | start_server(ip, 39493).await; 35 | 36 | return; 37 | } 38 | 39 | if let Some(file) = file { 40 | let mut smart_directory = String::new(); 41 | 42 | if let Ok(file) = file.canonicalize() { 43 | let components = &mut file.components(); 44 | let mut i = 0; 45 | 46 | for component in components.by_ref() { 47 | if component == Component::RootDir { 48 | continue; 49 | } 50 | 51 | smart_directory = format!( 52 | "{}/{}", 53 | smart_directory, 54 | component.as_os_str().to_str().unwrap() 55 | ); 56 | 57 | i += 1; 58 | 59 | if i == 3 { 60 | break; 61 | } 62 | } 63 | } else { 64 | smart_directory = file.to_str().unwrap().to_string(); 65 | } 66 | 67 | if let Some(directory) = directory { 68 | client::exec(address, &file, &arguments, directory.to_str().unwrap()); 69 | } else { 70 | client::exec(address, &file, &arguments, &smart_directory); 71 | } 72 | 73 | return; 74 | } 75 | 76 | notify("sakaya was called but no file was given.", None); 77 | } 78 | } 79 | } 80 | 81 | async fn start_server(ip: Ipv4Addr, port: u16) { 82 | let running_ip = SocketAddrV4::new(ip, port); 83 | 84 | server::serve(running_ip).await; 85 | } 86 | -------------------------------------------------------------------------------- /src/client/exec.rs: -------------------------------------------------------------------------------- 1 | use crate::cli::Cli; 2 | use crate::util::notify; 3 | 4 | use clap::Parser; 5 | use std::net::SocketAddrV4; 6 | use std::path::Path; 7 | 8 | use super::{ctrlc, get_target_machine, make_desktop_file, make_icon, make_xauth, request}; 9 | 10 | /// Run an executable inside the container from the host by requesting 11 | /// the server on a given socket address 12 | pub fn exec(address: SocketAddrV4, path: &Path, arguments: &[String], directory: &str) { 13 | let ping = minreq::get(format!("http://{address}/")) 14 | .with_timeout(1) 15 | .send(); 16 | 17 | if ping.is_err() { 18 | notify( 19 | &format!("Error: sakaya server is not accessible on {address}."), 20 | None, 21 | ); 22 | 23 | return; 24 | } 25 | 26 | if let Some(session) = std::env::var_os("XDG_SESSION_TYPE") { 27 | if session == "x11" { 28 | make_xauth(); 29 | } 30 | } 31 | 32 | let Cli { 33 | wine32, 34 | wine64, 35 | force64, 36 | .. 37 | } = Cli::parse(); 38 | 39 | let commands = ["winecfg", "winetricks"]; 40 | 41 | let maybe_command = path.to_str().unwrap(); 42 | let wine_prefix = if force64 { &wine64 } else { &wine32 }; 43 | 44 | if commands.contains(&maybe_command) { 45 | notify( 46 | &format!("Starting {maybe_command} with {wine_prefix}..."), 47 | None, 48 | ); 49 | 50 | ctrlc(maybe_command.to_string() + ".exe"); 51 | request(address, "", wine_prefix, arguments, maybe_command).unwrap(); 52 | return; 53 | } 54 | 55 | if !path.exists() { 56 | notify( 57 | &format!( 58 | "Exiting since {} is not available in the path.", 59 | path.to_string_lossy() 60 | ), 61 | None, 62 | ); 63 | return; 64 | } 65 | 66 | let file_name = path.file_name().unwrap().to_str().unwrap(); 67 | let path = path.canonicalize().unwrap(); 68 | let path = path.to_str().unwrap(); 69 | 70 | if path.contains(directory) { 71 | let container_path = path.replace(directory, "mnt"); 72 | let container_path = container_path.trim_end_matches('/'); 73 | let icon = make_icon(path, file_name); 74 | 75 | let wine_prefix = match get_target_machine(path) { 76 | 32 => &wine32, 77 | 64 => &wine64, 78 | _ => "", 79 | }; 80 | 81 | if wine_prefix.is_empty() { 82 | notify( 83 | "Exiting since 32/64-bit could not be determined. Please report this issue.", 84 | None, 85 | ); 86 | return; 87 | } 88 | 89 | let wine_prefix = if force64 { &wine64 } else { wine_prefix }; 90 | 91 | request(address, container_path, wine_prefix, arguments, "init").unwrap(); 92 | 93 | make_desktop_file(file_name, path); 94 | 95 | ctrlc(file_name.to_string()); 96 | 97 | notify( 98 | &format!("Starting {file_name} with {wine_prefix}..."), 99 | Some(&icon), 100 | ); 101 | 102 | if request(address, container_path, wine_prefix, arguments, "open").is_ok() { 103 | notify(&format!("Closed {file_name}."), Some(&icon)); 104 | } else { 105 | notify("Error: sakaya server is not accessible.", None); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sakaya 2 | 3 | Run native wine applications inside declarative systemd-nspawn containers. `sakaya` functions as a replacement for `wine` on the host. Works well with NixOS. 4 | 5 | ## Features 6 | 7 | - Start multiple wine applications that can interact with each other inside sandboxed systemd-nspawn containers 8 | - Automatically open 32/64-bit wine prefixes based on the executable 9 | - Pass-through `/dri` for native GPU performance inside containers 10 | - Prevent sandboxed applications from accessing the internet 11 | 12 | ## Installation 13 | 14 | ### [NixOS](https://wiki.nixos.org/wiki/Overview_of_the_NixOS_Linux_distribution) (Recommended) 15 | 16 | Add [`sakaya`](https://search.nixos.org/packages?channel=unstable&query=sakaya) to your `systemPackages` and rebuild. 17 | 18 | ```nix 19 | { pkgs, ... }: 20 | 21 | { 22 | environment.systemPackages = with pkgs; [ 23 | sakaya 24 | ]; 25 | } 26 | ``` 27 | 28 | ### Other distributions 29 | 30 | Follow the [install guide](https://www.rust-lang.org/tools/install) for Rust. Then, use cargo to install sakaya. 31 | 32 | ```fish 33 | cargo install --git https://github.com/donovanglover/sakaya --tag 0.1.0 34 | ``` 35 | 36 | ### Setup 37 | 38 | In order to use sakaya, you must first create a systemd-nspawn container running the sakaya server. 39 | 40 | See [`modules/containers.nix`](https://github.com/donovanglover/nix-config/blob/master/modules/containers.nix) in my nix-config for an example. 41 | 42 | ## Usage 43 | 44 | ```man 45 | Usage: sakaya [OPTIONS] [FILE] [ARGUMENTS]... [COMMAND] 46 | 47 | Commands: 48 | server Start a sakaya server instead of a client 49 | help Print this message or the help of the given subcommand(s) 50 | 51 | Arguments: 52 | [FILE] Path to the executable to run 53 | [ARGUMENTS]... Arguments to pass to [FILE] 54 | 55 | Options: 56 | -a, --address
Address of the server to request [default: 0.0.0.0:39493] 57 | -d, --directory Host directory mounted to /mnt inside the container (default 3 levels deep to file path) 58 | -w, --wine32 $WINEPREFIX for 32-bit applications (i386) [default: /mnt/wine32] 59 | -W, --wine64 $WINEPREFIX for 64-bit applications (amd64) [default: /mnt/wine64] 60 | -l, --locale Locale to run programs with [default: ja_JP.UTF-8] 61 | -t, --timezone Timezone to run programs with [default: Asia/Tokyo] 62 | -f, --force64 Force using the 64-bit $WINEPREFIX for 32-bit applications 63 | -h, --help Print help 64 | -V, --version Print version 65 | ``` 66 | 67 | ## Contributing 68 | 69 | I have been using sakaya since 2023 and it works well for my use case, however suggestions and improvements are welcome. If you would like to contribute code, you can check your work with `cargo clippy`, `cargo fmt`, and `cargo test`. 70 | 71 | ## Todo 72 | 73 | - [x] Reduce compile times 74 | - [x] Notify user if sakaya fails to start an executable 75 | - [x] Choose 32/64-bit automatically based on `IMAGE_FILE_32BIT_MACHINE` in the file headers 76 | - [x] Automatically run winetricks with sane defaults if prefix does not exist already 77 | - [x] Get .ico and convert to .png? Handle abrupt end of files? 78 | - [ ] Write tests 79 | - [x] Terminate sakaya if the server/container cannot be reached 80 | - [x] Create NixOS module to automate systemd service setup for sakaya server 81 | - [x] Automatically register sakaya to executables 82 | - [x] Update format of README 83 | - [x] Kill program inside container when using ctrl+c from host 84 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.22.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anstream" 31 | version = "0.6.14" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" 34 | dependencies = [ 35 | "anstyle", 36 | "anstyle-parse", 37 | "anstyle-query", 38 | "anstyle-wincon", 39 | "colorchoice", 40 | "is_terminal_polyfill", 41 | "utf8parse", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle" 46 | version = "1.0.8" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 49 | 50 | [[package]] 51 | name = "anstyle-parse" 52 | version = "0.2.4" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" 55 | dependencies = [ 56 | "utf8parse", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle-query" 61 | version = "1.0.3" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" 64 | dependencies = [ 65 | "windows-sys 0.52.0", 66 | ] 67 | 68 | [[package]] 69 | name = "anstyle-wincon" 70 | version = "3.0.3" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" 73 | dependencies = [ 74 | "anstyle", 75 | "windows-sys 0.52.0", 76 | ] 77 | 78 | [[package]] 79 | name = "anyhow" 80 | version = "1.0.98" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" 83 | 84 | [[package]] 85 | name = "assert_cmd" 86 | version = "2.0.16" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "dc1835b7f27878de8525dc71410b5a31cdcc5f230aed5ba5df968e09c201b23d" 89 | dependencies = [ 90 | "anstyle", 91 | "bstr", 92 | "doc-comment", 93 | "libc", 94 | "predicates", 95 | "predicates-core", 96 | "predicates-tree", 97 | "wait-timeout", 98 | ] 99 | 100 | [[package]] 101 | name = "async-broadcast" 102 | version = "0.7.1" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" 105 | dependencies = [ 106 | "event-listener", 107 | "event-listener-strategy", 108 | "futures-core", 109 | "pin-project-lite", 110 | ] 111 | 112 | [[package]] 113 | name = "async-channel" 114 | version = "2.3.1" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" 117 | dependencies = [ 118 | "concurrent-queue", 119 | "event-listener-strategy", 120 | "futures-core", 121 | "pin-project-lite", 122 | ] 123 | 124 | [[package]] 125 | name = "async-executor" 126 | version = "1.13.0" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" 129 | dependencies = [ 130 | "async-task", 131 | "concurrent-queue", 132 | "fastrand", 133 | "futures-lite", 134 | "slab", 135 | ] 136 | 137 | [[package]] 138 | name = "async-fs" 139 | version = "2.1.2" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" 142 | dependencies = [ 143 | "async-lock", 144 | "blocking", 145 | "futures-lite", 146 | ] 147 | 148 | [[package]] 149 | name = "async-io" 150 | version = "2.3.3" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" 153 | dependencies = [ 154 | "async-lock", 155 | "cfg-if", 156 | "concurrent-queue", 157 | "futures-io", 158 | "futures-lite", 159 | "parking", 160 | "polling", 161 | "rustix", 162 | "slab", 163 | "tracing", 164 | "windows-sys 0.52.0", 165 | ] 166 | 167 | [[package]] 168 | name = "async-lock" 169 | version = "3.4.0" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" 172 | dependencies = [ 173 | "event-listener", 174 | "event-listener-strategy", 175 | "pin-project-lite", 176 | ] 177 | 178 | [[package]] 179 | name = "async-process" 180 | version = "2.2.3" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a" 183 | dependencies = [ 184 | "async-channel", 185 | "async-io", 186 | "async-lock", 187 | "async-signal", 188 | "async-task", 189 | "blocking", 190 | "cfg-if", 191 | "event-listener", 192 | "futures-lite", 193 | "rustix", 194 | "tracing", 195 | "windows-sys 0.52.0", 196 | ] 197 | 198 | [[package]] 199 | name = "async-recursion" 200 | version = "1.1.1" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" 203 | dependencies = [ 204 | "proc-macro2", 205 | "quote", 206 | "syn 2.0.82", 207 | ] 208 | 209 | [[package]] 210 | name = "async-signal" 211 | version = "0.2.9" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "dfb3634b73397aa844481f814fad23bbf07fdb0eabec10f2eb95e58944b1ec32" 214 | dependencies = [ 215 | "async-io", 216 | "async-lock", 217 | "atomic-waker", 218 | "cfg-if", 219 | "futures-core", 220 | "futures-io", 221 | "rustix", 222 | "signal-hook-registry", 223 | "slab", 224 | "windows-sys 0.52.0", 225 | ] 226 | 227 | [[package]] 228 | name = "async-task" 229 | version = "4.7.1" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" 232 | 233 | [[package]] 234 | name = "async-trait" 235 | version = "0.1.81" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" 238 | dependencies = [ 239 | "proc-macro2", 240 | "quote", 241 | "syn 2.0.82", 242 | ] 243 | 244 | [[package]] 245 | name = "atomic-waker" 246 | version = "1.1.2" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 249 | 250 | [[package]] 251 | name = "autocfg" 252 | version = "1.3.0" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 255 | 256 | [[package]] 257 | name = "axum" 258 | version = "0.8.1" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8" 261 | dependencies = [ 262 | "axum-core", 263 | "bytes", 264 | "form_urlencoded", 265 | "futures-util", 266 | "http", 267 | "http-body", 268 | "http-body-util", 269 | "hyper", 270 | "hyper-util", 271 | "itoa", 272 | "matchit", 273 | "memchr", 274 | "mime", 275 | "percent-encoding", 276 | "pin-project-lite", 277 | "rustversion", 278 | "serde", 279 | "serde_json", 280 | "serde_path_to_error", 281 | "serde_urlencoded", 282 | "sync_wrapper", 283 | "tokio", 284 | "tower", 285 | "tower-layer", 286 | "tower-service", 287 | "tracing", 288 | ] 289 | 290 | [[package]] 291 | name = "axum-core" 292 | version = "0.5.0" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733" 295 | dependencies = [ 296 | "bytes", 297 | "futures-util", 298 | "http", 299 | "http-body", 300 | "http-body-util", 301 | "mime", 302 | "pin-project-lite", 303 | "rustversion", 304 | "sync_wrapper", 305 | "tower-layer", 306 | "tower-service", 307 | "tracing", 308 | ] 309 | 310 | [[package]] 311 | name = "backtrace" 312 | version = "0.3.73" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" 315 | dependencies = [ 316 | "addr2line", 317 | "cc", 318 | "cfg-if", 319 | "libc", 320 | "miniz_oxide", 321 | "object", 322 | "rustc-demangle", 323 | ] 324 | 325 | [[package]] 326 | name = "bitflags" 327 | version = "1.3.2" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 330 | 331 | [[package]] 332 | name = "bitflags" 333 | version = "2.6.0" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 336 | 337 | [[package]] 338 | name = "block" 339 | version = "0.1.6" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 342 | 343 | [[package]] 344 | name = "blocking" 345 | version = "1.6.1" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" 348 | dependencies = [ 349 | "async-channel", 350 | "async-task", 351 | "futures-io", 352 | "futures-lite", 353 | "piper", 354 | ] 355 | 356 | [[package]] 357 | name = "bstr" 358 | version = "1.9.1" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" 361 | dependencies = [ 362 | "memchr", 363 | "regex-automata", 364 | "serde", 365 | ] 366 | 367 | [[package]] 368 | name = "byteorder" 369 | version = "1.4.3" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 372 | 373 | [[package]] 374 | name = "bytes" 375 | version = "1.8.0" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" 378 | 379 | [[package]] 380 | name = "cc" 381 | version = "1.1.31" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" 384 | dependencies = [ 385 | "shlex", 386 | ] 387 | 388 | [[package]] 389 | name = "cfg-if" 390 | version = "1.0.0" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 393 | 394 | [[package]] 395 | name = "cfg_aliases" 396 | version = "0.2.1" 397 | source = "registry+https://github.com/rust-lang/crates.io-index" 398 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 399 | 400 | [[package]] 401 | name = "clap" 402 | version = "4.5.31" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" 405 | dependencies = [ 406 | "clap_builder", 407 | "clap_derive", 408 | ] 409 | 410 | [[package]] 411 | name = "clap_builder" 412 | version = "4.5.31" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" 415 | dependencies = [ 416 | "anstream", 417 | "anstyle", 418 | "clap_lex", 419 | "strsim", 420 | ] 421 | 422 | [[package]] 423 | name = "clap_complete" 424 | version = "4.5.46" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "f5c5508ea23c5366f77e53f5a0070e5a84e51687ec3ef9e0464c86dc8d13ce98" 427 | dependencies = [ 428 | "clap", 429 | ] 430 | 431 | [[package]] 432 | name = "clap_derive" 433 | version = "4.5.28" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" 436 | dependencies = [ 437 | "heck", 438 | "proc-macro2", 439 | "quote", 440 | "syn 2.0.82", 441 | ] 442 | 443 | [[package]] 444 | name = "clap_lex" 445 | version = "0.7.4" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 448 | 449 | [[package]] 450 | name = "clap_mangen" 451 | version = "0.2.26" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "724842fa9b144f9b89b3f3d371a89f3455eea660361d13a554f68f8ae5d6c13a" 454 | dependencies = [ 455 | "clap", 456 | "roff", 457 | ] 458 | 459 | [[package]] 460 | name = "colorchoice" 461 | version = "1.0.1" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" 464 | 465 | [[package]] 466 | name = "concurrent-queue" 467 | version = "2.5.0" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 470 | dependencies = [ 471 | "crossbeam-utils", 472 | ] 473 | 474 | [[package]] 475 | name = "crc32fast" 476 | version = "1.3.2" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 479 | dependencies = [ 480 | "cfg-if", 481 | ] 482 | 483 | [[package]] 484 | name = "crossbeam-utils" 485 | version = "0.8.20" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 488 | 489 | [[package]] 490 | name = "ctrlc" 491 | version = "3.4.6" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c" 494 | dependencies = [ 495 | "nix", 496 | "windows-sys 0.59.0", 497 | ] 498 | 499 | [[package]] 500 | name = "dataview" 501 | version = "1.0.1" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "50eb3a329e19d78c3a3dfa4ec5a51ecb84fa3a20c06edad04be25356018218f9" 504 | dependencies = [ 505 | "derive_pod", 506 | ] 507 | 508 | [[package]] 509 | name = "deranged" 510 | version = "0.3.11" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" 513 | dependencies = [ 514 | "powerfmt", 515 | ] 516 | 517 | [[package]] 518 | name = "derive_pod" 519 | version = "0.1.2" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "c2ea6706d74fca54e15f1d40b5cf7fe7f764aaec61352a9fcec58fe27e042fc8" 522 | 523 | [[package]] 524 | name = "difflib" 525 | version = "0.4.0" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" 528 | 529 | [[package]] 530 | name = "dirs-next" 531 | version = "2.0.0" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" 534 | dependencies = [ 535 | "cfg-if", 536 | "dirs-sys-next", 537 | ] 538 | 539 | [[package]] 540 | name = "dirs-sys-next" 541 | version = "0.1.2" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" 544 | dependencies = [ 545 | "libc", 546 | "redox_users", 547 | "winapi", 548 | ] 549 | 550 | [[package]] 551 | name = "doc-comment" 552 | version = "0.3.3" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" 555 | 556 | [[package]] 557 | name = "either" 558 | version = "1.11.0" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" 561 | 562 | [[package]] 563 | name = "endi" 564 | version = "1.1.0" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" 567 | 568 | [[package]] 569 | name = "enumflags2" 570 | version = "0.7.10" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" 573 | dependencies = [ 574 | "enumflags2_derive", 575 | "serde", 576 | ] 577 | 578 | [[package]] 579 | name = "enumflags2_derive" 580 | version = "0.7.10" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" 583 | dependencies = [ 584 | "proc-macro2", 585 | "quote", 586 | "syn 2.0.82", 587 | ] 588 | 589 | [[package]] 590 | name = "equivalent" 591 | version = "1.0.1" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 594 | 595 | [[package]] 596 | name = "errno" 597 | version = "0.3.9" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 600 | dependencies = [ 601 | "libc", 602 | "windows-sys 0.52.0", 603 | ] 604 | 605 | [[package]] 606 | name = "event-listener" 607 | version = "5.3.1" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" 610 | dependencies = [ 611 | "concurrent-queue", 612 | "parking", 613 | "pin-project-lite", 614 | ] 615 | 616 | [[package]] 617 | name = "event-listener-strategy" 618 | version = "0.5.2" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" 621 | dependencies = [ 622 | "event-listener", 623 | "pin-project-lite", 624 | ] 625 | 626 | [[package]] 627 | name = "fastrand" 628 | version = "2.1.0" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" 631 | 632 | [[package]] 633 | name = "fdeflate" 634 | version = "0.3.0" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" 637 | dependencies = [ 638 | "simd-adler32", 639 | ] 640 | 641 | [[package]] 642 | name = "flate2" 643 | version = "1.0.27" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" 646 | dependencies = [ 647 | "crc32fast", 648 | "miniz_oxide", 649 | ] 650 | 651 | [[package]] 652 | name = "fnv" 653 | version = "1.0.7" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 656 | 657 | [[package]] 658 | name = "form_urlencoded" 659 | version = "1.2.1" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 662 | dependencies = [ 663 | "percent-encoding", 664 | ] 665 | 666 | [[package]] 667 | name = "futures-channel" 668 | version = "0.3.30" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 671 | dependencies = [ 672 | "futures-core", 673 | ] 674 | 675 | [[package]] 676 | name = "futures-core" 677 | version = "0.3.30" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 680 | 681 | [[package]] 682 | name = "futures-io" 683 | version = "0.3.30" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 686 | 687 | [[package]] 688 | name = "futures-lite" 689 | version = "2.6.0" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" 692 | dependencies = [ 693 | "fastrand", 694 | "futures-core", 695 | "futures-io", 696 | "parking", 697 | "pin-project-lite", 698 | ] 699 | 700 | [[package]] 701 | name = "futures-sink" 702 | version = "0.3.30" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 705 | 706 | [[package]] 707 | name = "futures-task" 708 | version = "0.3.30" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 711 | 712 | [[package]] 713 | name = "futures-util" 714 | version = "0.3.30" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 717 | dependencies = [ 718 | "futures-core", 719 | "futures-io", 720 | "futures-sink", 721 | "futures-task", 722 | "memchr", 723 | "pin-project-lite", 724 | "pin-utils", 725 | "slab", 726 | ] 727 | 728 | [[package]] 729 | name = "getrandom" 730 | version = "0.2.15" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 733 | dependencies = [ 734 | "cfg-if", 735 | "libc", 736 | "wasi", 737 | ] 738 | 739 | [[package]] 740 | name = "gimli" 741 | version = "0.29.0" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" 744 | 745 | [[package]] 746 | name = "hashbrown" 747 | version = "0.14.5" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 750 | 751 | [[package]] 752 | name = "heck" 753 | version = "0.5.0" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 756 | 757 | [[package]] 758 | name = "hermit-abi" 759 | version = "0.3.9" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 762 | 763 | [[package]] 764 | name = "hermit-abi" 765 | version = "0.4.0" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" 768 | 769 | [[package]] 770 | name = "hex" 771 | version = "0.4.3" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 774 | 775 | [[package]] 776 | name = "home" 777 | version = "0.5.11" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 780 | dependencies = [ 781 | "windows-sys 0.59.0", 782 | ] 783 | 784 | [[package]] 785 | name = "http" 786 | version = "1.1.0" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 789 | dependencies = [ 790 | "bytes", 791 | "fnv", 792 | "itoa", 793 | ] 794 | 795 | [[package]] 796 | name = "http-body" 797 | version = "1.0.1" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 800 | dependencies = [ 801 | "bytes", 802 | "http", 803 | ] 804 | 805 | [[package]] 806 | name = "http-body-util" 807 | version = "0.1.2" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 810 | dependencies = [ 811 | "bytes", 812 | "futures-util", 813 | "http", 814 | "http-body", 815 | "pin-project-lite", 816 | ] 817 | 818 | [[package]] 819 | name = "httparse" 820 | version = "1.9.5" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" 823 | 824 | [[package]] 825 | name = "httpdate" 826 | version = "1.0.3" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 829 | 830 | [[package]] 831 | name = "hyper" 832 | version = "1.5.0" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" 835 | dependencies = [ 836 | "bytes", 837 | "futures-channel", 838 | "futures-util", 839 | "http", 840 | "http-body", 841 | "httparse", 842 | "httpdate", 843 | "itoa", 844 | "pin-project-lite", 845 | "smallvec", 846 | "tokio", 847 | ] 848 | 849 | [[package]] 850 | name = "hyper-util" 851 | version = "0.1.9" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" 854 | dependencies = [ 855 | "bytes", 856 | "futures-util", 857 | "http", 858 | "http-body", 859 | "hyper", 860 | "pin-project-lite", 861 | "tokio", 862 | "tower-service", 863 | ] 864 | 865 | [[package]] 866 | name = "ico" 867 | version = "0.4.0" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" 870 | dependencies = [ 871 | "byteorder", 872 | "png", 873 | ] 874 | 875 | [[package]] 876 | name = "indexmap" 877 | version = "2.2.6" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 880 | dependencies = [ 881 | "equivalent", 882 | "hashbrown", 883 | ] 884 | 885 | [[package]] 886 | name = "is_terminal_polyfill" 887 | version = "1.70.0" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" 890 | 891 | [[package]] 892 | name = "itoa" 893 | version = "1.0.11" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 896 | 897 | [[package]] 898 | name = "libc" 899 | version = "0.2.169" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" 902 | 903 | [[package]] 904 | name = "libredox" 905 | version = "0.1.3" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 908 | dependencies = [ 909 | "bitflags 2.6.0", 910 | "libc", 911 | ] 912 | 913 | [[package]] 914 | name = "linux-raw-sys" 915 | version = "0.4.14" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 918 | 919 | [[package]] 920 | name = "local-ip-address" 921 | version = "0.6.3" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "3669cf5561f8d27e8fc84cc15e58350e70f557d4d65f70e3154e54cd2f8e1782" 924 | dependencies = [ 925 | "libc", 926 | "neli", 927 | "thiserror", 928 | "windows-sys 0.59.0", 929 | ] 930 | 931 | [[package]] 932 | name = "lock_api" 933 | version = "0.4.12" 934 | source = "registry+https://github.com/rust-lang/crates.io-index" 935 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 936 | dependencies = [ 937 | "autocfg", 938 | "scopeguard", 939 | ] 940 | 941 | [[package]] 942 | name = "log" 943 | version = "0.4.21" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 946 | 947 | [[package]] 948 | name = "mac-notification-sys" 949 | version = "0.6.1" 950 | source = "registry+https://github.com/rust-lang/crates.io-index" 951 | checksum = "51fca4d74ff9dbaac16a01b924bc3693fa2bba0862c2c633abc73f9a8ea21f64" 952 | dependencies = [ 953 | "cc", 954 | "dirs-next", 955 | "objc-foundation", 956 | "objc_id", 957 | "time", 958 | ] 959 | 960 | [[package]] 961 | name = "malloc_buf" 962 | version = "0.0.6" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 965 | dependencies = [ 966 | "libc", 967 | ] 968 | 969 | [[package]] 970 | name = "matchit" 971 | version = "0.8.4" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" 974 | 975 | [[package]] 976 | name = "memchr" 977 | version = "2.7.2" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 980 | 981 | [[package]] 982 | name = "memoffset" 983 | version = "0.9.1" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 986 | dependencies = [ 987 | "autocfg", 988 | ] 989 | 990 | [[package]] 991 | name = "mime" 992 | version = "0.3.17" 993 | source = "registry+https://github.com/rust-lang/crates.io-index" 994 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 995 | 996 | [[package]] 997 | name = "minimal-lexical" 998 | version = "0.2.1" 999 | source = "registry+https://github.com/rust-lang/crates.io-index" 1000 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 1001 | 1002 | [[package]] 1003 | name = "miniz_oxide" 1004 | version = "0.7.1" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 1007 | dependencies = [ 1008 | "adler", 1009 | "simd-adler32", 1010 | ] 1011 | 1012 | [[package]] 1013 | name = "minreq" 1014 | version = "2.13.2" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | checksum = "da0c420feb01b9fb5061f8c8f452534361dd783756dcf38ec45191ce55e7a161" 1017 | dependencies = [ 1018 | "log", 1019 | "serde", 1020 | "serde_json", 1021 | ] 1022 | 1023 | [[package]] 1024 | name = "mio" 1025 | version = "1.0.2" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 1028 | dependencies = [ 1029 | "hermit-abi 0.3.9", 1030 | "libc", 1031 | "wasi", 1032 | "windows-sys 0.52.0", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "neli" 1037 | version = "0.6.4" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43" 1040 | dependencies = [ 1041 | "byteorder", 1042 | "libc", 1043 | "log", 1044 | "neli-proc-macros", 1045 | ] 1046 | 1047 | [[package]] 1048 | name = "neli-proc-macros" 1049 | version = "0.1.3" 1050 | source = "registry+https://github.com/rust-lang/crates.io-index" 1051 | checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4" 1052 | dependencies = [ 1053 | "either", 1054 | "proc-macro2", 1055 | "quote", 1056 | "serde", 1057 | "syn 1.0.109", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "nix" 1062 | version = "0.29.0" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" 1065 | dependencies = [ 1066 | "bitflags 2.6.0", 1067 | "cfg-if", 1068 | "cfg_aliases", 1069 | "libc", 1070 | "memoffset", 1071 | ] 1072 | 1073 | [[package]] 1074 | name = "no-std-compat" 1075 | version = "0.4.1" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" 1078 | 1079 | [[package]] 1080 | name = "nom" 1081 | version = "7.1.3" 1082 | source = "registry+https://github.com/rust-lang/crates.io-index" 1083 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 1084 | dependencies = [ 1085 | "memchr", 1086 | "minimal-lexical", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "notify-rust" 1091 | version = "4.11.5" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "7fa3b9f2364a09bd359aa0206702882e208437450866a374d5372d64aece4029" 1094 | dependencies = [ 1095 | "futures-lite", 1096 | "log", 1097 | "mac-notification-sys", 1098 | "serde", 1099 | "tauri-winrt-notification", 1100 | "zbus", 1101 | ] 1102 | 1103 | [[package]] 1104 | name = "num-conv" 1105 | version = "0.1.0" 1106 | source = "registry+https://github.com/rust-lang/crates.io-index" 1107 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 1108 | 1109 | [[package]] 1110 | name = "objc" 1111 | version = "0.2.7" 1112 | source = "registry+https://github.com/rust-lang/crates.io-index" 1113 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 1114 | dependencies = [ 1115 | "malloc_buf", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "objc-foundation" 1120 | version = "0.1.1" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" 1123 | dependencies = [ 1124 | "block", 1125 | "objc", 1126 | "objc_id", 1127 | ] 1128 | 1129 | [[package]] 1130 | name = "objc_id" 1131 | version = "0.1.1" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" 1134 | dependencies = [ 1135 | "objc", 1136 | ] 1137 | 1138 | [[package]] 1139 | name = "object" 1140 | version = "0.36.5" 1141 | source = "registry+https://github.com/rust-lang/crates.io-index" 1142 | checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" 1143 | dependencies = [ 1144 | "memchr", 1145 | ] 1146 | 1147 | [[package]] 1148 | name = "once_cell" 1149 | version = "1.19.0" 1150 | source = "registry+https://github.com/rust-lang/crates.io-index" 1151 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1152 | 1153 | [[package]] 1154 | name = "ordered-stream" 1155 | version = "0.2.0" 1156 | source = "registry+https://github.com/rust-lang/crates.io-index" 1157 | checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" 1158 | dependencies = [ 1159 | "futures-core", 1160 | "pin-project-lite", 1161 | ] 1162 | 1163 | [[package]] 1164 | name = "parking" 1165 | version = "2.2.0" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" 1168 | 1169 | [[package]] 1170 | name = "parking_lot" 1171 | version = "0.12.3" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1174 | dependencies = [ 1175 | "lock_api", 1176 | "parking_lot_core", 1177 | ] 1178 | 1179 | [[package]] 1180 | name = "parking_lot_core" 1181 | version = "0.9.10" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1184 | dependencies = [ 1185 | "cfg-if", 1186 | "libc", 1187 | "redox_syscall", 1188 | "smallvec", 1189 | "windows-targets", 1190 | ] 1191 | 1192 | [[package]] 1193 | name = "pelite" 1194 | version = "0.10.0" 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" 1196 | checksum = "88dccf4bd32294364aeb7bd55d749604450e9db54605887551f21baea7617685" 1197 | dependencies = [ 1198 | "dataview", 1199 | "libc", 1200 | "no-std-compat", 1201 | "pelite-macros", 1202 | "winapi", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "pelite-macros" 1207 | version = "0.1.1" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "7a7cf3f8ecebb0f4895f4892a8be0a0dc81b498f9d56735cb769dc31bf00815b" 1210 | 1211 | [[package]] 1212 | name = "percent-encoding" 1213 | version = "2.3.1" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1216 | 1217 | [[package]] 1218 | name = "pin-project-lite" 1219 | version = "0.2.14" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 1222 | 1223 | [[package]] 1224 | name = "pin-utils" 1225 | version = "0.1.0" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1228 | 1229 | [[package]] 1230 | name = "piper" 1231 | version = "0.2.3" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" 1234 | dependencies = [ 1235 | "atomic-waker", 1236 | "fastrand", 1237 | "futures-io", 1238 | ] 1239 | 1240 | [[package]] 1241 | name = "png" 1242 | version = "0.17.9" 1243 | source = "registry+https://github.com/rust-lang/crates.io-index" 1244 | checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" 1245 | dependencies = [ 1246 | "bitflags 1.3.2", 1247 | "crc32fast", 1248 | "fdeflate", 1249 | "flate2", 1250 | "miniz_oxide", 1251 | ] 1252 | 1253 | [[package]] 1254 | name = "polling" 1255 | version = "3.7.2" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" 1258 | dependencies = [ 1259 | "cfg-if", 1260 | "concurrent-queue", 1261 | "hermit-abi 0.4.0", 1262 | "pin-project-lite", 1263 | "rustix", 1264 | "tracing", 1265 | "windows-sys 0.52.0", 1266 | ] 1267 | 1268 | [[package]] 1269 | name = "powerfmt" 1270 | version = "0.2.0" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 1273 | 1274 | [[package]] 1275 | name = "predicates" 1276 | version = "3.1.0" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" 1279 | dependencies = [ 1280 | "anstyle", 1281 | "difflib", 1282 | "predicates-core", 1283 | ] 1284 | 1285 | [[package]] 1286 | name = "predicates-core" 1287 | version = "1.0.6" 1288 | source = "registry+https://github.com/rust-lang/crates.io-index" 1289 | checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" 1290 | 1291 | [[package]] 1292 | name = "predicates-tree" 1293 | version = "1.0.9" 1294 | source = "registry+https://github.com/rust-lang/crates.io-index" 1295 | checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" 1296 | dependencies = [ 1297 | "predicates-core", 1298 | "termtree", 1299 | ] 1300 | 1301 | [[package]] 1302 | name = "proc-macro-crate" 1303 | version = "3.1.0" 1304 | source = "registry+https://github.com/rust-lang/crates.io-index" 1305 | checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" 1306 | dependencies = [ 1307 | "toml_edit 0.21.1", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "proc-macro2" 1312 | version = "1.0.84" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" 1315 | dependencies = [ 1316 | "unicode-ident", 1317 | ] 1318 | 1319 | [[package]] 1320 | name = "quick-xml" 1321 | version = "0.31.0" 1322 | source = "registry+https://github.com/rust-lang/crates.io-index" 1323 | checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" 1324 | dependencies = [ 1325 | "memchr", 1326 | ] 1327 | 1328 | [[package]] 1329 | name = "quote" 1330 | version = "1.0.36" 1331 | source = "registry+https://github.com/rust-lang/crates.io-index" 1332 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 1333 | dependencies = [ 1334 | "proc-macro2", 1335 | ] 1336 | 1337 | [[package]] 1338 | name = "redox_syscall" 1339 | version = "0.5.7" 1340 | source = "registry+https://github.com/rust-lang/crates.io-index" 1341 | checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" 1342 | dependencies = [ 1343 | "bitflags 2.6.0", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "redox_users" 1348 | version = "0.4.5" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" 1351 | dependencies = [ 1352 | "getrandom", 1353 | "libredox", 1354 | "thiserror", 1355 | ] 1356 | 1357 | [[package]] 1358 | name = "regex" 1359 | version = "1.10.2" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" 1362 | dependencies = [ 1363 | "aho-corasick", 1364 | "memchr", 1365 | "regex-automata", 1366 | "regex-syntax", 1367 | ] 1368 | 1369 | [[package]] 1370 | name = "regex-automata" 1371 | version = "0.4.6" 1372 | source = "registry+https://github.com/rust-lang/crates.io-index" 1373 | checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" 1374 | dependencies = [ 1375 | "aho-corasick", 1376 | "memchr", 1377 | "regex-syntax", 1378 | ] 1379 | 1380 | [[package]] 1381 | name = "regex-syntax" 1382 | version = "0.8.3" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" 1385 | 1386 | [[package]] 1387 | name = "roff" 1388 | version = "0.2.1" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" 1391 | 1392 | [[package]] 1393 | name = "rustc-demangle" 1394 | version = "0.1.24" 1395 | source = "registry+https://github.com/rust-lang/crates.io-index" 1396 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1397 | 1398 | [[package]] 1399 | name = "rustix" 1400 | version = "0.38.34" 1401 | source = "registry+https://github.com/rust-lang/crates.io-index" 1402 | checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" 1403 | dependencies = [ 1404 | "bitflags 2.6.0", 1405 | "errno", 1406 | "libc", 1407 | "linux-raw-sys", 1408 | "windows-sys 0.52.0", 1409 | ] 1410 | 1411 | [[package]] 1412 | name = "rustversion" 1413 | version = "1.0.18" 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" 1415 | checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" 1416 | 1417 | [[package]] 1418 | name = "rustympkglib" 1419 | version = "0.1.1" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "39a6a04e9c4cc5d0fd4291f8ce8e1aa9d438d3e7b5ea09699cc81acd83272a16" 1422 | dependencies = [ 1423 | "serde", 1424 | "tree-sitter", 1425 | "tree-sitter-bash", 1426 | ] 1427 | 1428 | [[package]] 1429 | name = "ryu" 1430 | version = "1.0.18" 1431 | source = "registry+https://github.com/rust-lang/crates.io-index" 1432 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1433 | 1434 | [[package]] 1435 | name = "sakaya" 1436 | version = "0.1.0" 1437 | dependencies = [ 1438 | "anyhow", 1439 | "assert_cmd", 1440 | "axum", 1441 | "clap", 1442 | "clap_complete", 1443 | "clap_mangen", 1444 | "ctrlc", 1445 | "home", 1446 | "ico", 1447 | "local-ip-address", 1448 | "minreq", 1449 | "notify-rust", 1450 | "pelite", 1451 | "rustympkglib", 1452 | "serde", 1453 | "tokio", 1454 | "toml", 1455 | "urlencoding", 1456 | ] 1457 | 1458 | [[package]] 1459 | name = "scopeguard" 1460 | version = "1.2.0" 1461 | source = "registry+https://github.com/rust-lang/crates.io-index" 1462 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1463 | 1464 | [[package]] 1465 | name = "serde" 1466 | version = "1.0.218" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" 1469 | dependencies = [ 1470 | "serde_derive", 1471 | ] 1472 | 1473 | [[package]] 1474 | name = "serde_derive" 1475 | version = "1.0.218" 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" 1477 | checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" 1478 | dependencies = [ 1479 | "proc-macro2", 1480 | "quote", 1481 | "syn 2.0.82", 1482 | ] 1483 | 1484 | [[package]] 1485 | name = "serde_json" 1486 | version = "1.0.132" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" 1489 | dependencies = [ 1490 | "itoa", 1491 | "memchr", 1492 | "ryu", 1493 | "serde", 1494 | ] 1495 | 1496 | [[package]] 1497 | name = "serde_path_to_error" 1498 | version = "0.1.16" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" 1501 | dependencies = [ 1502 | "itoa", 1503 | "serde", 1504 | ] 1505 | 1506 | [[package]] 1507 | name = "serde_repr" 1508 | version = "0.1.19" 1509 | source = "registry+https://github.com/rust-lang/crates.io-index" 1510 | checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" 1511 | dependencies = [ 1512 | "proc-macro2", 1513 | "quote", 1514 | "syn 2.0.82", 1515 | ] 1516 | 1517 | [[package]] 1518 | name = "serde_spanned" 1519 | version = "0.6.6" 1520 | source = "registry+https://github.com/rust-lang/crates.io-index" 1521 | checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" 1522 | dependencies = [ 1523 | "serde", 1524 | ] 1525 | 1526 | [[package]] 1527 | name = "serde_urlencoded" 1528 | version = "0.7.1" 1529 | source = "registry+https://github.com/rust-lang/crates.io-index" 1530 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1531 | dependencies = [ 1532 | "form_urlencoded", 1533 | "itoa", 1534 | "ryu", 1535 | "serde", 1536 | ] 1537 | 1538 | [[package]] 1539 | name = "shlex" 1540 | version = "1.3.0" 1541 | source = "registry+https://github.com/rust-lang/crates.io-index" 1542 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1543 | 1544 | [[package]] 1545 | name = "signal-hook-registry" 1546 | version = "1.4.2" 1547 | source = "registry+https://github.com/rust-lang/crates.io-index" 1548 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 1549 | dependencies = [ 1550 | "libc", 1551 | ] 1552 | 1553 | [[package]] 1554 | name = "simd-adler32" 1555 | version = "0.3.7" 1556 | source = "registry+https://github.com/rust-lang/crates.io-index" 1557 | checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 1558 | 1559 | [[package]] 1560 | name = "slab" 1561 | version = "0.4.9" 1562 | source = "registry+https://github.com/rust-lang/crates.io-index" 1563 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1564 | dependencies = [ 1565 | "autocfg", 1566 | ] 1567 | 1568 | [[package]] 1569 | name = "smallvec" 1570 | version = "1.13.2" 1571 | source = "registry+https://github.com/rust-lang/crates.io-index" 1572 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1573 | 1574 | [[package]] 1575 | name = "socket2" 1576 | version = "0.5.7" 1577 | source = "registry+https://github.com/rust-lang/crates.io-index" 1578 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 1579 | dependencies = [ 1580 | "libc", 1581 | "windows-sys 0.52.0", 1582 | ] 1583 | 1584 | [[package]] 1585 | name = "static_assertions" 1586 | version = "1.1.0" 1587 | source = "registry+https://github.com/rust-lang/crates.io-index" 1588 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1589 | 1590 | [[package]] 1591 | name = "strsim" 1592 | version = "0.11.1" 1593 | source = "registry+https://github.com/rust-lang/crates.io-index" 1594 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1595 | 1596 | [[package]] 1597 | name = "syn" 1598 | version = "1.0.109" 1599 | source = "registry+https://github.com/rust-lang/crates.io-index" 1600 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1601 | dependencies = [ 1602 | "proc-macro2", 1603 | "quote", 1604 | "unicode-ident", 1605 | ] 1606 | 1607 | [[package]] 1608 | name = "syn" 1609 | version = "2.0.82" 1610 | source = "registry+https://github.com/rust-lang/crates.io-index" 1611 | checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" 1612 | dependencies = [ 1613 | "proc-macro2", 1614 | "quote", 1615 | "unicode-ident", 1616 | ] 1617 | 1618 | [[package]] 1619 | name = "sync_wrapper" 1620 | version = "1.0.1" 1621 | source = "registry+https://github.com/rust-lang/crates.io-index" 1622 | checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" 1623 | 1624 | [[package]] 1625 | name = "tauri-winrt-notification" 1626 | version = "0.2.1" 1627 | source = "registry+https://github.com/rust-lang/crates.io-index" 1628 | checksum = "f89f5fb70d6f62381f5d9b2ba9008196150b40b75f3068eb24faeddf1c686871" 1629 | dependencies = [ 1630 | "quick-xml", 1631 | "windows", 1632 | "windows-version", 1633 | ] 1634 | 1635 | [[package]] 1636 | name = "tempfile" 1637 | version = "3.10.1" 1638 | source = "registry+https://github.com/rust-lang/crates.io-index" 1639 | checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" 1640 | dependencies = [ 1641 | "cfg-if", 1642 | "fastrand", 1643 | "rustix", 1644 | "windows-sys 0.52.0", 1645 | ] 1646 | 1647 | [[package]] 1648 | name = "termtree" 1649 | version = "0.4.1" 1650 | source = "registry+https://github.com/rust-lang/crates.io-index" 1651 | checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" 1652 | 1653 | [[package]] 1654 | name = "thiserror" 1655 | version = "1.0.47" 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" 1657 | checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" 1658 | dependencies = [ 1659 | "thiserror-impl", 1660 | ] 1661 | 1662 | [[package]] 1663 | name = "thiserror-impl" 1664 | version = "1.0.47" 1665 | source = "registry+https://github.com/rust-lang/crates.io-index" 1666 | checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" 1667 | dependencies = [ 1668 | "proc-macro2", 1669 | "quote", 1670 | "syn 2.0.82", 1671 | ] 1672 | 1673 | [[package]] 1674 | name = "time" 1675 | version = "0.3.36" 1676 | source = "registry+https://github.com/rust-lang/crates.io-index" 1677 | checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" 1678 | dependencies = [ 1679 | "deranged", 1680 | "num-conv", 1681 | "powerfmt", 1682 | "serde", 1683 | "time-core", 1684 | ] 1685 | 1686 | [[package]] 1687 | name = "time-core" 1688 | version = "0.1.2" 1689 | source = "registry+https://github.com/rust-lang/crates.io-index" 1690 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 1691 | 1692 | [[package]] 1693 | name = "tokio" 1694 | version = "1.43.0" 1695 | source = "registry+https://github.com/rust-lang/crates.io-index" 1696 | checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" 1697 | dependencies = [ 1698 | "backtrace", 1699 | "bytes", 1700 | "libc", 1701 | "mio", 1702 | "parking_lot", 1703 | "pin-project-lite", 1704 | "signal-hook-registry", 1705 | "socket2", 1706 | "tokio-macros", 1707 | "windows-sys 0.52.0", 1708 | ] 1709 | 1710 | [[package]] 1711 | name = "tokio-macros" 1712 | version = "2.5.0" 1713 | source = "registry+https://github.com/rust-lang/crates.io-index" 1714 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1715 | dependencies = [ 1716 | "proc-macro2", 1717 | "quote", 1718 | "syn 2.0.82", 1719 | ] 1720 | 1721 | [[package]] 1722 | name = "toml" 1723 | version = "0.8.15" 1724 | source = "registry+https://github.com/rust-lang/crates.io-index" 1725 | checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" 1726 | dependencies = [ 1727 | "serde", 1728 | "serde_spanned", 1729 | "toml_datetime", 1730 | "toml_edit 0.22.16", 1731 | ] 1732 | 1733 | [[package]] 1734 | name = "toml_datetime" 1735 | version = "0.6.6" 1736 | source = "registry+https://github.com/rust-lang/crates.io-index" 1737 | checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" 1738 | dependencies = [ 1739 | "serde", 1740 | ] 1741 | 1742 | [[package]] 1743 | name = "toml_edit" 1744 | version = "0.21.1" 1745 | source = "registry+https://github.com/rust-lang/crates.io-index" 1746 | checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" 1747 | dependencies = [ 1748 | "indexmap", 1749 | "toml_datetime", 1750 | "winnow 0.5.40", 1751 | ] 1752 | 1753 | [[package]] 1754 | name = "toml_edit" 1755 | version = "0.22.16" 1756 | source = "registry+https://github.com/rust-lang/crates.io-index" 1757 | checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" 1758 | dependencies = [ 1759 | "indexmap", 1760 | "serde", 1761 | "serde_spanned", 1762 | "toml_datetime", 1763 | "winnow 0.6.9", 1764 | ] 1765 | 1766 | [[package]] 1767 | name = "tower" 1768 | version = "0.5.2" 1769 | source = "registry+https://github.com/rust-lang/crates.io-index" 1770 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 1771 | dependencies = [ 1772 | "futures-core", 1773 | "futures-util", 1774 | "pin-project-lite", 1775 | "sync_wrapper", 1776 | "tokio", 1777 | "tower-layer", 1778 | "tower-service", 1779 | "tracing", 1780 | ] 1781 | 1782 | [[package]] 1783 | name = "tower-layer" 1784 | version = "0.3.3" 1785 | source = "registry+https://github.com/rust-lang/crates.io-index" 1786 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 1787 | 1788 | [[package]] 1789 | name = "tower-service" 1790 | version = "0.3.3" 1791 | source = "registry+https://github.com/rust-lang/crates.io-index" 1792 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1793 | 1794 | [[package]] 1795 | name = "tracing" 1796 | version = "0.1.40" 1797 | source = "registry+https://github.com/rust-lang/crates.io-index" 1798 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 1799 | dependencies = [ 1800 | "log", 1801 | "pin-project-lite", 1802 | "tracing-attributes", 1803 | "tracing-core", 1804 | ] 1805 | 1806 | [[package]] 1807 | name = "tracing-attributes" 1808 | version = "0.1.27" 1809 | source = "registry+https://github.com/rust-lang/crates.io-index" 1810 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 1811 | dependencies = [ 1812 | "proc-macro2", 1813 | "quote", 1814 | "syn 2.0.82", 1815 | ] 1816 | 1817 | [[package]] 1818 | name = "tracing-core" 1819 | version = "0.1.32" 1820 | source = "registry+https://github.com/rust-lang/crates.io-index" 1821 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 1822 | dependencies = [ 1823 | "once_cell", 1824 | ] 1825 | 1826 | [[package]] 1827 | name = "tree-sitter" 1828 | version = "0.19.5" 1829 | source = "registry+https://github.com/rust-lang/crates.io-index" 1830 | checksum = "ad726ec26496bf4c083fff0f43d4eb3a2ad1bba305323af5ff91383c0b6ecac0" 1831 | dependencies = [ 1832 | "cc", 1833 | "regex", 1834 | ] 1835 | 1836 | [[package]] 1837 | name = "tree-sitter-bash" 1838 | version = "0.19.0" 1839 | source = "registry+https://github.com/rust-lang/crates.io-index" 1840 | checksum = "c629e2d29ebb85b34cd195a1c511a161ed775451456cde110470e7af693424db" 1841 | dependencies = [ 1842 | "cc", 1843 | "tree-sitter", 1844 | ] 1845 | 1846 | [[package]] 1847 | name = "uds_windows" 1848 | version = "1.1.0" 1849 | source = "registry+https://github.com/rust-lang/crates.io-index" 1850 | checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" 1851 | dependencies = [ 1852 | "memoffset", 1853 | "tempfile", 1854 | "winapi", 1855 | ] 1856 | 1857 | [[package]] 1858 | name = "unicode-ident" 1859 | version = "1.0.12" 1860 | source = "registry+https://github.com/rust-lang/crates.io-index" 1861 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1862 | 1863 | [[package]] 1864 | name = "urlencoding" 1865 | version = "2.1.3" 1866 | source = "registry+https://github.com/rust-lang/crates.io-index" 1867 | checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" 1868 | 1869 | [[package]] 1870 | name = "utf8parse" 1871 | version = "0.2.1" 1872 | source = "registry+https://github.com/rust-lang/crates.io-index" 1873 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1874 | 1875 | [[package]] 1876 | name = "wait-timeout" 1877 | version = "0.2.0" 1878 | source = "registry+https://github.com/rust-lang/crates.io-index" 1879 | checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" 1880 | dependencies = [ 1881 | "libc", 1882 | ] 1883 | 1884 | [[package]] 1885 | name = "wasi" 1886 | version = "0.11.0+wasi-snapshot-preview1" 1887 | source = "registry+https://github.com/rust-lang/crates.io-index" 1888 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1889 | 1890 | [[package]] 1891 | name = "winapi" 1892 | version = "0.3.9" 1893 | source = "registry+https://github.com/rust-lang/crates.io-index" 1894 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1895 | dependencies = [ 1896 | "winapi-i686-pc-windows-gnu", 1897 | "winapi-x86_64-pc-windows-gnu", 1898 | ] 1899 | 1900 | [[package]] 1901 | name = "winapi-i686-pc-windows-gnu" 1902 | version = "0.4.0" 1903 | source = "registry+https://github.com/rust-lang/crates.io-index" 1904 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1905 | 1906 | [[package]] 1907 | name = "winapi-x86_64-pc-windows-gnu" 1908 | version = "0.4.0" 1909 | source = "registry+https://github.com/rust-lang/crates.io-index" 1910 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1911 | 1912 | [[package]] 1913 | name = "windows" 1914 | version = "0.56.0" 1915 | source = "registry+https://github.com/rust-lang/crates.io-index" 1916 | checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" 1917 | dependencies = [ 1918 | "windows-core", 1919 | "windows-targets", 1920 | ] 1921 | 1922 | [[package]] 1923 | name = "windows-core" 1924 | version = "0.56.0" 1925 | source = "registry+https://github.com/rust-lang/crates.io-index" 1926 | checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" 1927 | dependencies = [ 1928 | "windows-implement", 1929 | "windows-interface", 1930 | "windows-result", 1931 | "windows-targets", 1932 | ] 1933 | 1934 | [[package]] 1935 | name = "windows-implement" 1936 | version = "0.56.0" 1937 | source = "registry+https://github.com/rust-lang/crates.io-index" 1938 | checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" 1939 | dependencies = [ 1940 | "proc-macro2", 1941 | "quote", 1942 | "syn 2.0.82", 1943 | ] 1944 | 1945 | [[package]] 1946 | name = "windows-interface" 1947 | version = "0.56.0" 1948 | source = "registry+https://github.com/rust-lang/crates.io-index" 1949 | checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" 1950 | dependencies = [ 1951 | "proc-macro2", 1952 | "quote", 1953 | "syn 2.0.82", 1954 | ] 1955 | 1956 | [[package]] 1957 | name = "windows-result" 1958 | version = "0.1.2" 1959 | source = "registry+https://github.com/rust-lang/crates.io-index" 1960 | checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" 1961 | dependencies = [ 1962 | "windows-targets", 1963 | ] 1964 | 1965 | [[package]] 1966 | name = "windows-sys" 1967 | version = "0.52.0" 1968 | source = "registry+https://github.com/rust-lang/crates.io-index" 1969 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1970 | dependencies = [ 1971 | "windows-targets", 1972 | ] 1973 | 1974 | [[package]] 1975 | name = "windows-sys" 1976 | version = "0.59.0" 1977 | source = "registry+https://github.com/rust-lang/crates.io-index" 1978 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1979 | dependencies = [ 1980 | "windows-targets", 1981 | ] 1982 | 1983 | [[package]] 1984 | name = "windows-targets" 1985 | version = "0.52.6" 1986 | source = "registry+https://github.com/rust-lang/crates.io-index" 1987 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1988 | dependencies = [ 1989 | "windows_aarch64_gnullvm", 1990 | "windows_aarch64_msvc", 1991 | "windows_i686_gnu", 1992 | "windows_i686_gnullvm", 1993 | "windows_i686_msvc", 1994 | "windows_x86_64_gnu", 1995 | "windows_x86_64_gnullvm", 1996 | "windows_x86_64_msvc", 1997 | ] 1998 | 1999 | [[package]] 2000 | name = "windows-version" 2001 | version = "0.1.1" 2002 | source = "registry+https://github.com/rust-lang/crates.io-index" 2003 | checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515" 2004 | dependencies = [ 2005 | "windows-targets", 2006 | ] 2007 | 2008 | [[package]] 2009 | name = "windows_aarch64_gnullvm" 2010 | version = "0.52.6" 2011 | source = "registry+https://github.com/rust-lang/crates.io-index" 2012 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2013 | 2014 | [[package]] 2015 | name = "windows_aarch64_msvc" 2016 | version = "0.52.6" 2017 | source = "registry+https://github.com/rust-lang/crates.io-index" 2018 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2019 | 2020 | [[package]] 2021 | name = "windows_i686_gnu" 2022 | version = "0.52.6" 2023 | source = "registry+https://github.com/rust-lang/crates.io-index" 2024 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2025 | 2026 | [[package]] 2027 | name = "windows_i686_gnullvm" 2028 | version = "0.52.6" 2029 | source = "registry+https://github.com/rust-lang/crates.io-index" 2030 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2031 | 2032 | [[package]] 2033 | name = "windows_i686_msvc" 2034 | version = "0.52.6" 2035 | source = "registry+https://github.com/rust-lang/crates.io-index" 2036 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2037 | 2038 | [[package]] 2039 | name = "windows_x86_64_gnu" 2040 | version = "0.52.6" 2041 | source = "registry+https://github.com/rust-lang/crates.io-index" 2042 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2043 | 2044 | [[package]] 2045 | name = "windows_x86_64_gnullvm" 2046 | version = "0.52.6" 2047 | source = "registry+https://github.com/rust-lang/crates.io-index" 2048 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2049 | 2050 | [[package]] 2051 | name = "windows_x86_64_msvc" 2052 | version = "0.52.6" 2053 | source = "registry+https://github.com/rust-lang/crates.io-index" 2054 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2055 | 2056 | [[package]] 2057 | name = "winnow" 2058 | version = "0.5.40" 2059 | source = "registry+https://github.com/rust-lang/crates.io-index" 2060 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 2061 | dependencies = [ 2062 | "memchr", 2063 | ] 2064 | 2065 | [[package]] 2066 | name = "winnow" 2067 | version = "0.6.9" 2068 | source = "registry+https://github.com/rust-lang/crates.io-index" 2069 | checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6" 2070 | dependencies = [ 2071 | "memchr", 2072 | ] 2073 | 2074 | [[package]] 2075 | name = "winnow" 2076 | version = "0.7.3" 2077 | source = "registry+https://github.com/rust-lang/crates.io-index" 2078 | checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" 2079 | dependencies = [ 2080 | "memchr", 2081 | ] 2082 | 2083 | [[package]] 2084 | name = "xdg-home" 2085 | version = "1.2.0" 2086 | source = "registry+https://github.com/rust-lang/crates.io-index" 2087 | checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" 2088 | dependencies = [ 2089 | "libc", 2090 | "windows-sys 0.52.0", 2091 | ] 2092 | 2093 | [[package]] 2094 | name = "zbus" 2095 | version = "5.0.0" 2096 | source = "registry+https://github.com/rust-lang/crates.io-index" 2097 | checksum = "0d17185ff0b54cf0af51da5762f9ccef45b633af5006651669fe90bb97e830f4" 2098 | dependencies = [ 2099 | "async-broadcast", 2100 | "async-executor", 2101 | "async-fs", 2102 | "async-io", 2103 | "async-lock", 2104 | "async-process", 2105 | "async-recursion", 2106 | "async-task", 2107 | "async-trait", 2108 | "blocking", 2109 | "enumflags2", 2110 | "event-listener", 2111 | "futures-core", 2112 | "futures-util", 2113 | "hex", 2114 | "nix", 2115 | "ordered-stream", 2116 | "serde", 2117 | "serde_repr", 2118 | "static_assertions", 2119 | "tracing", 2120 | "uds_windows", 2121 | "windows-sys 0.59.0", 2122 | "xdg-home", 2123 | "zbus_macros", 2124 | "zbus_names", 2125 | "zvariant", 2126 | ] 2127 | 2128 | [[package]] 2129 | name = "zbus_macros" 2130 | version = "5.0.0" 2131 | source = "registry+https://github.com/rust-lang/crates.io-index" 2132 | checksum = "ed3ad52bf7d51ef2a7b1bf9bbac6a2ebb8c77c7df297d3246963573d931bd5fd" 2133 | dependencies = [ 2134 | "proc-macro-crate", 2135 | "proc-macro2", 2136 | "quote", 2137 | "syn 2.0.82", 2138 | "zvariant_utils", 2139 | ] 2140 | 2141 | [[package]] 2142 | name = "zbus_names" 2143 | version = "4.2.0" 2144 | source = "registry+https://github.com/rust-lang/crates.io-index" 2145 | checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" 2146 | dependencies = [ 2147 | "serde", 2148 | "static_assertions", 2149 | "winnow 0.7.3", 2150 | "zvariant", 2151 | ] 2152 | 2153 | [[package]] 2154 | name = "zvariant" 2155 | version = "5.0.0" 2156 | source = "registry+https://github.com/rust-lang/crates.io-index" 2157 | checksum = "b909387da6d5787949f780919b5149d7f29f2f03f75eb883a67206e780b48fab" 2158 | dependencies = [ 2159 | "endi", 2160 | "enumflags2", 2161 | "serde", 2162 | "static_assertions", 2163 | "zvariant_derive", 2164 | "zvariant_utils", 2165 | ] 2166 | 2167 | [[package]] 2168 | name = "zvariant_derive" 2169 | version = "5.0.0" 2170 | source = "registry+https://github.com/rust-lang/crates.io-index" 2171 | checksum = "67fb722e4d5e0d88a4c370c17abf3e2323c549d9580b4c2d775f475a45b34307" 2172 | dependencies = [ 2173 | "proc-macro-crate", 2174 | "proc-macro2", 2175 | "quote", 2176 | "syn 2.0.82", 2177 | "zvariant_utils", 2178 | ] 2179 | 2180 | [[package]] 2181 | name = "zvariant_utils" 2182 | version = "3.0.0" 2183 | source = "registry+https://github.com/rust-lang/crates.io-index" 2184 | checksum = "05195b9a8930cfccb637b8ff1531404b5e16c5383f8f025078106793e24f9974" 2185 | dependencies = [ 2186 | "nom", 2187 | "proc-macro2", 2188 | "quote", 2189 | "serde", 2190 | "static_assertions", 2191 | "syn 2.0.82", 2192 | ] 2193 | --------------------------------------------------------------------------------