radb 0.1.8

A Rust Implement Python AdbUtils
Documentation
use crate::errors::{AdbError, AdbResult};
use crate::protocols::frame;
use async_trait::async_trait;
use log::info;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};

#[async_trait]
pub trait AdbProtocol: AsyncRead + AsyncWrite + Unpin + Send {
    async fn send_command(&mut self, command: &str) -> AdbResult<()> {
        let packet = frame::build_command_packet(command);
        self.send_all(&packet).await
    }

    async fn send(&mut self, data: &[u8]) -> AdbResult<usize> {
        self.send_all(data).await?;
        Ok(data.len())
    }

    async fn send_all(&mut self, data: &[u8]) -> AdbResult<()> {
        info!(">>>>>>> Send Size: {:#?} >>>>>>>", data.len());
        self.write_all(data).await?;
        Ok(())
    }

    async fn recv(&mut self, n: usize) -> AdbResult<Vec<u8>> {
        self.recv_exact(n).await
    }

    async fn recv_exact(&mut self, n: usize) -> AdbResult<Vec<u8>> {
        info!("<<<<<<< Try Recv Exact Size: {:#?} <<<<<<<", n);
        let mut target = vec![0; n];
        self.read_exact(&mut target).await?;
        Ok(target)
    }

    async fn read_string(&mut self, size: usize) -> AdbResult<String> {
        let data = self.recv_exact(size).await?;
        Ok(String::from_utf8_lossy(&data).to_string())
    }

    async fn read_response(&mut self) -> AdbResult<String> {
        let length_buf = self.recv_exact(4).await?;
        let length = frame::parse_length_prefix(&length_buf)?;
        let data_buf = self.recv_exact(length).await?;
        Ok(String::from_utf8_lossy(&data_buf).to_string())
    }

    async fn send_cmd_then_check_okay(&mut self, command: &str) -> AdbResult<()> {
        self.send_command(command).await?;
        let response = self.recv_exact(4).await?;

        if frame::is_okay_response(&response) {
            Ok(())
        } else if frame::is_fail_response(&response) {
            let error_msg = self.read_response().await?;
            Err(AdbError::command_failed(command, error_msg))
        } else {
            Err(AdbError::protocol_error("Unexpected response"))
        }
    }

    async fn read_until_close(&mut self) -> AdbResult<String> {
        let mut content = Vec::new();
        let mut buf = vec![0; 4096];
        loop {
            let bytes_read = self.read(&mut buf).await?;
            if bytes_read == 0 {
                break;
            }
            content.extend_from_slice(&buf[..bytes_read]);
        }
        Ok(String::from_utf8_lossy(&content).to_string())
    }
}

#[async_trait]
impl<T> AdbProtocol for T where T: AsyncRead + AsyncWrite + Unpin + Send {}