doe 1.1.88

doe is a powerful Rust crate designed to enhance development workflow by providing an extensive collection of useful macros and utility functions. It not only simplifies common tasks but also offers convenient features for clipboard management,robust cryptographic functions,keyboard input, and mouse interaction.
Documentation
/// Asynchronous utilities for working with Tokio runtime and async operations
///
/// Provides functionality for:
/// - Blocking on async operations
/// - Running system commands asynchronously
///
/// # Examples
///
/// ```ignore
/// #[allow(warnings)]
/// fn main() {
/// // Block on an async operation
/// asyncrs::block_on(async {
///     let output = asyncrs::command("echo hello").await;
///     println!("{}", String::from_utf8_lossy(&output.stdout));
/// });
///     let rt = doe::asyncrs::runtime::Builder::new_multi_thread()
///         .enable_all()
///         .build()
///         .unwrap();
///     rt.block_on(run());
///     rt.block_on(async {
///         run().await;
///     });
/// }
///
/// async fn run() {}
///
/// ```
#[allow(warnings)]
#[cfg(feature = "asyncrs")]
pub mod asyncrs {
    pub use tokio;
    pub use tokio::runtime::Runtime;
    pub use tokio::*;

    use crate::Vector;

    /// Trait for blocking on async operations
    ///
    /// Provides a method to block the current thread until a future completes
    use std::future::Future;

    pub trait BlockOn: Future + Send + 'static {
        /// Runs the future to completion on a new multi‑threaded Tokio runtime,
        /// blocking the current thread until it finishes.
        ///
        /// # Panics
        ///
        /// ```ignore
        ///     use doe::asyncrs::BlockOn;
        ///     
        ///     fn main() {
        ///         run().block_on();
        ///     }
        ///     
        ///     async fn run() {
        ///         println!("start");
        ///         use doe::httprs::*;
        ///         let headers = r#"
        ///     POST /api/v3/translate HTTP/1.1
        ///     Host: demo.com
        ///     Connection: keep-alive
        ///     Content-Length: 271
        ///     Accept-Language: zh-CN,zh;q=0.9
        ///         "#.to_headers();
        ///         let client = doe::httprs::async_client().await;
        ///         let resp = client.post("https://demo.com/api/v3/translate")
        ///             .headers(headers)
        ///             .body(doe::json::json!({"content":"由于","unionid":"ozM5_0WbKEDN6WmhHAphhBoVCUGE","openid":"o7jUU0dPlvcvDQwnfAcTPEuMxrD8","source_flag":"wxd511b28a58c8d268","source":"汉维翻译小程序大号"}).to_string())
        ///             .send().await.unwrap().text().await.unwrap();
        ///         std::fs::write("resp.json", resp).unwrap();
        ///     }
        /// ```
        ///
        /// Panics if a new Tokio runtime cannot be created.
        fn block_on(self) -> Self::Output
        where
            Self: Sized,
        {
            let rt = tokio::runtime::Builder::new_multi_thread()
                .enable_all()
                .build()
                .unwrap();
            rt.block_on(self)
        }
    }

    // Blanket implementation: every future that is Send + 'static
    // automatically gets the .block_on() method.
    impl<F, T> BlockOn for F where F: Future<Output = T> + Send + 'static {}

    /// Blocks the current thread on the given future, executing it to completion
    ///
    /// Creates a new Tokio runtime and uses it to run the provided future
    ///
    /// # Arguments
    ///
    /// * `future` - A future that will be blocked on
    ///
    /// # Panics
    ///
    /// Panics if unable to create a new Tokio runtime
    pub fn block_on<F, T>(future: F) -> T
    where
        F: std::future::Future<Output = T> + Send + 'static,
    {
        let rt = tokio::runtime::Builder::new_multi_thread()
            .enable_all()
            .build()
            .unwrap();
        rt.block_on(future)
    }

    /// Executes a system command asynchronously
    ///
    /// # Arguments
    ///
    /// * `command` - The command to execute, can be a string or byte slice
    ///
    /// # Returns
    ///
    /// Returns a `std::process::Output` containing the command's output
    ///
    /// # Panics
    ///
    /// Panics if unable to spawn the child process
    ///
    /// # Example
    ///
    /// ```
    /// use doe::asyncrs;
    ///
    /// asyncrs::block_on(async {
    ///     let output = asyncrs::command("echo hello").await;
    ///     println!("{}", String::from_utf8_lossy(&output.stdout));
    /// });
    /// ```
    pub async fn command(command: impl AsRef<[u8]>) -> std::process::Output {
        use std::process::Stdio;
        use tokio::process::Command;
        let command = command.as_ref().to_string_lossy().to_string();
        let exe = command.split(" ").into_iter().nth(0).unwrap();
        let other = command.split(" ").into_iter().skip(1).collect::<Vec<_>>();
        let child = Command::new(exe)
            .args(other)
            .stdin(Stdio::piped())
            .stdout(Stdio::piped())
            .stderr(Stdio::piped())
            .spawn()
            .expect("Failed to spawn child process");
        let output = child
            .wait_with_output()
            .await
            .expect("Failed to wait on child");
        output
    }
}
#[cfg(feature = "asyncrs")]
pub use asyncrs::*;