68 lines
1.7 KiB
Rust
68 lines
1.7 KiB
Rust
|
use anyhow::Context;
|
||
|
use bytes::Bytes;
|
||
|
use thiserror::Error;
|
||
|
use tokio_stream::StreamExt;
|
||
|
|
||
|
mod exec;
|
||
|
mod terminal;
|
||
|
|
||
|
#[derive(Debug, Error)]
|
||
|
enum ServiceError {
|
||
|
#[error("received an invalid body format for a valid message")]
|
||
|
BodyFormatError,
|
||
|
}
|
||
|
|
||
|
struct Ctx<T> {
|
||
|
body: T,
|
||
|
}
|
||
|
|
||
|
impl<T> Ctx<T>
|
||
|
where
|
||
|
T: TryFrom<Bytes>,
|
||
|
{
|
||
|
fn with_body(client: crate::messaging::Client, body: Bytes) -> Result<Self, ServiceError> {
|
||
|
Ok(Self {
|
||
|
body: body
|
||
|
.try_into()
|
||
|
.map_err(|_err| ServiceError::BodyFormatError)?,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async fn route_message(
|
||
|
client: crate::messaging::Client,
|
||
|
message: crate::messaging::Message,
|
||
|
) -> Result<(), ServiceError> {
|
||
|
match message.subject() {
|
||
|
crate::messaging::Subject::Health => {}
|
||
|
crate::messaging::Subject::Exec => {
|
||
|
let ctx = Ctx::with_body(client, message.body())?;
|
||
|
let _ = self::exec::exec(ctx).await;
|
||
|
}
|
||
|
crate::messaging::Subject::OpenTerminal => {
|
||
|
let ctx = Ctx::with_body(client, message.body())?;
|
||
|
let _ = self::terminal::open_terminal(ctx).await;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
pub async fn init_services(client: crate::messaging::Client) -> anyhow::Result<()> {
|
||
|
let mut message_stream = client
|
||
|
.subscribe()
|
||
|
.await
|
||
|
.context("could not initialize services system")?;
|
||
|
|
||
|
tokio::spawn(async move {
|
||
|
while let Some(message) = message_stream.next().await {
|
||
|
// TODO: How do i handle this error?
|
||
|
if let Err(err) = route_message(client.clone(), message).await {
|
||
|
tracing::warn!("{}", err);
|
||
|
};
|
||
|
}
|
||
|
});
|
||
|
|
||
|
Ok(())
|
||
|
}
|