diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5e664d..8edef4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: Cdio's Rust CI +name: libcdio-rs CI on: push: diff --git a/Cargo.lock b/Cargo.lock index 425166a..1fb8688 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -61,43 +61,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "anyhow" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[package]] -name = "assert_cmd" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aa3a22042e45de04255c7bf3626e239f450200fd0493c1e382263544b20aea6" -dependencies = [ - "anstream", - "anstyle", - "bstr", - "libc", - "predicates", - "predicates-core", - "predicates-tree", - "wait-timeout", -] - -[[package]] -name = "assert_fs" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ecf5c70ca07b7f80220bce936f0556a960ca6fb00fc2bd4125b5e581b218137" -dependencies = [ - "anstream", - "anstyle", - "globwalk", - "predicates", - "predicates-core", - "predicates-tree", - "tempfile", -] - [[package]] name = "bindgen" version = "0.72.1" @@ -115,31 +78,20 @@ dependencies = [ "regex", "rustc-hash", "shlex 1.3.0", - "syn", + "syn 2.0.119", ] [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" - -[[package]] -name = "bstr" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" -dependencies = [ - "memchr", - "regex-automata", - "serde", -] +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "cc" -version = "1.4.2" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "shlex 2.0.1", @@ -156,9 +108,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.20.7" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6b04e07d8080154ed4ac03546d9a2b303cc2fe1901ba0b35b301516e289368" +checksum = "fe4ece8474b5f766c63426647e7b4b316b67431ade1036a8313cee24a03ae917" dependencies = [ "smallvec", "target-lexicon", @@ -172,110 +124,36 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "clang-sys" -version = "1.8.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" dependencies = [ "glob", "libc", "libloading", ] -[[package]] -name = "clap" -version = "4.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" - [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - [[package]] name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "difflib" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" [[package]] name = "displaydoc" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -295,29 +173,30 @@ checksum = "11772ed3eb3db124d826f3abeadf5a791a557f62c19b123e3f07288158a71fdd" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "either" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "env_filter" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" dependencies = [ "log", + "regex", ] [[package]] name = "env_logger" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" dependencies = [ "anstream", "anstyle", @@ -331,22 +210,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "fastrand" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" - [[package]] name = "file-mode" version = "0.1.2" @@ -358,39 +221,15 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "globset" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "globwalk" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" -dependencies = [ - "bitflags", - "ignore", - "walkdir", -] +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "hashbrown" @@ -404,22 +243,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "ignore" -version = "0.4.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b915661dd01db3f05050265b2477bcc6527b3792388e2749b41623cc592be67d" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata", - "same-file", - "walkdir", - "winapi-util", -] - [[package]] name = "indexmap" version = "2.14.0" @@ -445,12 +268,6 @@ dependencies = [ "either", ] -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - [[package]] name = "lazy_static" version = "1.5.0" @@ -459,22 +276,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "libcdio-cli" -version = "0.1.0" -dependencies = [ - "anyhow", - "assert_cmd", - "assert_fs", - "clap", - "libcdio-rs", - "time", - "tracing-subscriber", -] +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libcdio-rs" @@ -496,7 +300,8 @@ dependencies = [ [[package]] name = "libcdio-sys" version = "3.0.0+2.4.0p2.0.2" -source = "git+https://github.com/libcdio/libcdio-sys.git?rev=a232be6#a232be6d7d1898eaeaa9c1dedcecbcf3bfcced4e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3341bd0c18a38e2a02fe6645b375f007e8023672a59b0c50554954e97c46da3b" dependencies = [ "bindgen", "cc", @@ -513,17 +318,11 @@ dependencies = [ "windows-link", ] -[[package]] -name = "linux-raw-sys" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" - [[package]] name = "log" -version = "0.4.30" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "matchers" @@ -536,9 +335,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "minimal-lexical" @@ -590,7 +389,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -622,9 +421,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "powerfmt" @@ -632,33 +431,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "predicates" -version = "3.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe" -dependencies = [ - "anstyle", - "difflib", - "predicates-core", -] - -[[package]] -name = "predicates-core" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" - -[[package]] -name = "predicates-tree" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" -dependencies = [ - "predicates-core", - "termtree", -] - [[package]] name = "prettyplease" version = "0.2.37" @@ -666,7 +438,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.119", ] [[package]] @@ -680,27 +452,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -710,9 +482,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -721,71 +493,40 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" - -[[package]] -name = "rustix" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "serde" -version = "1.0.228" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", -] +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -820,21 +561,26 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] -name = "strsim" -version = "0.11.1" +name = "syn" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "2.0.117" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -856,33 +602,15 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" - -[[package]] -name = "tempfile" -version = "3.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" -dependencies = [ - "fastrand", - "once_cell", - "rustix", - "windows-sys", -] - -[[package]] -name = "termtree" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "test-log" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f46bf474f0a4afebf92f076d54fd5e63423d9438b8c278a3d2ccb0f47f7cdb3" +checksum = "9b9c218384242b5c89b68303ab6f6fc53a312d923f0c14dc6bb860c6aeee40f1" dependencies = [ "env_logger", "test-log-macros", @@ -891,62 +619,61 @@ dependencies = [ [[package]] name = "test-log-core" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d4d41320b48bc4a211a9021678fcc0c99569b594ea31c93735b8e517102b4c" +checksum = "c26ef8b00e4d382e59f6a8ddb3cd790b3a5bb29f21a358a9a69ea2f29f13f27b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "test-log-macros" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9beb9249a81e430dffd42400a49019bcf548444f1968ff23080a625de0d4d320" +checksum = "944ad38adcbb71eaa682c56bceeb079e4ca82b4b3edc2a0fde5cb297b77dac8d" dependencies = [ - "syn", + "syn 2.0.119", "test-log-core", ] [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] [[package]] name = "time" -version = "0.3.47" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", - "itoa", "libc", "num-conv", "num_threads", @@ -958,15 +685,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" dependencies = [ "num-conv", "time-core", @@ -974,9 +701,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5" dependencies = [ "indexmap", "serde_core", @@ -998,9 +725,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.13+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" dependencies = [ "indexmap", "toml_datetime", @@ -1010,18 +737,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tracing" @@ -1029,11 +756,22 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ - "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "tracing-core" version = "0.1.36" @@ -1066,7 +804,6 @@ dependencies = [ "once_cell", "regex-automata", "sharded-slab", - "smallvec", "thread_local", "tracing", "tracing-core", @@ -1097,34 +834,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" -[[package]] -name = "wait-timeout" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" -dependencies = [ - "libc", -] - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys", -] - [[package]] name = "windows-link" version = "0.2.1" @@ -1142,9 +851,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 6cbbeef..a38e304 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,35 @@ -[workspace] -resolver = "3" -members = ["libcdio-cli", "libcdio-rs"] - -[workspace.package] +[package] +name = "libcdio-rs" +version = "0.1.0" authors = ["Shiva Kiran Koninty "] -description = "Rust implementation and Utility programs of the Compact Disc Input and Control Core Library." edition = "2024" +description = "Safe wrapper and Rust port of GNU libcdio." +repository = "https://github.com/libcdio/libcdio-rs" license = "GPL-3.0-or-later" -readme = "README.md" -repository = "https://github.com/libcdio/cdio-rust" +keywords = ["cd", "scsi", "iso9660", "udf"] +categories = ["api-bindings", "multimedia::audio", "filesystem", "hardware-support"] + +[features] +iso9660 = ["libcdio-sys/iso9660", "dep:file-mode", "dep:time"] +mmc = ["dep:winnow"] +udf = ["libcdio-sys/udf", "dep:file-mode", "dep:time"] + +[dependencies] +bitflags = "2.2.1" +displaydoc = "0.2.5" +docsplay = "0.1.3" +file-mode = { version = "0.1.0", optional = true } +libcdio-sys = { version = "3.0.0", default-features = false } +num_enum = { version = "0.7.6", features = ["complex-expressions"] } +thiserror = "2.0.0" +time = { version = "0.3.31", features = ["local-offset"], optional = true } +tracing = "0.1.6" +winnow = { version = "1.0.0", features = ["binary", "parser", "std"], default-features = false, optional = true } + +[dev-dependencies] +test-log = "0.2.21" +time = { version = "0.3.31", features = ["macros"] } -[workspace.dependencies] -libcdio-sys = { git = "https://github.com/libcdio/libcdio-sys.git", rev = "a232be6", default-features = false } -test-log = { version = "0.2.20", features = ["trace"] } -time = "0.3.47" -tracing = { version = "0.1.44", default-features = false, features = ["log", "std"] } +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/README.md b/README.md index 7a2816e..d2cb55a 100644 --- a/README.md +++ b/README.md @@ -1,108 +1,32 @@ -# cdio-rust +# libcdio-rs +Safe wrapper and Rust port of [GNU libcdio][libcdio-site]. -Rust implementation and Utility programs of the Compact Disc Input and -Control Core Library. +For raw bindings, check out [libcdio-sys][libcdio-sys]. -This Cargo workspace contains two packages: -- [libcdio-rs](./libcdio-rs): Safe Rust abstraction over libcdio C -- [libcdio-cli](./libcdio-cli): Utility programs that use libcdio +## Usage +- Install [clang][bindgen-reqs]. +- Add with cargo: + ```shell + cargo add libcdio-rs --all-features + ``` -## Status - * [x] cd-drive: show CD-ROM drive characteristics - * [ ] cd-info: show information about a CD or CD-image - * [ ] cd-paranoia: an audio CD ripper - * [ ] cd-read: read information from a CD or CD-image - * [ ] cdda-player: a simple curses-based audio CD player - * [x] iso-info: show information about an ISO 9660 image - * [x] iso-read: read portions of an ISO 9660 image - * [ ] mmc-tool: issue low-level commands to a CD drive +Feature flags are provided and guard the modules named after them. +See the [documentation][docs]. -## Development -### Build Requirements -- [Cargo](https://rust-lang.org/learn/get-started/): The Rust build tool -- [libclang](https://rust-lang.github.io/rust-bindgen/requirements.html): - Used by `libcdio-sys` for generating Rust bindings to libcdio -- [libcdio](https://github.com/libcdio/libcdio): libcdio headers. Consult your package manager. - - Debian: `libcdio-headers` - - Fedora: `libcdio-devel` -### Build -```sh -cargo build --release -``` -Omit `--release` for debug builds. -The build outputs should be in the `target` directory. +## Design +Currently, this library is partly a safe wrapper over libcdio and +partly a port, with the goal of an eventual transition to a full +rewrite. -### Run the tests -```sh -cargo test -``` +Progress so far: +- Ported SCSI MMC functionality. +- Implemented safe wrappers for a subset of ISO 9660 and UDF routines. -To run ignored tests, which require some extra setup: -```sh -cargo test -- --include-ignored -``` +## SCSI MMC references +This library implements SCSI routines primarily based on +[MMC-6 rev.2g][mmc6r2g] and [SPC-3 rev.23][spc3r23]. -To run tests which require manual intervention: -```sh -MANUAL_TESTS=1 cargo test -- [TEST_FILTER1 TEST_FILTER2...] --include-ignored -``` - -### Run the executables -For example, to run the `iso-info` program: -```sh -cargo run --bin iso-info-rs -- ./test-data/rock-ridge.iso -``` - -### Use the provided Git Hooks -These automatically perform lint and formatting checks: -```sh -git config core.hooksPath .githooks -``` - -To skip hooks, use `--no-verify`: -```sh -git commit --no-verify -``` - -### How to use a local build of libcdio -Build libcdio with the `--without-versioned-libs` option. -```sh -cd libcdio -autoreconf -f -i -./configure --without-versioned-libs -make -``` - -Set the following environment variables: -```sh -# Set this to the (absolute!) path of your libcdio build directory -export LIBCDIO_ROOT="/home/skran/libcdio" - -export SYSTEM_DEPS_LIBCDIO_NO_PKG_CONFIG="yes" -export SYSTEM_DEPS_LIBCDIO_SEARCH_NATIVE="$LIBCDIO_ROOT/lib/driver/.libs" -export SYSTEM_DEPS_LIBCDIO_INCLUDE="$LIBCDIO_ROOT/include" -export SYSTEM_DEPS_LIBCDIO_LIB="cdio" - -export SYSTEM_DEPS_LIBISO9660_NO_PKG_CONFIG="yes" -export SYSTEM_DEPS_LIBISO9660_SEARCH_NATIVE="$LIBCDIO_ROOT/lib/iso9660/.libs" -export SYSTEM_DEPS_LIBISO9660_INCLUDE="$LIBCDIO_ROOT/include" -export SYSTEM_DEPS_LIBISO9660_LIB="iso9660" - -export SYSTEM_DEPS_LIBUDF_NO_PKG_CONFIG="yes" -export SYSTEM_DEPS_LIBUDF_SEARCH_NATIVE="$LIBCDIO_ROOT/lib/udf/.libs" -export SYSTEM_DEPS_LIBUDF_INCLUDE="$LIBCDIO_ROOT/include" -export SYSTEM_DEPS_LIBUDF_LIB="udf" - -export BINDGEN_EXTRA_CLANG_ARGS="-I$LIBCDIO_ROOT/include" -export LD_LIBRARY_PATH="$LIBCDIO_ROOT/lib/driver/.libs:$LIBCDIO_ROOT/lib/iso9660/.libs:$LIBCDIO_ROOT/lib/udf/.libs:$LD_LIBRARY_PATH" - -# For macOS -export LD_LIBRARY_PATH="$LIBCDIO_ROOT/lib/driver/.libs:$LIBCDIO_ROOT/lib/iso9660/.libs:$LIBCDIO_ROOT/lib/udf/.libs:$DYLD_LIBRARY_PATH" -``` - -That's it. Cargo should now use your local copy of libcdio. - -# License +## License Copyright (C) 2026 Shiva Kiran Koninty This program is free software: you can redistribute it and/or modify @@ -117,3 +41,10 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . + +[libcdio-site]: https://libcdio.github.io +[libcdio-sys]: https://crates.io/crates/libcdio-sys +[bindgen-reqs]: https://rust-lang.github.io/rust-bindgen/requirements.html +[docs]: https://docs.rs/libcdio-rs/latest/libcdio-rs +[mmc6r2g]: https://www.13thmonkey.org/documentation/SCSI/mmc6r02g.pdf +[spc3r23]: https://www.13thmonkey.org/documentation/SCSI/spc3r23.pdf diff --git a/libcdio-cli/COPYING b/libcdio-cli/COPYING deleted file mode 120000 index 012065c..0000000 --- a/libcdio-cli/COPYING +++ /dev/null @@ -1 +0,0 @@ -../COPYING \ No newline at end of file diff --git a/libcdio-cli/Cargo.toml b/libcdio-cli/Cargo.toml deleted file mode 100644 index f0d4b2d..0000000 --- a/libcdio-cli/Cargo.toml +++ /dev/null @@ -1,47 +0,0 @@ -[package] -name = "libcdio-cli" -version = "0.1.0" -edition.workspace = true -authors.workspace = true -description = "Utilities to work with CD/DVD media, ISO 9660 and UDF images" -license.workspace = true -repository.workspace = true - -[dependencies] -anyhow = "1.0.102" -clap = { version = "4.6.1", features = ["cargo", "derive"] } -libcdio-rs = { path = "../libcdio-rs" } -time = { workspace = true, features = ["formatting", "local-offset", "macros"], optional = true } -tracing-subscriber = { version = "0.3.23", features = ["env-filter"] } - -# TODO: Remove the "-rs" suffixes before release -[[bin]] -name = "cd-drive-rs" -path = "src/cd-drive/main.rs" -required-features = ["cd-drive"] - -[[bin]] -name = "iso-info-rs" -path = "src/iso-info/main.rs" -required-features = ["iso-info"] - -[[bin]] -name = "iso-read-rs" -path = "src/iso-read/main.rs" -required-features = ["iso-read"] - -[[bin]] -name = "mmc-tool-rs" -path = "src/mmc-tool/main.rs" -required-features = ["mmc-tool"] - -[features] -default = ["cd-drive", "iso-info", "iso-read", "mmc-tool"] -cd-drive = ["libcdio-rs/mmc"] -iso-info = ["libcdio-rs/iso9660", "libcdio-rs/udf", "dep:time"] -iso-read = ["libcdio-rs/iso9660", "libcdio-rs/udf"] -mmc-tool = ["libcdio-rs/mmc"] - -[dev-dependencies] -assert_cmd = { version = "2.2.2", features = ["color"] } -assert_fs = { version = "1.1.4", features = ["color"] } diff --git a/libcdio-cli/README.md b/libcdio-cli/README.md deleted file mode 100644 index b504486..0000000 --- a/libcdio-cli/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# libcdio-cli -Utilities to work with CD/DVD media, ISO 9660 and UDF images - -Also, checkout the workspace [readme](../README.md). - -## License -Copyright (C) 2026 Shiva Kiran Koninty - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . diff --git a/libcdio-cli/src/cd-drive/cli.rs b/libcdio-cli/src/cd-drive/cli.rs deleted file mode 100644 index 7480f4d..0000000 --- a/libcdio-cli/src/cd-drive/cli.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2026 Shiva Kiran Koninty -// -// This file is part of libcdio-cli. -// -// libcdio-cli is free software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// libcdio-cli is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with libcdio-cli. If not, see . - -use std::path::PathBuf; - -use clap::{Args, Parser}; - -/// Show information about a disc drive. -#[derive(Parser)] -#[command(long_about = libcdio_cli::HEADER, version)] -pub struct Cli { - /// Path to a disc drive. - #[command(flatten)] - pub drive: DriveArg, -} - -#[derive(Args)] -#[group(required = false, multiple = false)] -pub struct DriveArg { - /// Path to a disc drive. - #[arg(short = 'i', long = "input", value_name = "DRIVE")] - pub option: Option, - - /// Path to a disc drive. - #[arg(value_name = "DRIVE")] - pub positional: Option, -} diff --git a/libcdio-cli/src/cd-drive/main.rs b/libcdio-cli/src/cd-drive/main.rs deleted file mode 100644 index 2c032e8..0000000 --- a/libcdio-cli/src/cd-drive/main.rs +++ /dev/null @@ -1,186 +0,0 @@ -use std::path::PathBuf; - -use anyhow::Result; -use clap::Parser; -use libcdio_rs::{ - Drive, Mmc, - mmc::{MmcFeature, MmcProfile}, -}; -use tracing_subscriber::EnvFilter; - -use crate::cli::Cli; - -mod cli; - -fn main() -> Result<()> { - let cli = Cli::parse(); - tracing_subscriber::fmt() - .with_env_filter(EnvFilter::from_default_env()) - .init(); - let drive = cli.drive.positional.or(cli.drive.option); - if let Some(drive) = drive { - print_drive_info(drive)?; - } else if let drives = Drive::drives() - && !drives.is_empty() - { - for drive in drives { - if let Err(err) = print_drive_info(drive) { - println!("{err:?}"); - } - println!(); - } - } else { - println!("no drives connected"); - } - - Ok(()) -} - -fn print_drive_info(path: PathBuf) -> Result<()> { - println!("Using drive {}", path.display()); - let drive = Drive::with_drive(path.clone())?; - - if let Err(err) = print_device_info(&drive) { - println!("{err:?}"); - }; - - println!("MMC information:"); - match Mmc::with_device(path) { - Err(err) => println!("{err:?}"), - Ok(mmc) => print_mmc_features(&mmc), - }; - - print_drive_capabilities(&drive); - - Ok(()) -} - -fn print_device_info(drive: &Drive) -> Result<()> { - println!("Device information:"); - let identifiers = drive.hardware_identifiers()?; - println!("{L1} Vendor : {}", identifiers.vendor); - println!("{L1} Model : {}", identifiers.model); - println!("{L1} Revision : {}", identifiers.revision); - - Ok(()) -} - -fn print_mmc_features(mmc: &Mmc) { - println!("{L1} Supported features:"); - let features = match mmc.features() { - Ok(features) => features, - Err(err) => { - println!("{:?}", err); - return; - } - }; - - features.into_iter().for_each(|feature| { - match feature { - MmcFeature::ProfileList { ref profiles } => { - println!("{L2} {} {}: ", to_char(true), feature); - profiles.iter().for_each(|MmcProfile { active, kind }| { - println!("{L3} {} {}", to_char(*active), kind); - }) - } - MmcFeature::Core { interface } => { - println!("{L2} {} {}:", to_char(true), feature); - println!("{L3} {} Interface: {}", to_char1(true), interface); - } - MmcFeature::Morphing { - async_events, - op_chg_events, - } => { - println!("{L2} {} {}:", to_char(true), feature); - println!("{L3} {} Asynchronous events", to_char1(async_events)); - println!("{L3} {} Operational change events", to_char1(op_chg_events)); - } - MmcFeature::RemovableMedium { - eject, - lock, - prevent_jumper, - load_mech, - } => { - println!("{L2} {} {}:", to_char(true), feature); - println!("{L3} {} Eject", to_char1(eject)); - println!("{L3} {} Lock", to_char1(lock)); - println!("{L3} {} Prevent Jumper", to_char1(prevent_jumper)); - println!("{L3} {} Loading Mechanism: {}", to_char1(true), load_mech); - } - MmcFeature::CdRead { - active, - c2_error, - cd_text, - dap, - } => { - println!("{L2} {} {}:", to_char(active), feature); - println!("{L3} {} C2 Errors", to_char1(c2_error)); - println!("{L3} {} CD-Text", to_char1(cd_text)); - println!("{L3} {} DAP", to_char1(dap)); - } - MmcFeature::CdAudioExternalPlay { - active, - scan, - sep_channel_mute, - sep_volume, - volume_levels, - } => { - println!("{L2} {} {}:", to_char(active), feature); - println!("{L3} {} SCAN", to_char1(scan)); - println!("{L3} {} Separate Channel Mute", to_char1(sep_channel_mute)); - println!("{L3} {} Separate Volume", to_char1(sep_volume)); - println!("{L3} {} Volume Levels: {}", to_char1(true), volume_levels); - } - MmcFeature::DvdCss { active, .. } => { - println!("{L2} {} {}:", to_char(active), feature); - } - MmcFeature::DriveSerialNumber { ref sno } => { - println!("{L2} {} {}:", to_char(true), feature); - println!("{L3} {} S/N: {}", to_char1(true), sno); - } - _ => { - println!("{L2} (?) {}:", feature); - } - } - - fn to_char(active: bool) -> &'static str { - if active { "[*]" } else { "[ ]" } - } - }); -} - -fn print_drive_capabilities(drive: &Drive) { - println!("Drive capabilities:"); - let capabilities = match drive.capabilities() { - Ok(cap) => cap, - Err(err) => { - println!("{err:?}"); - return; - } - }; - println!("{L1} Hardware:"); - capabilities - .misc - .into_iter() - .for_each(|cap| println!("{L2} {} {}", to_char1(true), cap)); - - println!("{L1} Read:"); - capabilities - .read - .into_iter() - .for_each(|cap| println!("{L2} {} {}", to_char1(true), cap)); - - println!("{L1} Write:"); - capabilities - .write - .into_iter() - .for_each(|cap| println!("{L2} {} {}", to_char1(true), cap)); -} - -fn to_char1(supported: bool) -> &'static str { - if supported { "+" } else { "-" } -} - -const L1: &str = " "; -const L2: &str = " "; -const L3: &str = " "; diff --git a/libcdio-cli/src/iso-info/cli.rs b/libcdio-cli/src/iso-info/cli.rs deleted file mode 100644 index bd9d404..0000000 --- a/libcdio-cli/src/iso-info/cli.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2026 Shiva Kiran Koninty -// -// This file is part of libcdio-cli. -// -// libcdio-cli is free software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// libcdio-cli is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with libcdio-cli. If not, see . - -use std::path::PathBuf; - -use clap::{Args, Parser}; - -/// Inspect metadata and list contents of ISO 9660 and UDF files. -#[derive(Parser)] -#[command(arg_required_else_help = true, long_about = libcdio_cli::HEADER, version)] -pub struct Cli { - /// The file argument as an option or a positional argument - #[command(flatten)] - pub file: FileArg, - - /// Show contents of ISO9660 image in long listing format - #[arg(short = 'l', long, group = "listing")] - pub iso9660: bool, - - /// Do not use Rock Ridge extensions - #[arg(long)] - pub no_rock_ridge: bool, - - /// Do not use CD-ROM XA extensions - #[arg(long)] - pub no_xa: bool, - - /// Check if the image uses Rock Ridge extensions by considering a maximum - /// of FILE_COUNT files. Provide '0' to check all files. - #[arg(short = 'r', long, value_name = "FILE_COUNT")] - pub show_rock_ridge: Option, - - /// Produce only error outputs. - #[arg(short, long)] - pub quiet: bool, - - /// Show contents of UDF image in long listing format - #[arg(short = 'U', long, group = "listing")] - pub udf: bool, -} - -#[derive(Args)] -#[group(required = true, multiple = false)] -pub struct FileArg { - /// Path to an ISO9660 and/or UDF image - #[arg(short = 'i', long = "input", value_name = "FILE")] - pub option: Option, - - /// Path to an ISO9660 and/or UDF image - #[arg(value_name = "FILE")] - pub positional: Option, -} diff --git a/libcdio-cli/src/iso-info/main.rs b/libcdio-cli/src/iso-info/main.rs deleted file mode 100644 index 7d251da..0000000 --- a/libcdio-cli/src/iso-info/main.rs +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (C) 2026 Shiva Kiran Koninty -// -// This file is part of libcdio-cli. -// -// libcdio-cli is free software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// libcdio-cli is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with libcdio-cli. If not, see . - -mod cli; - -use std::{ - collections::VecDeque, - io, - path::{Path, PathBuf}, -}; - -use anyhow::{Context, Result, bail}; -use clap::Parser; -use libcdio_rs::{Iso, Udf, iso9660::XaFileAttributes}; -use time::{UtcOffset, format_description::BorrowedFormatItem, macros::format_description}; -use tracing_subscriber::EnvFilter; - -use crate::cli::Cli; - -const DATE_FMT: &[BorrowedFormatItem] = - format_description!("[month repr:short] [day] [year] [hour]:[minute]:[second]"); -static LINE: &str = "__________________________________"; - -fn main() -> Result<()> { - let cli = Cli::parse(); - tracing_subscriber::fmt() - .with_env_filter(EnvFilter::from_default_env()) - .init(); - let mut output: &mut dyn io::Write = if cli.quiet { - &mut io::sink() - } else { - &mut io::stdout() - }; - let file = cli.file.positional.or(cli.file.option).expect( - "the cli logic must ensure that the file argument is provided either as a positional or as an option", - ); - - if cli.udf { - return print_udf_contents(file, &mut output); - } - - let iso = Iso::new(file.clone())?; - print_iso9660_metadata(&iso, &file, &mut output) - .context("io error while printing iso9660 metadata")?; - - if cli.show_rock_ridge.is_some() { - let file_limit = cli.show_rock_ridge.filter(|file_limit| *file_limit != 0); - print_rock_ridge(&iso, file_limit, &mut output) - .context("io error while printing rock ridge status")?; - } - - print_joliet_level(&iso, &mut output).context("io error while printing joliet level")?; - - if cli.iso9660 { - print_iso9660_contents(&iso, &mut output, !cli.no_rock_ridge, !cli.no_xa) - .context("error printing iso9660 contents")?; - } - - Ok(()) -} - -fn print_iso9660_metadata( - iso: &Iso, - path: &Path, - mut out: impl io::Write, -) -> Result<(), io::Error> { - writeln!(out, "{LINE}")?; - writeln!(out, "ISO 9660 image: {}", path.display())?; - let mut write_if_some = |key, val| { - let Some(val) = val else { return Ok(()) }; - writeln!(out, "{key} : {val}") - }; - write_if_some("Application", iso.application())?; - write_if_some("Preparer ", iso.data_preparer())?; - write_if_some("Publisher ", iso.publisher())?; - write_if_some("System ", iso.system())?; - write_if_some("Volume ", iso.volume())?; - write_if_some("Volume Set ", iso.volume_set())?; - - Ok(()) -} - -fn print_rock_ridge( - iso: &Iso, - file_limit: Option, - mut out: impl io::Write, -) -> Result<(), io::Error> { - let status = match iso.have_rock_ridge(file_limit) { - Ok(true) => "yes", - Ok(false) => "no", - _ => "possibly not", - }; - writeln!(out, "Rock Ridge : {}", status) -} - -/// Outputs the file contents of the ISO 9660 image in an ls-like listing format. -fn print_iso9660_contents( - iso: &Iso, - mut out: impl io::Write, - use_rock_ridge: bool, - use_xa: bool, -) -> Result<()> { - const ISO9660_DEPTH_LIMIT: usize = 512; - let mut dirs = VecDeque::new(); - dirs.push_back(("/".to_owned(), 0)); // (path, depth) - - writeln!(out, "{}", LINE)?; - writeln!(out, "ISO-9660 Information")?; - - while let Some((dir_path, depth)) = dirs.pop_front() { - if depth == ISO9660_DEPTH_LIMIT { - bail!("directory recursion too deep. ISO most probably damaged"); - } - - writeln!(out, "{}:", dir_path)?; - - for entry in iso.read_dir(dir_path.clone())? { - let rock_ridge = use_rock_ridge.then_some(entry.rock_ridge()).flatten(); - let entry_name = if rock_ridge.is_none() { - entry.filename()? - } else { - entry.filename_raw().map(String::from)? - }; - - let full_path = dir_path.clone() + &entry_name + "/"; - if entry.is_dir() && entry_name != "." && entry_name != ".." { - dirs.push_back((full_path.clone(), depth + 1)); - } - - write!(out, " ")?; - if let Some(rock) = &rock_ridge { - let total_size = if let Some(symlink) = &rock.symlink_to { - symlink.len() as u64 - } else { - entry.total_size() - }; - write!(out, " {}", rock.mode)?; - write!(out, " {:3}", rock.hard_links)?; - write!(out, " {}", rock.user_id)?; - write!(out, " {}", rock.group_id)?; - write!(out, " [LSN {:6}]", entry.lsn())?; - write!(out, " {:9}", total_size)?; - } else if use_xa && let Some(xa) = entry.xa() { - write!(out, " {}", xa_file_mode_str(xa.file_attr))?; - write!(out, " {}", xa.user_id)?; - write!(out, " {}", xa.group_id)?; - write!(out, " [fn {:02}]", xa.file_num)?; - write!(out, " [LSN {:6}]", entry.lsn())?; - if let Some(m2f2_size) = xa.mode2form2_size() { - write!(out, " {:9}", m2f2_size)?; - write!(out, " ({:9})", entry.total_size())?; - } else { - write!(out, " {:9}", entry.total_size())?; - } - } else { - write!(out, " {}", if entry.is_dir() { 'd' } else { '-' })?; - write!(out, " [LSN {:6}]", entry.lsn())?; - write!(out, " {:9}", entry.total_size())?; - } - - let time = if let Some(rock) = &rock_ridge - && let Some(mtime) = rock.modify_time - { - mtime - } else { - entry.timestamp()? - }; - - let local = UtcOffset::current_local_offset() - .context("could not get current time offset from system")?; - let time = time - .to_offset(local) - .format(DATE_FMT) - .with_context(|| format!("could not format timestamp: {}", full_path))?; - - write!(out, " {}", time)?; - write!(out, " {}", entry_name)?; - - if let Some(rock) = rock_ridge - && let Some(symlink_to) = rock.symlink_to - { - write!(out, " -> {}", symlink_to)?; - } - - writeln!(out)?; - } - - writeln!(out)?; - } - - Ok(()) -} - -/// Returns an ls-like string representation of the XA file mode attributes. -/// Example: "d---1xrxr-r" -fn xa_file_mode_str(attr: XaFileAttributes) -> String { - let mut mode_str = String::new(); - let mut has_attr = |attribute, letter| { - if attr.contains(attribute) { - mode_str.push(letter) - } else { - mode_str.push('-') - } - }; - has_attr(XaFileAttributes::Directory, 'd'); - has_attr(XaFileAttributes::Cdda, 'a'); - has_attr(XaFileAttributes::Interleaved, 'i'); - has_attr(XaFileAttributes::Mode2Form2, '2'); - has_attr(XaFileAttributes::Mode2, '1'); - has_attr(XaFileAttributes::OwnerExecute, 'x'); - has_attr(XaFileAttributes::OwnerRead, 'r'); - has_attr(XaFileAttributes::GroupExecute, 'x'); - has_attr(XaFileAttributes::GroupRead, 'r'); - has_attr(XaFileAttributes::WorldExecute, 'x'); - has_attr(XaFileAttributes::WorldRead, 'r'); - - mode_str -} - -/// Outputs the file contents of the UDF image in an ls-like listing format. -fn print_udf_contents(path: PathBuf, out: &mut dyn io::Write) -> Result<()> { - let udf = Udf::new(path.clone())?; - - let root = udf.root()?; - let mut dirs = VecDeque::new(); - dirs.push_back((root, "/".to_owned())); - - while let Some((dir, dir_path)) = dirs.pop_front() { - writeln!(out, "{}:", dir_path)?; - let mut next_entry = dir.next(); - - while let Some(entry) = next_entry { - let filename = entry.filename()?; - let file_path = dir_path.clone() + filename + "/"; - - let local = UtcOffset::current_local_offset() - .context("could not get current time offset from system")?; - let modify_time = entry - .modify_time()? - .to_offset(local) - .format(DATE_FMT) - .with_context(|| format!("could not format timestamp: {}", file_path))?; - write!(out, " ")?; - write!(out, " {}", entry.mode())?; - write!(out, " {}", entry.uid)?; - write!(out, " {}", entry.gid)?; - write!(out, " {:3}", entry.link_count())?; - write!(out, " {:9}", entry.file_length())?; - write!(out, " {}", modify_time)?; - write!(out, " {}", filename)?; - writeln!(out)?; - - if let Some(subdir) = entry.open_dir() { - dirs.push_back((subdir, file_path)); - } - next_entry = entry.next(); - } - - writeln!(out)?; - } - - Ok(()) -} - -fn print_joliet_level(iso: &Iso, mut out: impl io::Write) -> Result<(), io::Error> { - let Some(joliet_level) = iso.joliet_level() else { - return writeln!(out, "No Joliet extensions"); - }; - - writeln!(out, "Joliet Level: {}", u8::from(joliet_level)) -} diff --git a/libcdio-cli/src/iso-read/cli.rs b/libcdio-cli/src/iso-read/cli.rs deleted file mode 100644 index f157d02..0000000 --- a/libcdio-cli/src/iso-read/cli.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (C) 2026 Shiva Kiran Koninty -// -// This file is part of libcdio-cli. -// -// libcdio-cli is free software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// libcdio-cli is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with libcdio-cli. If not, see . - -use std::path::PathBuf; - -use clap::{Args, Parser}; - -/// Extract files from ISO 9660 and UDF files. -#[derive(Parser)] -#[command(arg_required_else_help = true, version)] -pub struct Cli { - /// Path to the file in the image to extract - #[arg(short, long, value_name = "FILE")] - pub extract: String, - - /// Path to an ISO9660 and/or UDF image - #[command(flatten)] - pub image: FileArg, - - /// Path of the output file. Defaults to name of the extracted file. - #[arg(short, long, value_name = "FILE")] - pub output_file: Option, - - /// Use UDF - #[arg(short = 'U', long)] - pub udf: bool, -} - -#[derive(Args)] -#[group(required = true, multiple = false)] -pub struct FileArg { - /// Path to an ISO9660 and/or UDF image - #[arg(short = 'i', long = "image", value_name = "FILE")] - pub option: Option, - - /// Path to an ISO9660 and/or UDF image - #[arg(value_name = "FILE")] - pub positional: Option, -} diff --git a/libcdio-cli/src/iso-read/main.rs b/libcdio-cli/src/iso-read/main.rs deleted file mode 100644 index 1c21c12..0000000 --- a/libcdio-cli/src/iso-read/main.rs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2026 Shiva Kiran Koninty -// -// This file is part of libcdio-cli. -// -// libcdio-cli is free software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// libcdio-cli is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with libcdio-cli. If not, see . - -use std::{fs::File, io, path::PathBuf}; - -use anyhow::{Context, Result, bail}; -use clap::Parser; -use libcdio_rs::{Iso, Udf}; -use tracing_subscriber::EnvFilter; - -use crate::cli::Cli; - -mod cli; - -fn main() -> Result<()> { - let cli = Cli::parse(); - tracing_subscriber::fmt() - .with_env_filter(EnvFilter::from_default_env()) - .init(); - let image = cli.image.positional.or(cli.image.option) - .expect( "the cli logic must ensure that the file argument is provided either as a positional or as an option"); - if !image.exists() { - bail!("could not open input file at {}", image.display()); - } - - let output = cli.output_file.unwrap_or(PathBuf::from(&cli.extract)); - let mut output = File::create(output).context("could not create output file")?; - - if cli.udf { - udf_extract(image, cli.extract, &mut output)?; - } else { - iso9660_extract(image, cli.extract, &mut output)?; - } - - Ok(()) -} - -/// Extract given file from a UDF image. -fn udf_extract(image: PathBuf, extract: String, output: &mut File) -> Result<()> { - let udf = Udf::new(image)?; - let entry = udf.entry(extract)?; - - io::copy(&mut entry.reader(), output)?; - - Ok(()) -} - -/// Extract given file from an ISO 9660 image. -fn iso9660_extract(image: PathBuf, extract: String, output: &mut File) -> Result<()> { - let iso = Iso::new(image.clone())?; - let entry = iso.entry(extract)?; - - io::copy(&mut entry.reader(), output)?; - - Ok(()) -} diff --git a/libcdio-cli/src/lib.rs b/libcdio-cli/src/lib.rs deleted file mode 100644 index 0b5955c..0000000 --- a/libcdio-cli/src/lib.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2026 Shiva Kiran Koninty -// -// This file is part of libcdio-cli. -// -// libcdio-cli is free software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// libcdio-cli is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with libcdio-cli. If not, see . - -//! Shared code for libcdio-cli -#![doc(hidden)] - -pub static HEADER: &str = concat!( - env!("CARGO_PKG_NAME"), - " version ", - env!("CARGO_PKG_VERSION"), - "\nCopyright (C) 2026 ", - env!("CARGO_PKG_AUTHORS"), - r" -This is free software; see the source for copying conditions. -There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.", -); diff --git a/libcdio-cli/src/mmc-tool/cli.rs b/libcdio-cli/src/mmc-tool/cli.rs deleted file mode 100644 index 8f7fc85..0000000 --- a/libcdio-cli/src/mmc-tool/cli.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2026 Shiva Kiran Koninty -// -// This file is part of libcdio-cli. -// -// libcdio-cli is free software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// libcdio-cli is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with libcdio-cli. If not, see . - -use std::path::PathBuf; - -use clap::{Args, Parser}; - -#[derive(Debug, Parser)] -#[command(arg_required_else_help = true, long_about = libcdio_cli::HEADER, version)] -pub struct Cli { - /// Path to an MMC device. - pub device: Option, - - #[command(flatten)] - pub actions: MmcActions, -} - -#[derive(Args, Debug)] -#[group(required = true, multiple = false)] -pub struct MmcActions { - /// Eject the drive - #[arg(short, long)] - pub eject: bool, - - /// Close the tray, if present - #[arg(short, long)] - pub close_tray: bool, - - /// Put the device into standby - #[arg(short, long)] - pub standby: bool, - - /// Get the MCN (Media Catalog Number) of the media - #[arg(short, long)] - pub mcn: bool, - - /// Get hardware identifiers (Product, Vendor and Revision) - #[arg(short, long)] - pub inquiry: bool, - - /// Set the drive read and write speed in KB/s. - /// - /// Falls back to the nearest supported value if the provided value is not - /// supported. - #[arg(short = 'S', long)] - pub speed: Option, -} diff --git a/libcdio-cli/src/mmc-tool/main.rs b/libcdio-cli/src/mmc-tool/main.rs deleted file mode 100644 index 2b1784e..0000000 --- a/libcdio-cli/src/mmc-tool/main.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2026 Shiva Kiran Koninty -// -// This file is part of libcdio-cli. -// -// libcdio-cli is free software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// libcdio-cli is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with libcdio-cli. If not, see . - -use anyhow::{Context, Result}; -use clap::Parser; -use libcdio_rs::{ - Mmc, - mmc::{PowerCondition, RotationMode}, -}; -use tracing_subscriber::EnvFilter; - -use crate::cli::Cli; - -mod cli; - -fn main() -> Result<()> { - let cli = Cli::parse(); - tracing_subscriber::fmt() - .with_env_filter(EnvFilter::from_default_env()) - .init(); - let mmc = if let Some(device) = cli.device { - Mmc::with_device(device)? - } else { - Mmc::new()? - }; - - if cli.actions.eject { - mmc.allow_media_removal()?; - mmc.eject()?; - } else if cli.actions.close_tray { - mmc.close_tray()?; - } else if cli.actions.standby { - mmc.set_power_state(PowerCondition::Standby)?; - } else if cli.actions.mcn { - let mcn = mmc - .media_catalog_number() - .context("could not get MCN")? - .context("current media does not have a Media Catalog Number")?; - println!("{}", mcn); - } else if cli.actions.inquiry { - let ident = mmc.hardware_identifiers()?; - println!("Product: {}", ident.product); - println!("Vendor: {}", ident.vendor); - println!("Revision: {}", ident.revision); - } else if let Some(speed) = cli.actions.speed { - // some drives may not support CLV (Constant Linear Velocity) - if mmc.set_cd_speed(RotationMode::Clv, speed, speed).is_err() { - mmc.set_cd_speed(RotationMode::Cav, speed, speed)?; - } - } - - Ok(()) -} diff --git a/libcdio-cli/tests/iso-info.rs b/libcdio-cli/tests/iso-info.rs deleted file mode 100644 index 8355652..0000000 --- a/libcdio-cli/tests/iso-info.rs +++ /dev/null @@ -1,158 +0,0 @@ -use assert_cmd::{Command, cargo::cargo_bin_cmd}; - -fn cmd() -> Command { - cargo_bin_cmd!("iso-info-rs") -} - -static ROCK_RIDGE_FILE: &str = "../test-data/rock-ridge.iso"; -static ROCK_METADATA: &str = r"__________________________________ -ISO 9660 image: ../test-data/rock-ridge.iso -Application : K3B THE CD KREATOR VERSION 0.11.20 (C) 2003 SEBASTIAN TRUEG AND THE K3B TEAM -Preparer : K3b - Version 0.11.20 -Publisher : Rocky Bernstein -System : LINUX -Volume : Rock Ridge Copy test -No Joliet extensions -"; -#[test] -fn rock_metadata() { - cmd() - .arg(ROCK_RIDGE_FILE) - .assert() - .success() - .stdout(ROCK_METADATA); -} - -static JOLIET_FILE: &str = "../test-data/joliet.iso"; -static JOLIET_METADATA: &str = r"__________________________________ -ISO 9660 image: ../test-data/joliet.iso -Application : K3B THE CD KREATOR VERSION 0.11.12 (C) 2003 SEBASTIAN TRUEG AND THE K3B TEAM -Preparer : K3b - Version 0.11.12 -Publisher : Rocky Bernstein -System : LINUX -Volume : K3b data project -Joliet Level: 3 -"; -#[test] -fn joliet_metadata() { - cmd() - .arg(JOLIET_FILE) - .assert() - .success() - .stdout(JOLIET_METADATA); -} - -static XA_FILE: &str = "../test-data/xa.iso"; -static XA_METADATA: &str = r"__________________________________ -ISO 9660 image: ../test-data/xa.iso -Application : GENISOIMAGE ISO 9660/HFS FILESYSTEM CREATOR (C) 1993 E.YOUNGDALE (C) 1997-2006 J.PEARSON/J.SCHILLING (C) 2006-2007 CDRKIT TEAM -System : LINUX -Volume : CDROM -No Joliet extensions -"; -#[test] -fn xa_metadata() { - cmd().arg(XA_FILE).assert().success().stdout(XA_METADATA); -} - -static ROCK_CONTENTS: &str = r"__________________________________ -ISO-9660 Information -/: - dr-xr-xr-x 4 0 0 [LSN 23] 2048 Oct 22 2004 02:21:14 . - dr-xr-xr-x 2 0 0 [LSN 23] 2048 Oct 22 2004 02:21:14 .. - dr-xr-xr-x 2 0 0 [LSN 24] 2048 Mar 05 2005 16:12:25 copy - lr-xr-xr-x 1 0 0 [LSN 27] 7 Mar 05 2005 15:26:00 Copy2 -> COPYING - -r--r--r-- 1 0 0 [LSN 27] 17992 Mar 05 2005 15:25:51 COPYING - br--r--r-- 1 0 0 [LSN 36] 0 Mar 05 2005 15:32:05 fd0 - dr-xr-xr-x 2 0 0 [LSN 25] 2048 Mar 05 2005 16:12:25 tmp - cr--r--r-- 1 0 0 [LSN 36] 0 Mar 05 2005 15:31:42 zero - -/copy/: - dr-xr-xr-x 2 0 0 [LSN 24] 2048 Mar 05 2005 16:12:25 . - dr-xr-xr-x 4 0 0 [LSN 23] 2048 Mar 05 2005 16:12:25 .. - lr-xr-xr-x 1 0 0 [LSN 36] 10 Mar 05 2005 15:27:05 COPYING -> ../COPYING - -/tmp/: - dr-xr-xr-x 2 0 0 [LSN 25] 2048 Mar 05 2005 16:12:25 . - dr-xr-xr-x 4 0 0 [LSN 23] 2048 Mar 05 2005 16:12:25 .. - lr-xr-xr-x 1 0 0 [LSN 36] 18 Mar 05 2005 15:51:05 COPYING -> ../copying/COPYING - -"; -#[test] -fn rock_contents() { - cmd() - .env("TZ", "UTC") - .arg("-l") - .arg(ROCK_RIDGE_FILE) - .assert() - .success() - .stdout(ROCK_METADATA.to_owned() + ROCK_CONTENTS); -} - -static JOLIET_CONTENTS: &str = r"__________________________________ -ISO-9660 Information -/: - d [LSN 31] 2048 Oct 22 2004 22:44:59 . - d [LSN 31] 2048 Oct 22 2004 22:44:59 .. - d [LSN 32] 2048 Oct 22 2004 22:44:59 libcdio - -/libcdio/: - d [LSN 32] 2048 Oct 22 2004 22:44:59 . - d [LSN 31] 2048 Oct 22 2004 22:44:59 .. - - [LSN 34] 17992 Mar 12 2004 07:18:03 COPYING - - [LSN 43] 2156 Jun 26 2004 10:01:09 README - - [LSN 45] 2849 Aug 12 2004 09:22:23 README.libcdio - d [LSN 33] 2048 Oct 22 2004 22:44:59 test - -/libcdio/test/: - d [LSN 33] 2048 Oct 22 2004 22:44:59 . - d [LSN 32] 2048 Oct 22 2004 22:44:59 .. - - [LSN 47] 74 Jul 25 2004 09:52:32 isofs-m1.cue - -"; -#[test] -fn joliet_contents() { - cmd() - .env("TZ", "UTC") - .arg("-l") - .arg(JOLIET_FILE) - .assert() - .success() - .stdout(JOLIET_METADATA.to_owned() + JOLIET_CONTENTS); -} - -static XA_CONTENTS: &str = r"__________________________________ -ISO-9660 Information -/: - d---1xrxrxr 1000 3000 [fn 00] [LSN 23] 2048 Jun 08 2026 04:44:35 . - d---1xrxrxr 1000 3000 [fn 00] [LSN 23] 2048 Jun 08 2026 04:44:35 .. - ----1--xr-- 1000 3000 [fn 00] [LSN 25] 35149 Jun 08 2026 04:43:19 copying - -"; -#[test] -fn xa_contents() { - cmd() - .env("TZ", "UTC") - .arg("-l") - .arg(XA_FILE) - .assert() - .success() - .stdout(XA_METADATA.to_owned() + XA_CONTENTS); -} - -static UDF_FILE: &str = "../test-data/udf.iso"; -static UDF_OUTPUT: &str = "/: - dr-xr-xr-x 4294967295 4294967295 1 100 Feb 20 2014 01:26:20 . - -r-xr-xr-x 4294967295 4294967295 1 10 Feb 20 2014 01:25:12 FéжΘvrier - -"; -#[test] -fn udf() { - cmd() - .env("TZ", "UTC") - .arg("-U") - .arg(UDF_FILE) - .assert() - .success() - .stdout(UDF_OUTPUT); -} diff --git a/libcdio-cli/tests/iso-read.rs b/libcdio-cli/tests/iso-read.rs deleted file mode 100644 index ae84252..0000000 --- a/libcdio-cli/tests/iso-read.rs +++ /dev/null @@ -1,45 +0,0 @@ -use std::fs; - -use assert_cmd::{Command, cargo::cargo_bin_cmd}; -use assert_fs::{NamedTempFile, assert::PathAssert}; - -fn cmd() -> Command { - cargo_bin_cmd!("iso-read-rs") -} - -static UDF_FILE: &str = "../test-data/udf1.iso"; -#[test] -fn extract_udf() { - let output = NamedTempFile::new("out").unwrap(); - cmd() - .arg("-e") - .arg("licenses/COPYING") - .arg("-i") - .arg(UDF_FILE) - .arg("-o") - .arg(output.path()) - .arg("-U") - .assert() - .success(); - - let gpl = fs::read_to_string("../COPYING").unwrap(); - output.assert(gpl); -} - -static ISO9660_FILE: &str = "../test-data/xa.iso"; -#[test] -fn extract_iso9660() { - let output = NamedTempFile::new("out").unwrap(); - cmd() - .arg("-e") - .arg("copying") - .arg("-i") - .arg(ISO9660_FILE) - .arg("-o") - .arg(output.path()) - .assert() - .success(); - - let gpl = fs::read_to_string("../COPYING").unwrap(); - output.assert(gpl); -} diff --git a/libcdio-rs/COPYING b/libcdio-rs/COPYING deleted file mode 120000 index 012065c..0000000 --- a/libcdio-rs/COPYING +++ /dev/null @@ -1 +0,0 @@ -../COPYING \ No newline at end of file diff --git a/libcdio-rs/Cargo.toml b/libcdio-rs/Cargo.toml deleted file mode 100644 index abfad0d..0000000 --- a/libcdio-rs/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "libcdio-rs" -version = "0.1.0" -edition.workspace = true -authors.workspace = true -categories = ["api-bindings", "multimedia::audio", "filesystem", "hardware-support"] -description = "Safe abstraction library over libcdio" -keywords = ["cd", "scsi", "iso9660", "udf"] -license.workspace = true -readme = "README.md" -repository.workspace = true - -[features] -iso9660 = ["libcdio-sys/iso9660", "dep:file-mode", "dep:time"] -mmc = ["dep:winnow"] -udf = ["libcdio-sys/udf", "dep:file-mode", "dep:time"] - -[dependencies] -bitflags = "2.11.1" -displaydoc = "0.2.6" -docsplay = "0.1.3" -file-mode = { version = "0.1.2", optional = true } -libcdio-sys.workspace = true -num_enum = { version = "0.7.6", features = ["complex-expressions"] } -thiserror = "2.0.18" -time = { workspace = true, features = ["local-offset"], optional = true } -tracing.workspace = true -winnow = { version = "1.0.3", features = ["binary", "parser", "std"], default-features = false, optional = true } - -[dev-dependencies] -test-log.workspace = true -time = { workspace = true, features = ["macros"] } - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/libcdio-rs/README.md b/libcdio-rs/README.md deleted file mode 100644 index 51f5391..0000000 --- a/libcdio-rs/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# libcdio-rs -Safe Rust abstraction over libcdio C. -To use the raw FFI bindings, check out [libcdio-sys](https://crates.io/crates/libcdio-sys). - -## SCSI MMC spec references -This library is primarily based on SCSI's [MMC-6][1] and [SPC-3][2]. - -However, in an attempt to achieve feature parity with libcdio C, a few -commands and options of existing commands that are marked legacy in -MMC-6 have also been implemented. -See Annexure E on legacy specifications in MMC-6 to find the last -supported MMC version for said command or option. - -[1]: https://www.13thmonkey.org/documentation/SCSI/mmc6r02g.pdf -[2]: https://www.13thmonkey.org/documentation/SCSI/spc3r23.pdf - -## License -Copyright (C) 2026 Shiva Kiran Koninty - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . diff --git a/libcdio-rs/src/cdio.rs b/src/cdio.rs similarity index 100% rename from libcdio-rs/src/cdio.rs rename to src/cdio.rs diff --git a/libcdio-rs/src/drive.rs b/src/drive.rs similarity index 100% rename from libcdio-rs/src/drive.rs rename to src/drive.rs diff --git a/libcdio-rs/src/iso9660.rs b/src/iso9660.rs similarity index 98% rename from libcdio-rs/src/iso9660.rs rename to src/iso9660.rs index 8e4f7db..ecea1cf 100644 --- a/libcdio-rs/src/iso9660.rs +++ b/src/iso9660.rs @@ -189,10 +189,10 @@ pub(crate) mod tests { use super::*; pub fn test_rockridge_file() -> PathBuf { - PathBuf::from("../test-data/rock-ridge.iso") + PathBuf::from("tests/data/rock-ridge.iso") } pub fn test_joliet_file() -> PathBuf { - PathBuf::from("../test-data/joliet.iso") + PathBuf::from("tests/data/joliet.iso") } #[test_log::test(test)] diff --git a/libcdio-rs/src/iso9660/entry.rs b/src/iso9660/entry.rs similarity index 98% rename from libcdio-rs/src/iso9660/entry.rs rename to src/iso9660/entry.rs index b2f8782..7983d8c 100644 --- a/libcdio-rs/src/iso9660/entry.rs +++ b/src/iso9660/entry.rs @@ -366,9 +366,9 @@ mod tests { #[test] fn read() { - let iso = Iso::new(PathBuf::from("../test-data/xa.iso")).unwrap(); + let iso = Iso::new(PathBuf::from("tests/data/xa.iso")).unwrap(); let entry = iso.entry("copying".to_string()).unwrap(); - let gpl = std::fs::read_to_string("../COPYING").unwrap(); + let gpl = std::fs::read_to_string("COPYING").unwrap(); let mut reader = entry.reader(); let mut result = String::new(); diff --git a/libcdio-rs/src/iso9660/rock.rs b/src/iso9660/rock.rs similarity index 100% rename from libcdio-rs/src/iso9660/rock.rs rename to src/iso9660/rock.rs diff --git a/libcdio-rs/src/iso9660/util.rs b/src/iso9660/util.rs similarity index 100% rename from libcdio-rs/src/iso9660/util.rs rename to src/iso9660/util.rs diff --git a/libcdio-rs/src/iso9660/xa.rs b/src/iso9660/xa.rs similarity index 97% rename from libcdio-rs/src/iso9660/xa.rs rename to src/iso9660/xa.rs index 0d62383..9281560 100644 --- a/libcdio-rs/src/iso9660/xa.rs +++ b/src/iso9660/xa.rs @@ -102,7 +102,7 @@ mod tests { #[test] fn xa() { - let iso = Iso::new(PathBuf::from("../test-data/xa.iso")).unwrap(); + let iso = Iso::new(PathBuf::from("tests/data/xa.iso")).unwrap(); let entry = iso.entry("/copying".to_string()).unwrap(); let xa = entry.xa().unwrap(); assert_eq!(xa.file_num, 0); diff --git a/libcdio-rs/src/lib.rs b/src/lib.rs similarity index 100% rename from libcdio-rs/src/lib.rs rename to src/lib.rs diff --git a/libcdio-rs/src/logging.rs b/src/logging.rs similarity index 100% rename from libcdio-rs/src/logging.rs rename to src/logging.rs diff --git a/libcdio-rs/src/mmc.rs b/src/mmc.rs similarity index 100% rename from libcdio-rs/src/mmc.rs rename to src/mmc.rs diff --git a/libcdio-rs/src/mmc/get_config.rs b/src/mmc/get_config.rs similarity index 100% rename from libcdio-rs/src/mmc/get_config.rs rename to src/mmc/get_config.rs diff --git a/libcdio-rs/src/mmc/get_event_status.rs b/src/mmc/get_event_status.rs similarity index 100% rename from libcdio-rs/src/mmc/get_event_status.rs rename to src/mmc/get_event_status.rs diff --git a/libcdio-rs/src/mmc/inquiry.rs b/src/mmc/inquiry.rs similarity index 100% rename from libcdio-rs/src/mmc/inquiry.rs rename to src/mmc/inquiry.rs diff --git a/libcdio-rs/src/mmc/prevent_allow_medium_removal.rs b/src/mmc/prevent_allow_medium_removal.rs similarity index 100% rename from libcdio-rs/src/mmc/prevent_allow_medium_removal.rs rename to src/mmc/prevent_allow_medium_removal.rs diff --git a/libcdio-rs/src/mmc/read_cd.rs b/src/mmc/read_cd.rs similarity index 100% rename from libcdio-rs/src/mmc/read_cd.rs rename to src/mmc/read_cd.rs diff --git a/libcdio-rs/src/mmc/read_disc_info.rs b/src/mmc/read_disc_info.rs similarity index 100% rename from libcdio-rs/src/mmc/read_disc_info.rs rename to src/mmc/read_disc_info.rs diff --git a/libcdio-rs/src/mmc/read_subchannel.rs b/src/mmc/read_subchannel.rs similarity index 100% rename from libcdio-rs/src/mmc/read_subchannel.rs rename to src/mmc/read_subchannel.rs diff --git a/libcdio-rs/src/mmc/read_toc.rs b/src/mmc/read_toc.rs similarity index 100% rename from libcdio-rs/src/mmc/read_toc.rs rename to src/mmc/read_toc.rs diff --git a/libcdio-rs/src/mmc/set_cd_speed.rs b/src/mmc/set_cd_speed.rs similarity index 100% rename from libcdio-rs/src/mmc/set_cd_speed.rs rename to src/mmc/set_cd_speed.rs diff --git a/libcdio-rs/src/mmc/start_stop_unit.rs b/src/mmc/start_stop_unit.rs similarity index 100% rename from libcdio-rs/src/mmc/start_stop_unit.rs rename to src/mmc/start_stop_unit.rs diff --git a/libcdio-rs/src/mmc/test_unit_ready.rs b/src/mmc/test_unit_ready.rs similarity index 100% rename from libcdio-rs/src/mmc/test_unit_ready.rs rename to src/mmc/test_unit_ready.rs diff --git a/libcdio-rs/src/udf.rs b/src/udf.rs similarity index 98% rename from libcdio-rs/src/udf.rs rename to src/udf.rs index 60a2a5a..489c33c 100644 --- a/libcdio-rs/src/udf.rs +++ b/src/udf.rs @@ -94,7 +94,7 @@ mod tests { use super::*; pub fn test_udf_file() -> PathBuf { - PathBuf::from("../test-data/udf.iso") + PathBuf::from("tests/data/udf.iso") } #[test] diff --git a/libcdio-rs/src/udf/entry.rs b/src/udf/entry.rs similarity index 99% rename from libcdio-rs/src/udf/entry.rs rename to src/udf/entry.rs index 983fced..346ee9b 100644 --- a/libcdio-rs/src/udf/entry.rs +++ b/src/udf/entry.rs @@ -333,7 +333,7 @@ mod tests { use super::*; fn test_udf_file1() -> PathBuf { - PathBuf::from("../test-data/udf1.iso") + PathBuf::from("tests/data/udf1.iso") } #[test] @@ -439,7 +439,7 @@ mod tests { let mut contents = String::new(); let bytes_read = reader.read_to_string(&mut contents).unwrap(); - let gpl = std::fs::read_to_string("../COPYING").unwrap(); + let gpl = std::fs::read_to_string("COPYING").unwrap(); assert_eq!(gpl.len(), bytes_read); assert_eq!(gpl, contents); } diff --git a/test-data/isofs-m1.bin b/tests/data/isofs-m1.bin similarity index 100% rename from test-data/isofs-m1.bin rename to tests/data/isofs-m1.bin diff --git a/test-data/isofs-m1.cue b/tests/data/isofs-m1.cue similarity index 95% rename from test-data/isofs-m1.cue rename to tests/data/isofs-m1.cue index 7f2c37f..257d2fe 100644 --- a/test-data/isofs-m1.cue +++ b/tests/data/isofs-m1.cue @@ -1,4 +1,4 @@ -CATALOG 0000012101954 -FILE "isofs-m1.bin" BINARY - TRACK 01 MODE1/2352 - INDEX 01 00:00:00 +CATALOG 0000012101954 +FILE "isofs-m1.bin" BINARY + TRACK 01 MODE1/2352 + INDEX 01 00:00:00 diff --git a/test-data/isofs-m1.toc b/tests/data/isofs-m1.toc similarity index 100% rename from test-data/isofs-m1.toc rename to tests/data/isofs-m1.toc diff --git a/test-data/joliet.iso b/tests/data/joliet.iso similarity index 100% rename from test-data/joliet.iso rename to tests/data/joliet.iso diff --git a/test-data/rock-ridge.iso b/tests/data/rock-ridge.iso similarity index 100% rename from test-data/rock-ridge.iso rename to tests/data/rock-ridge.iso diff --git a/test-data/udf.iso b/tests/data/udf.iso similarity index 100% rename from test-data/udf.iso rename to tests/data/udf.iso diff --git a/test-data/udf1.iso b/tests/data/udf1.iso similarity index 100% rename from test-data/udf1.iso rename to tests/data/udf1.iso diff --git a/test-data/xa.iso b/tests/data/xa.iso similarity index 100% rename from test-data/xa.iso rename to tests/data/xa.iso diff --git a/libcdio-rs/tests/media_removal.rs b/tests/media_removal.rs similarity index 100% rename from libcdio-rs/tests/media_removal.rs rename to tests/media_removal.rs