diff --git a/Cargo.lock b/Cargo.lock index 47ad165..07dfaa6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,6 +434,15 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "atomic" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" +dependencies = [ + "bytemuck", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -517,6 +526,12 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "bit-set" version = "0.5.3" @@ -1030,6 +1045,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "csscolorparser" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf" +dependencies = [ + "lab", + "phf", +] + [[package]] name = "cursor-icon" version = "1.1.0" @@ -1047,6 +1072,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "deltae" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4" + [[package]] name = "derivative" version = "2.2.0" @@ -1068,6 +1099,26 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -1352,6 +1403,15 @@ version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" +[[package]] +name = "euclid" +version = "0.22.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" +dependencies = [ + "num-traits", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1406,6 +1466,16 @@ dependencies = [ "zune-inflate", ] +[[package]] +name = "fancy-regex" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +dependencies = [ + "bit-set", + "regex", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -1441,6 +1511,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.33" @@ -1460,6 +1542,12 @@ dependencies = [ "spin", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "foreign-types" version = "0.5.0" @@ -2062,6 +2150,12 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "lab" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f" + [[package]] name = "lazy_static" version = "1.5.0" @@ -2132,6 +2226,16 @@ dependencies = [ "redox_syscall 0.4.1", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + [[package]] name = "libssh2-sys" version = "0.3.0" @@ -2221,6 +2325,16 @@ dependencies = [ "imgref", ] +[[package]] +name = "mac_address" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8836fae9d0d4be2c8b4efcdd79e828a2faa058a90d005abf42f91cac5493a08e" +dependencies = [ + "nix 0.28.0", + "winapi", +] + [[package]] name = "mach2" version = "0.4.2" @@ -2272,6 +2386,12 @@ dependencies = [ "libc", ] +[[package]] +name = "memmem" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15" + [[package]] name = "memoffset" version = "0.6.5" @@ -2437,6 +2557,20 @@ dependencies = [ "cfg-if", "libc", "memoffset 0.7.1", + "pin-utils", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases 0.1.1", + "libc", + "memoffset 0.9.1", ] [[package]] @@ -2492,6 +2626,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "num-derive" version = "0.4.2" @@ -2727,7 +2872,16 @@ version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ - "libredox", + "libredox 0.0.2", +] + +[[package]] +name = "ordered-float" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d501f1a72f71d3c063a6bbc8f7271fa73aa09fe5d6283b6571e2ed176a2537" +dependencies = [ + "num-traits", ] [[package]] @@ -2815,6 +2969,103 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "pest_meta" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -3133,7 +3384,7 @@ dependencies = [ "maybe-rayon", "new_debug_unreachable", "noop_proc_macro", - "num-derive", + "num-derive 0.4.2", "num-traits", "once_cell", "paste", @@ -3229,6 +3480,17 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox 0.1.3", + "thiserror", +] + [[package]] name = "regex" version = "1.10.6" @@ -3346,6 +3608,24 @@ dependencies = [ "tiny-skia", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.210" @@ -3427,7 +3707,7 @@ dependencies = [ "ioctl-rs", "libc", "serial-core", - "termios", + "termios 0.2.2", ] [[package]] @@ -3469,6 +3749,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shared_library" version = "0.1.9" @@ -3491,6 +3782,16 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -3515,6 +3816,12 @@ dependencies = [ "quote", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -3661,6 +3968,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.109" @@ -3738,6 +4051,19 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminfo" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "666cd3a6681775d22b200409aad3b089c5b99fb11ecdd8a204d9d62f8148498f" +dependencies = [ + "dirs", + "fnv", + "nom", + "phf", + "phf_codegen", +] + [[package]] name = "termios" version = "0.2.2" @@ -3747,6 +4073,59 @@ dependencies = [ "libc", ] +[[package]] +name = "termios" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b" +dependencies = [ + "libc", +] + +[[package]] +name = "termwiz" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a75313e21da5d4406ea31402035b3b97aa74c04356bdfafa5d1043ab4e551d1" +dependencies = [ + "anyhow", + "base64", + "bitflags 2.6.0", + "fancy-regex", + "filedescriptor", + "finl_unicode", + "fixedbitset", + "hex", + "lazy_static", + "libc", + "log", + "memmem", + "nix 0.26.4", + "num-derive 0.3.3", + "num-traits", + "ordered-float", + "pest", + "pest_derive", + "phf", + "semver", + "sha2", + "signal-hook", + "siphasher", + "tempfile", + "terminfo", + "termios 0.3.3", + "thiserror", + "ucd-trie", + "unicode-segmentation", + "vtparse", + "wezterm-bidi", + "wezterm-blob-leases", + "wezterm-color-types", + "wezterm-dynamic", + "wezterm-input-types", + "winapi", +] + [[package]] name = "tester" version = "0.1.0" @@ -3766,6 +4145,7 @@ dependencies = [ "serde_json", "serialport", "ssh2", + "termwiz", "toml", "vte", "xcap", @@ -3939,6 +4319,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "uds_windows" version = "1.1.0" @@ -4030,6 +4416,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "atomic", + "getrandom", +] + [[package]] name = "v_frame" version = "0.3.8" @@ -4080,6 +4476,15 @@ dependencies = [ "quote", ] +[[package]] +name = "vtparse" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9b2acfb050df409c972a37d3b8e08cdea3bddb0c09db9d53137e504cfabed0" +dependencies = [ + "utf8parse", +] + [[package]] name = "waker-fn" version = "1.2.0" @@ -4347,6 +4752,78 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" +[[package]] +name = "wezterm-bidi" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0a6e355560527dd2d1cf7890652f4f09bb3433b6aadade4c9b5ed76de5f3ec" +dependencies = [ + "log", + "wezterm-dynamic", +] + +[[package]] +name = "wezterm-blob-leases" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5a5e0adf7eed68976410def849a4bdab6f6e9f6163f152de9cb89deea9e60b" +dependencies = [ + "getrandom", + "mac_address", + "once_cell", + "sha2", + "thiserror", + "uuid", +] + +[[package]] +name = "wezterm-color-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de81ef35c9010270d63772bebef2f2d6d1f2d20a983d27505ac850b8c4b4296" +dependencies = [ + "csscolorparser", + "deltae", + "lazy_static", + "wezterm-dynamic", +] + +[[package]] +name = "wezterm-dynamic" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb128bacfa86734e07681fb6068e34c144698e84ee022d6e009145d1abb77b5" +dependencies = [ + "log", + "ordered-float", + "strsim", + "thiserror", + "wezterm-dynamic-derive", +] + +[[package]] +name = "wezterm-dynamic-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9f5ef318442d07b3d071f9f43ea40b80992f87faee14bb4d017b6991c307f0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "wezterm-input-types" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7012add459f951456ec9d6c7e6fc340b1ce15d6fc9629f8c42853412c029e57e" +dependencies = [ + "bitflags 1.3.2", + "euclid", + "lazy_static", + "wezterm-dynamic", +] + [[package]] name = "wgpu" version = "0.20.1" diff --git a/Cargo.toml b/Cargo.toml index 6645493..aea1970 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "tester" version = "0.1.0" edition = "2021" +license = "GPL-3.0-or-later" # We used GPL lib # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] @@ -27,6 +28,7 @@ portable-pty = "0.8.1" inventory = "0.3.15" eframe = "0.28.1" egui_extras = "0.28.1" +termwiz = "0.22.0" [toolchain] channel = "nightly" diff --git a/src/lib.rs b/src/lib.rs index 77b9017..d796f13 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ #![feature(box_into_inner)] #![feature(macro_metavar_expr_concat)] #![allow(clippy::module_inception)] +#![feature(new_range_api)] pub mod consts; pub mod cli; diff --git a/src/pythonapi/asciicast.rs b/src/pythonapi/asciicast.rs index 94ae1c8..51d4e7d 100644 --- a/src/pythonapi/asciicast.rs +++ b/src/pythonapi/asciicast.rs @@ -2,9 +2,9 @@ use pyo3::{exceptions::PyRuntimeError, pyclass, pymethods, PyResult}; use crate::util::anybase::heap_raw; -use super::shell_like::{handle_wrap, PyTty, PyTtyWrapper, TtyType}; +use super::shell_like::{handle_wrap, py_tty_inner, PyTty, PyTtyInner, TtyType}; -pub fn handle_asciicast(inner: &mut Option) -> PyResult<()> { +pub fn handle_asciicast(inner: &mut Option) -> PyResult<()> { if inner.is_none() { return Err(PyRuntimeError::new_err( "You must define at least one valid object", @@ -15,7 +15,7 @@ pub fn handle_asciicast(inner: &mut Option) -> PyResult<()> { let be_wrapped = Box::into_inner(be_wrapped); let tee = Box::new(crate::cli::asciicast::Asciicast::build(be_wrapped)); let tee = tee as TtyType; - *inner = Some(PyTtyWrapper { tty: heap_raw(tee) }); + *inner = Some(py_tty_inner(heap_raw(tee))); Ok(()) } diff --git a/src/pythonapi/deansi.rs b/src/pythonapi/deansi.rs index e9f2266..43e613a 100644 --- a/src/pythonapi/deansi.rs +++ b/src/pythonapi/deansi.rs @@ -2,9 +2,9 @@ use pyo3::{exceptions::PyRuntimeError, pyclass, pymethods, PyResult}; use crate::{cli::tty::Tty, util::anybase::heap_raw}; -use super::shell_like::{handle_wrap, PyTty, PyTtyWrapper, TtyType}; +use super::shell_like::{handle_wrap, py_tty_inner, PyTty, PyTtyInner, TtyType}; -pub fn handle_deansi(inner: &mut Option) -> PyResult<()> { +pub fn handle_deansi(inner: &mut Option) -> PyResult<()> { if inner.is_none() { return Err(PyRuntimeError::new_err( "You must define at least one valid object", @@ -15,9 +15,7 @@ pub fn handle_deansi(inner: &mut Option) -> PyResult<()> { let be_wrapped = Box::into_inner(be_wrapped); let dean = Box::new(crate::cli::deansi::DeANSI::build(be_wrapped)); let dean: Box = dean as TtyType; - *inner = Some(PyTtyWrapper { - tty: heap_raw(dean), - }); + *inner = Some(py_tty_inner(heap_raw(dean))); Ok(()) } diff --git a/src/pythonapi/exec.rs b/src/pythonapi/exec.rs index bf25c90..b4356d7 100644 --- a/src/pythonapi/exec.rs +++ b/src/pythonapi/exec.rs @@ -9,20 +9,15 @@ use crate::{ util::anybase::heap_raw, }; -use super::shell_like::{handle_wrap, PyTty, PyTtyWrapper, TtyType}; +use super::shell_like::{handle_wrap, py_tty_inner, PyTty, PyTtyInner, TtyType}; -pub fn handle_clitester(inner: &mut Option, need_sudo: Option) -> PyResult<()> { +pub fn handle_clitester(inner: &mut Option, need_sudo: Option) -> PyResult<()> { if inner.is_none() { return Err(PyRuntimeError::new_err( "You must define at least one valid object", )); } let mut be_wrapped = inner.take().unwrap(); - if be_wrapped.tty.is_null() { - return Err(PyRuntimeError::new_err( - "You gave me it, you will never own it again.", - )); - } let tty = be_wrapped.safe_take()?; let tty = Box::into_inner(tty); let need_sudo = need_sudo.unwrap_or(true); @@ -33,7 +28,7 @@ pub fn handle_clitester(inner: &mut Option, need_sudo: Option) -> PyTty { let inner = TtyHook::build(inner); let inner = Box::new(inner); - let inner = PyTtyWrapper { - tty: heap_raw(inner) - }; - PyTty { - inner - } + let inner = py_tty_inner(heap_raw(inner)); + PyTty { inner } } pub struct TtyHook { diff --git a/src/pythonapi/serial.rs b/src/pythonapi/serial.rs index c97a429..dd0ac3a 100644 --- a/src/pythonapi/serial.rs +++ b/src/pythonapi/serial.rs @@ -2,7 +2,7 @@ use pyo3::{exceptions::PyRuntimeError, pyclass, pymethods, PyResult}; use crate::util::anybase::heap_raw; -use super::shell_like::{PyTty, PyTtyWrapper, TtyType}; +use super::shell_like::{py_tty_inner, PyTty, TtyType}; #[pyclass(extends=PyTty, subclass)] pub struct Serial {} @@ -15,11 +15,6 @@ impl Serial { let serial = crate::cli::serial::Serial::build(port, baud) .map_err(|e| PyRuntimeError::new_err(e.to_string()))?; let serial = Box::new(serial) as TtyType; - Ok(( - Serial {}, - PyTty::build(PyTtyWrapper { - tty: heap_raw(serial), - }), - )) + Ok((Serial {}, PyTty::build(py_tty_inner(heap_raw(serial))))) } } diff --git a/src/pythonapi/shell.rs b/src/pythonapi/shell.rs index d8d5a78..d808cb4 100644 --- a/src/pythonapi/shell.rs +++ b/src/pythonapi/shell.rs @@ -3,14 +3,14 @@ use serde::Deserialize; use crate::util::anybase::heap_raw; -use super::shell_like::{PyTty, PyTtyWrapper, TtyType}; +use super::shell_like::{py_tty_inner, PyTty, PyTtyInner, TtyType}; #[derive(Deserialize)] pub struct ShellConf { pub shell: Option, } -pub fn handle_shell(inner: &mut Option, shell_conf: ShellConf) -> PyResult<()> { +pub fn handle_shell(inner: &mut Option, shell_conf: ShellConf) -> PyResult<()> { let shell = shell_conf.shell.as_deref(); let shell = crate::cli::shell::Shell::build(shell) .map_err(|e| PyRuntimeError::new_err(e.to_string()))?; @@ -20,9 +20,7 @@ pub fn handle_shell(inner: &mut Option, shell_conf: ShellConf) -> )); } let shell = Box::new(shell) as TtyType; - *inner = Some(PyTtyWrapper { - tty: heap_raw(shell), - }); + *inner = Some(py_tty_inner(heap_raw(shell))); Ok(()) } @@ -37,11 +35,6 @@ impl Shell { let shell = crate::cli::shell::Shell::build(shell) .map_err(|e| PyRuntimeError::new_err(e.to_string()))?; let shell = Box::new(shell) as TtyType; - Ok(( - Shell {}, - PyTty::build(PyTtyWrapper { - tty: heap_raw(shell), - }), - )) + Ok((Shell {}, PyTty::build(py_tty_inner(heap_raw(shell))))) } } diff --git a/src/pythonapi/shell_like.rs b/src/pythonapi/shell_like.rs index 76374a3..d619b56 100644 --- a/src/pythonapi/shell_like.rs +++ b/src/pythonapi/shell_like.rs @@ -26,12 +26,20 @@ use super::{ pub type TtyType = DynTty; -pub struct PyTtyWrapper { - pub tty: *mut TtyType, +pub trait PyTtyWrapper: Send { + fn take(&mut self) -> PyResult<*mut TtyType>; + fn safe_take(&mut self) -> PyResult>; + fn get(&self) -> PyResult<&TtyType>; + fn get_mut(&mut self) -> PyResult<&mut TtyType>; + fn put(&mut self, tty: *mut TtyType) -> PyResult<()>; } -impl PyTtyWrapper { - pub fn take(&mut self) -> PyResult<*mut TtyType> { +pub struct PyTtyWrapperBasic { + tty: *mut TtyType, +} + +impl PyTtyWrapper for PyTtyWrapperBasic { + fn take(&mut self) -> PyResult<*mut TtyType> { if self.tty.is_null() { return Err(PyRuntimeError::new_err( "You gave me it, you will never own it again.", @@ -41,11 +49,11 @@ impl PyTtyWrapper { self.tty = null_mut(); Ok(res) } - pub fn safe_take(&mut self) -> PyResult> { + fn safe_take(&mut self) -> PyResult> { let res = self.take()?; Ok(unsafe { Box::from_raw(res) }) } - pub fn get(&self) -> PyResult<&TtyType> { + fn get(&self) -> PyResult<&TtyType> { if self.tty.is_null() { return Err(PyRuntimeError::new_err( "You gave me it, you will never own it again.", @@ -53,7 +61,7 @@ impl PyTtyWrapper { } Ok(unsafe { &*self.tty }) } - pub fn get_mut(&self) -> PyResult<&mut TtyType> { + fn get_mut(&mut self) -> PyResult<&mut TtyType> { if self.tty.is_null() { return Err(PyRuntimeError::new_err( "You gave me it, you will never own it again.", @@ -61,17 +69,35 @@ impl PyTtyWrapper { } Ok(unsafe { &mut *self.tty }) } + fn put(&mut self, tty: *mut TtyType) -> PyResult<()> { + if !self.tty.is_null() { + return Err(PyRuntimeError::new_err( + "You must take the object before you put another one.", + )); + } + self.tty = tty; + Ok(()) + } } -unsafe impl Send for PyTtyWrapper {} +unsafe impl Send for PyTtyWrapperBasic {} +unsafe impl Sync for PyTtyWrapperBasic {} + +pub type PyTtyInner = Box; + +pub fn py_tty_inner(tty: *mut TtyType) -> PyTtyInner { + let inner = PyTtyWrapperBasic { tty }; + let inner = Box::new(inner); + inner as PyTtyInner +} #[pyclass(subclass)] pub struct PyTty { - pub inner: PyTtyWrapper, + pub inner: PyTtyInner, } impl PyTty { - pub fn build(inner: PyTtyWrapper) -> Self { + pub fn build(inner: PyTtyInner) -> Self { PyTty { inner } } } @@ -95,10 +121,7 @@ struct PyTtyExecConf { sudo: Option, } -pub fn handle_wrap( - inner: &mut Option, - be_wrapped: Option<&mut PyTty>, -) -> PyResult<()> { +pub fn handle_wrap(inner: &mut Option, be_wrapped: Option<&mut PyTty>) -> PyResult<()> { if be_wrapped.is_none() { return Err(PyRuntimeError::new_err( "be_wrapped must be provided when wrap is true", @@ -106,13 +129,11 @@ pub fn handle_wrap( } let be_wrapped = be_wrapped.unwrap(); - *inner = Some(PyTtyWrapper { - tty: be_wrapped.inner.take()?, - }); + *inner = Some(py_tty_inner(be_wrapped.inner.take()?)); Ok(()) } -pub fn handle_simple_recorder(inner: &mut Option) -> PyResult<()> { +pub fn handle_simple_recorder(inner: &mut Option) -> PyResult<()> { if inner.is_none() { return Err(PyRuntimeError::new_err( "You must define at least one valid object", @@ -123,9 +144,7 @@ pub fn handle_simple_recorder(inner: &mut Option) -> PyResult<()> let tty = Box::into_inner(tty); let recorder = Box::new(SimpleRecorder::build(tty)); let recorder = recorder as TtyType; - *inner = Some(PyTtyWrapper { - tty: heap_raw(recorder), - }); + *inner = Some(py_tty_inner(heap_raw(recorder))); Ok(()) } @@ -219,49 +238,37 @@ impl PyTty { let inner = inner.downcast::().unwrap(); let inner = inner.exit(); Ok(PyTty { - inner: PyTtyWrapper { - tty: heap_raw(inner), - }, + inner: py_tty_inner(heap_raw(inner)), }) } else if inner.downcast_ref::().is_some() { let inner = inner.downcast::().unwrap(); let inner = inner.exit(); Ok(PyTty { - inner: PyTtyWrapper { - tty: heap_raw(inner), - }, + inner: py_tty_inner(heap_raw(inner)), }) } else if inner.downcast_ref::().is_some() { let inner = inner.downcast::().unwrap(); let inner = inner.exit(); Ok(PyTty { - inner: PyTtyWrapper { - tty: heap_raw(inner), - }, + inner: py_tty_inner(heap_raw(inner)), }) } else if inner.downcast_ref::().is_some() { let inner = inner.downcast::().unwrap(); let inner = inner.exit(); Ok(PyTty { - inner: PyTtyWrapper { - tty: heap_raw(inner), - }, + inner: py_tty_inner(heap_raw(inner)), }) } else if inner.downcast_ref::().is_some() { let inner = inner.downcast::().unwrap(); let inner = inner.exit(); Ok(PyTty { - inner: PyTtyWrapper { - tty: heap_raw(inner), - }, + inner: py_tty_inner(heap_raw(inner)), }) } else if inner.downcast_ref::().is_some() { let inner = inner.downcast::().unwrap(); let inner = inner.exit(); Ok(PyTty { - inner: PyTtyWrapper { - tty: heap_raw(inner), - }, + inner: py_tty_inner(heap_raw(inner)), }) } else { Err(PyRuntimeError::new_err( @@ -369,7 +376,7 @@ impl PyTty { return Err(PyRuntimeError::new_err(e.to_string())); } let target = target.unwrap(); - other.inner.tty = heap_raw(target); + other.inner.put(heap_raw(target))?; Ok(()) } else if inner.downcast_ref::().is_some() { let inner = inner.downcast_mut::().unwrap(); @@ -380,7 +387,7 @@ impl PyTty { return Err(PyRuntimeError::new_err(e.to_string())); } let target = target.unwrap(); - other.inner.tty = heap_raw(target); + other.inner.put(heap_raw(target))?; Ok(()) } else { Err(PyRuntimeError::new_err( diff --git a/src/pythonapi/tee.rs b/src/pythonapi/tee.rs index ffb3b63..5b2bc58 100644 --- a/src/pythonapi/tee.rs +++ b/src/pythonapi/tee.rs @@ -3,14 +3,14 @@ use serde::Deserialize; use crate::util::anybase::heap_raw; -use super::shell_like::{handle_wrap, PyTty, PyTtyWrapper, TtyType}; +use super::shell_like::{handle_wrap, py_tty_inner, PyTty, PyTtyInner, TtyType}; #[derive(Deserialize)] pub struct PyTeeConf { pub path: String, } -pub fn handle_tee(inner: &mut Option, tee_conf: PyTeeConf) -> PyResult<()> { +pub fn handle_tee(inner: &mut Option, tee_conf: PyTeeConf) -> PyResult<()> { let path = tee_conf.path; if inner.is_none() { return Err(PyRuntimeError::new_err( @@ -22,7 +22,7 @@ pub fn handle_tee(inner: &mut Option, tee_conf: PyTeeConf) -> PyRe let be_wrapped = Box::into_inner(be_wrapped); let tee = Box::new(crate::cli::tee::Tee::build(be_wrapped, &path)); let tee = tee as TtyType; - *inner = Some(PyTtyWrapper { tty: heap_raw(tee) }); + *inner = Some(py_tty_inner(heap_raw(tee))); Ok(()) }