adb_client 3.2.0

Rust ADB (Android Debug Bridge) client library
Documentation
use std::io::Write;

use crate::{
    Result, RustADBError,
    message_devices::{
        adb_message_device::ADBMessageDevice,
        adb_message_transport::ADBMessageTransport,
        adb_transport_message::ADBTransportMessage,
        message_commands::{MessageCommand, MessageSubcommand},
        utils::BinaryEncodable,
    },
};

impl<T: ADBMessageTransport> ADBMessageDevice<T> {
    pub(crate) fn pull<A: AsRef<str>, W: Write>(&mut self, source: A, output: W) -> Result<()> {
        let mut session = self.open_synchronization_session()?;
        let source = source.as_ref();

        let adb_stat_response = session.stat_with_explicit_ids(source)?;

        if adb_stat_response.file_perm == 0 {
            return Err(RustADBError::UnknownResponseType(
                "mode is 0: source file does not exist".to_string(),
            ));
        }

        self.get_transport_mut().write_message_with_timeout(
            ADBTransportMessage::try_new(
                MessageCommand::Okay,
                session.local_id(),
                session.remote_id(),
                &[],
            )?,
            std::time::Duration::from_secs(4),
        )?;

        let recv_buffer = MessageSubcommand::Recv.with_arg(u32::try_from(source.len())?);
        session.send_and_expect_okay(ADBTransportMessage::try_new(
            MessageCommand::Write,
            session.local_id(),
            session.remote_id(),
            &recv_buffer.encode(),
        )?)?;
        session.send_and_expect_okay(ADBTransportMessage::try_new(
            MessageCommand::Write,
            session.local_id(),
            session.remote_id(),
            source.as_bytes(),
        )?)?;

        session.recv_file(output)?;
        self.end_transaction(&mut session)?;
        Ok(())
    }
}