diff --git a/Cargo.lock b/Cargo.lock index f776354..31d64ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,6 +73,25 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "cbindgen" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975982cdb7ad6a142be15bdf84aea7ec6a9e5d4d797c004d43185b24cfe4e684" +dependencies = [ + "clap", + "heck", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", + "tempfile", + "toml 0.8.23", +] + [[package]] name = "cfg-if" version = "1.0.3" @@ -184,6 +203,24 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + [[package]] name = "hashbrown" version = "0.16.0" @@ -212,6 +249,12 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + [[package]] name = "js-sys" version = "0.3.81" @@ -314,6 +357,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "redox_syscall" version = "0.5.18" @@ -371,6 +420,12 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + [[package]] name = "scopeguard" version = "1.2.0" @@ -407,6 +462,28 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + [[package]] name = "serde_spanned" version = "1.0.3" @@ -439,6 +516,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.60.2", +] + [[package]] name = "thiserror" version = "2.0.17" @@ -459,6 +549,18 @@ dependencies = [ "syn", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit", +] + [[package]] name = "toml" version = "0.9.8" @@ -467,13 +569,22 @@ checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ "indexmap", "serde_core", - "serde_spanned", - "toml_datetime", + "serde_spanned 1.0.3", + "toml_datetime 0.7.3", "toml_parser", "toml_writer", "winnow", ] +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + [[package]] name = "toml_datetime" version = "0.7.3" @@ -483,6 +594,20 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow", +] + [[package]] name = "toml_parser" version = "1.0.4" @@ -492,6 +617,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "toml_writer" version = "1.0.4" @@ -532,6 +663,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.104" @@ -607,6 +747,7 @@ dependencies = [ name = "wfassoc_dylib" version = "0.1.0" dependencies = [ + "cbindgen", "thiserror", "wfassoc", ] @@ -619,7 +760,7 @@ dependencies = [ "comfy-table", "serde", "thiserror", - "toml", + "toml 0.9.8", "wfassoc", ] @@ -803,6 +944,9 @@ name = "winnow" version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] [[package]] name = "winreg" @@ -813,3 +957,9 @@ dependencies = [ "cfg-if", "windows-sys 0.59.0", ] + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" diff --git a/README.md b/README.md index f8640aa..148e5d5 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ and provide it and `wfassoc_exec` with your executable. By executing `wfassoc_exec` with this TOML file in your executable, you can simply achieve this goal and analyze its return value to check whether it success. -However, if you are prefering taht let user decide which file associations should be created, +However, if you are prefering that let user decide which file associations should be created, even have an UI displaying all current file association related with this program (like 7-Zip File Manager does), you can choose `wfassoc_dylib` for your solution. `wfassoc_dylib` expose all essential functions for this task. diff --git a/example/ppic.toml b/example/ppic.toml index 1721778..5521927 100644 --- a/example/ppic.toml +++ b/example/ppic.toml @@ -1,12 +1,40 @@ +# Identifier is used as an unique symbol for your program. +# Please choose it carefully to avoid any name conflict. +# +# The value of identifier should only contain alphabet chars and digits and +# digits should not be the first char (like C variable naming convention). +# +# More preciously, this identifier is used as the "vendor" part of ProgId. identifier = "PineapplePicture" +# The fully qualified path to the application. +# +# A fully qualified path or absolute path always defines an exact path +# from a particular drive or device to a target file or directory, +# and does not depend on the current drive or current directory. +# +# Considering Windows use back-slash as path splittor, which is frequently used as escape char, +# you can utilize "literal strings" syntax in this TOML file to quickly write this path +# as this example following does. path = 'C:\path\to\ppic.exe' +# CLSID is an unique UUID or GUID of your program. clsid = "{B5291320-FE7C-4069-BF87-A0AC327FCD20}" [manners] +# Each manner has a name as its key, and detailed command line arguments list as its value. +# The name of manner will be used sonner for associating with specific file extension. +# The command line arguments indicate which program should be executed and how to configure their arguments. +# +# Also, you can utilize "literal strings" syntax to write this pair, +# because quotes usually need special escape in "basic string" syntax. common = '"C:\path\to\ppic.exe" "%1"' +# "exts" list hold all potential file extensions related with this program, +# and the correct manner for opening them. [exts] +# In this case, we bind ".jpg" file extension with "common" manner for opening +# which was defined above. ".jpg" = "common" +# Set more file extensions with manner defined above. ".jfif" = "common" ".gif" = "common" ".bmp" = "common" diff --git a/wfassoc/src/lib.rs b/wfassoc/src/lib.rs index 7c3a9a3..4fc6a0a 100644 --- a/wfassoc/src/lib.rs +++ b/wfassoc/src/lib.rs @@ -125,6 +125,7 @@ impl From for View { /// or more preciously, the consititution of command arguments passed to program. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Manner { + // TODO: use specialized WinArg instead. argv: String, } @@ -147,6 +148,7 @@ impl Display for Manner { // region: Program /// The struct representing a complete program for registration and unregistration. +#[derive(Debug)] pub struct Program { /// The identifier of this program. identifier: String, diff --git a/wfassoc_dylib/Cargo.toml b/wfassoc_dylib/Cargo.toml index 850493f..b458c3f 100644 --- a/wfassoc_dylib/Cargo.toml +++ b/wfassoc_dylib/Cargo.toml @@ -6,6 +6,12 @@ edition = "2024" description = "The dynamic wfassoc library exposed for C/C++ and other languages users." license = "SPDX:MIT" +[lib] +crate-type = ["cdylib"] + [dependencies] thiserror = { workspace = true } wfassoc = { path="../wfassoc" } + +[build-dependencies] +cbindgen = "0.29.0" diff --git a/wfassoc_dylib/src/lib.rs b/wfassoc_dylib/src/lib.rs index b93cf3f..e4f99f9 100644 --- a/wfassoc_dylib/src/lib.rs +++ b/wfassoc_dylib/src/lib.rs @@ -1,14 +1,5 @@ -pub fn add(left: u64, right: u64) -> u64 { + +#[unsafe(no_mangle)] +pub extern "C" fn WFAdd(left: u32, right: u32) -> u32 { left + right } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/wfassoc_exec/src/main.rs b/wfassoc_exec/src/main.rs index 8a697b6..1048207 100644 --- a/wfassoc_exec/src/main.rs +++ b/wfassoc_exec/src/main.rs @@ -2,7 +2,10 @@ pub(crate) mod cli; pub(crate) mod manifest; use clap::Parser; -use std::{collections::HashMap, path::Path, process}; +use std::collections::HashMap; +use std::path::{Path, PathBuf}; +use std::process; +use std::str::FromStr; use thiserror::Error as TeError; use wfassoc::{Program, Token}; use cli::{Cli, Commands}; @@ -39,9 +42,9 @@ fn build_program(cli: &Cli) -> Result { // Open file and read manifest TOML file let mf = Manifest::from_file(&cli.config_file)?; // Create instance - let rv = Program::new(&mf.identifier, &Path::from(mf.path.as_str()))?; + let mut rv = Program::new(&mf.identifier, PathBuf::from_str(&cli.config_file).unwrap().as_path())?; // Setup manner - let manners: HashMap<&str, Token> = HashMap::new(); + let mut manners: HashMap<&str, Token> = HashMap::new(); for (k, v) in mf.manners.iter() { let token = rv.add_manner(v.as_str())?; manners.insert(k.as_str(), token); @@ -72,7 +75,8 @@ fn run_unregister(cli: &Cli) -> Result<()> { } fn run_query(cli: &Cli) -> Result<()> { - + let program = build_program(cli)?; + print!("{:?}", program); Ok(()) }