1use rkyv::Serialize;
2use rkyv::api::high::HighSerializer;
3use rkyv::ser::allocator::ArenaHandle;
4use rkyv::util::AlignedVec;
5use std::borrow::Cow;
6use std::io;
7use std::io::{ErrorKind, Write};
8use std::sync::LazyLock;
9
10pub mod client;
11pub mod env;
12pub mod server;
13
14#[cfg(windows)]
15pub const NO_AGENT_ERROR_KIND: ErrorKind = ErrorKind::NotFound;
16#[cfg(not(windows))]
17pub const NO_AGENT_ERROR_KIND: ErrorKind = ErrorKind::ConnectionRefused;
18
19const EOT: u8 = 4;
21
22#[macro_export]
23macro_rules! receive {
24 ($typ:ty, $con:ident) => {{
25 let mut buf = Vec::with_capacity(32);
26 std::io::BufRead::read_until(&mut $con, $crate::EOT, &mut buf).and_then(|_| {
27 buf.pop();
28 paste::paste! {
29 let archived =
30 rkyv::access::<[<Archived $typ>], rkyv::rancor::Error>(buf.as_slice())
31 .map_err(io::Error::other)?;
32 rkyv::deserialize::<$typ, rkyv::rancor::Error>(archived)
33 .map_err(io::Error::other)
34 }
35 })
36 }};
37}
38
39fn send<S, C>(request: &S, con: &mut C) -> io::Result<()>
40where
41 S: for<'a> Serialize<HighSerializer<AlignedVec, ArenaHandle<'a>, rkyv::rancor::Error>>,
42 C: Write,
43{
44 let vec = rkyv::to_bytes(request).map_err(io::Error::other)?;
45 con.write_all(vec.as_slice())?;
46 con.write_all([EOT].as_ref())
47}
48
49static SOCKET_NAME: LazyLock<Cow<str>> = LazyLock::new(env::agent_socket_name);