playwright/imp/core/
transport.rs

1use crate::imp::core::*;
2use std::{
3    convert::TryInto,
4    io,
5    io::{Read, Write},
6    process::{ChildStdin, ChildStdout},
7};
8use thiserror::Error;
9
10#[derive(Debug)]
11pub(super) struct Reader {
12    stdout: ChildStdout,
13    length: Option<u32>,
14    buf: Vec<u8>,
15}
16
17#[derive(Debug)]
18pub(super) struct Writer {
19    stdin: ChildStdin,
20}
21
22#[derive(Error, Debug)]
23pub enum TransportError {
24    #[error(transparent)]
25    Serde(#[from] serde_json::error::Error),
26    #[error(transparent)]
27    Io(#[from] io::Error),
28}
29
30impl Reader {
31    const BUFSIZE: usize = 30000;
32
33    pub(super) fn new(stdout: ChildStdout) -> Self {
34        Self {
35            stdout,
36            length: None,
37            buf: Vec::with_capacity(Self::BUFSIZE),
38        }
39    }
40
41    // TODO: heap efficiency
42    pub(super) fn try_read(&mut self) -> Result<Option<Res>, TransportError> {
43        let this = self;
44        {
45            if this.length.is_none() && this.buf.len() >= 4 {
46                let off = this.buf.split_off(4);
47                let bytes: &[u8] = &this.buf;
48                this.length = Some(u32::from_le_bytes(bytes.try_into().unwrap()));
49                this.buf = off;
50            }
51            match this.length.map(|u| u as usize) {
52                None => {}
53                Some(l) if this.buf.len() < l => {}
54                Some(l) => {
55                    let bytes: &[u8] = &this.buf[..l];
56                    let raw_str = unsafe { std::str::from_utf8_unchecked(bytes) };
57                    log::debug!("RECV {}", raw_str);
58                    let msg: Res = match serde_json::from_slice(bytes) {
59                        Ok(m) => m,
60                        Err(e) => {
61                            // Log the raw message when deserialization fails
62                            eprintln!("DESER ERROR: {} for msg: {}", e, raw_str);
63                            return Err(e.into());
64                        }
65                    };
66                    this.length = None;
67                    this.buf = this.buf[l..].to_owned();
68                    return Ok(Some(msg));
69                }
70            }
71        }
72        {
73            let mut buf = [0; Self::BUFSIZE];
74            let n = this.stdout.read(&mut buf)?;
75            this.buf.extend(&buf[..n]);
76        }
77        Ok(None)
78    }
79}
80
81impl Writer {
82    pub(super) fn new(stdin: ChildStdin) -> Self {
83        Self { stdin }
84    }
85
86    pub(super) fn send(&mut self, req: &Req<'_, '_>) -> Result<(), TransportError> {
87        let serialized = serde_json::to_vec(&req)?;
88        let serialized_str = String::from_utf8_lossy(&serialized);
89        log::debug!("SEND {}", serialized_str);
90        let length = serialized.len() as u32;
91        let mut bytes = length.to_le_bytes().to_vec();
92        bytes.extend(serialized);
93        self.stdin.write_all(&bytes)?;
94        Ok(())
95    }
96}