asdf_overlay_common/ipc.rs
1//! Common types and utilities for IPC communication between the overlay client and server.
2
3use asdf_overlay_event::OverlayEvent;
4use bincode::{Decode, Encode};
5use tokio::io::{self, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
6
7use crate::request::Request;
8
9/// Creates a unique IPC address for the given process ID and module handle.
10/// Because there can be multiple overlays in the same process, we need to distinguish with the module handle.
11///
12/// This function is used internally by `asdf-overlay-client` and `asdf-overlay-dll` crates to establish IPC communication.
13pub fn create_ipc_addr(pid: u32, module_handle: u32) -> String {
14 format!("\\\\.\\pipe\\asdf-overlay-{pid}-{module_handle}")
15}
16
17/// Describes a request sent from the client to the server.
18#[derive(Encode, Decode)]
19pub struct ClientRequest {
20 /// Unique identifier for matching responses.
21 pub id: u32,
22
23 /// The actual request data.
24 pub req: Request,
25}
26
27/// Describes a response sent from server to client.
28#[derive(Encode, Decode)]
29pub struct ServerResponse {
30 /// Unique identifier matching the request.
31 pub id: u32,
32
33 /// The raw response data.
34 pub data: Vec<u8>,
35}
36
37/// Describes a packet sent from server to client.
38#[derive(Encode, Decode)]
39pub enum ServerToClientPacket {
40 /// The packet is a response to a specific request.
41 Response(ServerResponse),
42
43 /// The packet is an event notification.
44 Event(OverlayEvent),
45}
46
47/// Describes a frame header for IPC communication.
48#[derive(Debug, Clone, Copy)]
49pub struct Frame {
50 /// Size of the frame body in bytes.
51 pub size: u32,
52}
53
54impl Frame {
55 /// Reads a frame header from the given async reader.
56 pub async fn read(mut r: impl AsyncRead + Unpin) -> io::Result<Self> {
57 Ok(Self {
58 size: r.read_u32().await?,
59 })
60 }
61
62 /// Writes the frame header to the given async writer.
63 pub async fn write(self, mut w: impl AsyncWrite + Unpin) -> io::Result<()> {
64 w.write_u32(self.size).await?;
65 Ok(())
66 }
67}