Initial commit
This commit is contained in:
commit
97541d7d3c
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/target
|
||||||
|
links
|
||||||
|
|
||||||
|
|
||||||
|
# Added by cargo
|
||||||
|
#
|
||||||
|
# already existing elements were commented out
|
||||||
|
|
||||||
|
#/target
|
575
Cargo.lock
generated
Normal file
575
Cargo.lock
generated
Normal file
@ -0,0 +1,575 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ansi_term"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.58"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bindgen"
|
||||||
|
version = "0.59.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cexpr",
|
||||||
|
"clang-sys",
|
||||||
|
"clap",
|
||||||
|
"env_logger",
|
||||||
|
"lazy_static",
|
||||||
|
"lazycell",
|
||||||
|
"log",
|
||||||
|
"peeking_take_while",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash",
|
||||||
|
"shlex",
|
||||||
|
"which",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.73"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cexpr"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-expr"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db"
|
||||||
|
dependencies = [
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clang-sys"
|
||||||
|
version = "1.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
"libc",
|
||||||
|
"libloading",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "2.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||||
|
dependencies = [
|
||||||
|
"ansi_term",
|
||||||
|
"atty",
|
||||||
|
"bitflags",
|
||||||
|
"strsim",
|
||||||
|
"textwrap",
|
||||||
|
"unicode-width",
|
||||||
|
"vec_map",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie-factory"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "396de984970346b0d9e93d1415082923c679e5ae5c3ee3dcbd104f5610af126b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"humantime",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||||
|
dependencies = [
|
||||||
|
"errno-dragonfly",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno-dragonfly"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.126"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libloading"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libspa"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8bb02bbc8d550e2f0a31989c61e1ac3c883bab2edee49ffcb5d5ca18266786d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cc",
|
||||||
|
"cookie-factory",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"libspa-sys",
|
||||||
|
"nom",
|
||||||
|
"system-deps",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libspa-sys"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e8d2e38d6cdd10d7d78eb0cb409c127cf16da2c296d9623375551e309616d4d"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"system-deps",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.14.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cc",
|
||||||
|
"cfg-if 0.1.10",
|
||||||
|
"libc",
|
||||||
|
"void",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peeking_take_while"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pipewire"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d80fef8219c37f479f3d62d70167f3daaa90b71a083f7fd88d69e49f05f0ecdc"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bitflags",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"libspa",
|
||||||
|
"libspa-sys",
|
||||||
|
"once_cell",
|
||||||
|
"pipewire-sys",
|
||||||
|
"signal",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pipewire-autoconnect"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"libspa",
|
||||||
|
"pipewire",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pipewire-sys"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f6d4262ea1fd3b01786046d1892cc49e9578d872faf8723d95dc7affc810ee4"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"libspa-sys",
|
||||||
|
"system-deps",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.140"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f6ce83b159ab6984d2419f495134972b48754d13ff2e3f8c998339942b56ed9"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"nix",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.98"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "system-deps"
|
||||||
|
version = "6.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-expr",
|
||||||
|
"heck",
|
||||||
|
"pkg-config",
|
||||||
|
"toml",
|
||||||
|
"version-compare",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vec_map"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version-compare"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "void"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "4.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "pipewire-autoconnect"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pipewire = "0.5.0"
|
||||||
|
libspa = "0.5.0"
|
||||||
|
regex = "1.6.0"
|
||||||
|
lazy_static = "1.4.0"
|
381
src/main.rs
Normal file
381
src/main.rs
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
use std::{cell::RefCell, env, fs, io::BufRead, collections::HashMap};
|
||||||
|
use std::vec::Vec;
|
||||||
|
use std::{cell::RefMut, rc::Rc};
|
||||||
|
|
||||||
|
use libspa::ReadableDict;
|
||||||
|
use pipewire::{types::ObjectType, Context, MainLoop};
|
||||||
|
use pipewire as pw;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Port {
|
||||||
|
id: u32,
|
||||||
|
name: String,
|
||||||
|
node: Rc<Node>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Node {
|
||||||
|
id: u32,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NodeDef {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct PortDef {
|
||||||
|
node: Rc<NodeDef>,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct LinkDef {
|
||||||
|
port_in: Rc<PortDef>,
|
||||||
|
port_out: Rc<PortDef>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AppState {
|
||||||
|
ports: Vec<Rc<Port>>,
|
||||||
|
nodes: Vec<Rc<Node>>,
|
||||||
|
|
||||||
|
get_names: bool,
|
||||||
|
|
||||||
|
node_def: Vec<Rc<NodeDef>>,
|
||||||
|
link_def: Vec<Rc<LinkDef>>,
|
||||||
|
port_def: Vec<Rc<PortDef>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search<T, P>(v: &[Rc<T>], f: P) -> Option<Rc<T>>
|
||||||
|
where
|
||||||
|
T: Sized,
|
||||||
|
P: FnMut(&&Rc<T>) -> bool,
|
||||||
|
{
|
||||||
|
let n = v.iter().filter(f).cloned().collect::<Vec<Rc<T>>>();
|
||||||
|
|
||||||
|
if n.len() != 1 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(n[0].clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppState {
|
||||||
|
fn new(
|
||||||
|
node_def: Vec<Rc<NodeDef>>,
|
||||||
|
link_def: Vec<Rc<LinkDef>>,
|
||||||
|
port_def: Vec<Rc<PortDef>>,
|
||||||
|
get_names: bool,
|
||||||
|
) -> AppState {
|
||||||
|
AppState {
|
||||||
|
node_def,
|
||||||
|
link_def,
|
||||||
|
port_def,
|
||||||
|
get_names,
|
||||||
|
ports: Vec::new(),
|
||||||
|
nodes: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_add_node(&mut self, def: Node) -> bool {
|
||||||
|
if !self.node_def.iter().any(|a| a.name.eq(&def.name)) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut nodes = self
|
||||||
|
.nodes
|
||||||
|
.iter()
|
||||||
|
.filter(|a| !a.name.eq(&def.name))
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<Rc<Node>>>();
|
||||||
|
|
||||||
|
nodes.push(Rc::new(def));
|
||||||
|
|
||||||
|
self.nodes = nodes;
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_node(&self, id: u32) -> Option<Rc<Node>> {
|
||||||
|
search(&self.nodes, |a| a.id == id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_port_by_name(&self, name: String) -> Option<Rc<Port>> {
|
||||||
|
search(&self.ports, |a| a.name.eq(&name))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_add_port(&mut self, id: u32, name: String, node_id: u32) -> bool {
|
||||||
|
let node = self.get_node(node_id);
|
||||||
|
|
||||||
|
if node.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let node = node.unwrap();
|
||||||
|
|
||||||
|
if self
|
||||||
|
.port_def
|
||||||
|
.iter()
|
||||||
|
.filter(|a| a.name.eq(&name) && a.node.name.eq(&node.name))
|
||||||
|
.count()
|
||||||
|
!= 1
|
||||||
|
{
|
||||||
|
if self.get_names && node.id == node_id {
|
||||||
|
println!("Port from node {} -> {}: {}", &node.name, id, name);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ports = self
|
||||||
|
.ports
|
||||||
|
.iter()
|
||||||
|
.filter(|a| !(a.name.eq(&name) && a.node.name.eq(&node.name)))
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<Rc<Port>>>();
|
||||||
|
|
||||||
|
ports.push(Rc::new(Port { id, name, node }));
|
||||||
|
|
||||||
|
self.ports = ports;
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_links(&mut self, port_name: String, core: Rc<pw::Core>) {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TempLink {
|
||||||
|
port_in: Option<Rc<Port>>,
|
||||||
|
port_out: Option<Rc<Port>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.link_def
|
||||||
|
.iter()
|
||||||
|
.filter(|link| (link.port_in.name.eq(&port_name) || link.port_out.name.eq(&port_name)))
|
||||||
|
.map(|a| TempLink {
|
||||||
|
port_in: self.get_port_by_name(a.port_in.name.to_string()),
|
||||||
|
port_out: self.get_port_by_name(a.port_out.name.to_string()),
|
||||||
|
}).filter(|a| a.port_in.is_some() && a.port_out.is_some()).for_each(|a| {
|
||||||
|
let port_in = a.port_in.unwrap();
|
||||||
|
let port_out = a.port_out.unwrap();
|
||||||
|
|
||||||
|
println!("Try to created link: [{}]{} -> [{}]{}", port_out.node.name, port_out.name, port_in.node.name, port_in.name);
|
||||||
|
|
||||||
|
// Try to create the link
|
||||||
|
if core.create_object::<pw::link::Link, _>(
|
||||||
|
// The actual name for a link factory might be different for your system,
|
||||||
|
// you should probably obtain a factory from the registry.
|
||||||
|
"link-factory",
|
||||||
|
&pw::properties! {
|
||||||
|
"link.output.port" => port_out.id.to_string(),
|
||||||
|
"link.input.port" => port_in.id.to_string(),
|
||||||
|
"link.output.node" => port_out.node.id.to_string(),
|
||||||
|
"link.input.node" => port_in.node.id.to_string(),
|
||||||
|
"object.linger" => "1"
|
||||||
|
},
|
||||||
|
).is_err() {
|
||||||
|
println!("Failed to create link");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deal_with_node(
|
||||||
|
global_object: &pipewire::registry::GlobalObject<libspa::ForeignDict>,
|
||||||
|
mut state: RefMut<AppState>,
|
||||||
|
) {
|
||||||
|
if let Some(props) = &global_object.props {
|
||||||
|
if let (Some(class), Some(name)) = (props.get("media.class"), props.get("node.name")) {
|
||||||
|
if class.starts_with("Audio") {
|
||||||
|
if state.get_names {
|
||||||
|
println!(
|
||||||
|
"Got Audio device {}: {}({})",
|
||||||
|
global_object.id,
|
||||||
|
name,
|
||||||
|
props.get("node.nick").unwrap_or("<no nick>")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.try_add_node(Node {
|
||||||
|
id: global_object.id,
|
||||||
|
name: name.to_string(),
|
||||||
|
}) {
|
||||||
|
println!(
|
||||||
|
"Got {}: {}({})",
|
||||||
|
global_object.id,
|
||||||
|
name,
|
||||||
|
props.get("node.nick").unwrap_or("<no nick>")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("No props! Skiping id: {:?}", global_object.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deal_with_port(
|
||||||
|
port: &pipewire::registry::GlobalObject<libspa::ForeignDict>,
|
||||||
|
mut state: RefMut<AppState>,
|
||||||
|
core: Rc<pw::Core>,
|
||||||
|
) {
|
||||||
|
if let Some(props) = &port.props {
|
||||||
|
if let (Some(name), Some(node_id)) = (props.get("port.name"), props.get("node.id")) {
|
||||||
|
if let Ok(node_id) = node_id.parse::<u32>() {
|
||||||
|
if state.try_add_port(port.id, name.to_string(), node_id) {
|
||||||
|
println!(
|
||||||
|
"Got port {} for {}",
|
||||||
|
name,
|
||||||
|
state.get_node(node_id).unwrap().name
|
||||||
|
);
|
||||||
|
state.create_links(name.to_string(), core)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("Clould not parse {}'s node.id({})", name, node_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("No props! Skiping id: {}", port.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn help() {
|
||||||
|
println!("Usage: \n");
|
||||||
|
println!("pw-autoconnect <filename> \n")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_file(path: std::path::PathBuf, get_names: bool) -> Result<AppState, Box<dyn std::error::Error>> {
|
||||||
|
let file = fs::File::open(path)?;
|
||||||
|
let reader = std::io::BufReader::new(file);
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref RE: Regex = Regex::new("\\[(?P<node_out>.*)\\]\\((?P<port_out>.*)\\)\\s*->\\s*\\[(?P<node_in>.*)\\]\\((?P<port_in>.*)\\)").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut node_def: HashMap<String, Rc<NodeDef>> = HashMap::new();
|
||||||
|
let mut port_def: HashMap<String, Rc<PortDef>> = HashMap::new();
|
||||||
|
let mut link_def: Vec<Rc<LinkDef>> = Vec::new();
|
||||||
|
|
||||||
|
for line in reader.lines() {
|
||||||
|
let line = line?;
|
||||||
|
|
||||||
|
if RE.is_match(&line) {
|
||||||
|
let caps = RE.captures(&line).unwrap();
|
||||||
|
println!("Found link: [{}]{} -> [{}]{}", &caps["node_out"], &caps["port_out"], &caps["node_in"], &caps["port_in"]);
|
||||||
|
|
||||||
|
let node_out = match node_def.get_mut(&caps["node_out"]) {
|
||||||
|
Some(node) => node.to_owned(),
|
||||||
|
None => {
|
||||||
|
let node = Rc::new(NodeDef {name: caps["node_out"].to_string()});
|
||||||
|
node_def.insert(caps["node_out"].to_string(), node.clone());
|
||||||
|
node
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let node_in = match node_def.get_mut(&caps["node_in"]) {
|
||||||
|
Some(node) => node.to_owned(),
|
||||||
|
None => {
|
||||||
|
let node = Rc::new(NodeDef {name: caps["node_in"].to_string()});
|
||||||
|
node_def.insert(caps["node_in"].to_string(), node.clone());
|
||||||
|
node
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let port_out = match port_def.get_mut(&caps["port_out"]) {
|
||||||
|
Some(port) => port.to_owned(),
|
||||||
|
None => {
|
||||||
|
let port = Rc::new(PortDef { node: node_out.clone(), name: caps["port_out"].to_string() } );
|
||||||
|
port_def.insert(caps["port_out"].to_string(), port.clone());
|
||||||
|
port
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let port_in = match port_def.get_mut(&caps["port_in"]) {
|
||||||
|
Some(port) => port.to_owned(),
|
||||||
|
None => {
|
||||||
|
let port = Rc::new(PortDef { node: node_in.clone(), name: caps["port_in"].to_string() } );
|
||||||
|
port_def.insert(caps["port_in"].to_string(), port.clone());
|
||||||
|
port
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let link = Rc::new(LinkDef { port_out: port_out.clone(), port_in: port_in.clone() });
|
||||||
|
|
||||||
|
link_def.push(link)
|
||||||
|
} else if !line.starts_with('#') {
|
||||||
|
println!("invalid line: {}", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let node_def = node_def.values().cloned().collect::<Vec<Rc<NodeDef>>>();
|
||||||
|
let port_def = port_def.values().cloned().collect::<Vec<Rc<PortDef>>>();
|
||||||
|
|
||||||
|
Ok(AppState::new(node_def, link_def, port_def, get_names))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
println!("Hello, world!");
|
||||||
|
|
||||||
|
let mut args = env::args();
|
||||||
|
// Skip the current directory
|
||||||
|
args.next();
|
||||||
|
|
||||||
|
let mut find_names = false;
|
||||||
|
|
||||||
|
let mut file_name = None;
|
||||||
|
|
||||||
|
for a in args {
|
||||||
|
if a.eq("-f") {
|
||||||
|
find_names = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if file_name.is_some() {
|
||||||
|
println!("File name already exists");
|
||||||
|
return Ok(());
|
||||||
|
} else {
|
||||||
|
file_name = Some(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if file_name.is_none() {
|
||||||
|
help();
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let file_name = file_name.unwrap();
|
||||||
|
|
||||||
|
let path = std::path::Path::new(&file_name);
|
||||||
|
|
||||||
|
if !path.exists() || !path.is_file() {
|
||||||
|
println!("File not found does not exists");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create DeSized State
|
||||||
|
|
||||||
|
let state = RefCell::new(parse_file(path.to_path_buf(), find_names)?);
|
||||||
|
|
||||||
|
println!("\n\nGot state! Starting up\n\n");
|
||||||
|
|
||||||
|
let mainloop = MainLoop::new()?;
|
||||||
|
let context = Context::new(&mainloop)?;
|
||||||
|
let core = Rc::new(context.connect(None)?);
|
||||||
|
let registry = core.get_registry()?;
|
||||||
|
|
||||||
|
let _listener = registry
|
||||||
|
.add_listener_local()
|
||||||
|
.global(move |global| match global.type_ {
|
||||||
|
ObjectType::Port => deal_with_port(global, state.borrow_mut(), core.clone()),
|
||||||
|
ObjectType::Node => deal_with_node(global, state.borrow_mut()),
|
||||||
|
_ => (),
|
||||||
|
})
|
||||||
|
.register();
|
||||||
|
|
||||||
|
mainloop.run();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user