better reponses

This commit is contained in:
wrk 2023-05-31 12:25:37 +02:00
parent 6c1cd8a2c9
commit 2a7d346d52
3 changed files with 111 additions and 46 deletions

View File

@ -128,22 +128,33 @@ impl Irc {
let mut context = self.context.write().await; let mut context = self.context.write().await;
if !context.systems.contains_key(&sys_name) { if !context.systems.contains_key(&sys_name) {
for line in context.run_default_system(prefix, &arguments).await { let resp = context.run_default_system(prefix, &arguments).await;
context.privmsg(channel, &line)
let Response::Data(data) = resp else {
return;
};
for (idx, line) in data.data.iter().enumerate() {
if idx == 0 && data.highlight {
context.privmsg(channel, &format!("{}: {}", prefix.nick, line))
} else {
context.privmsg(channel, &line)
}
} }
return; return;
} }
let response = context.run_system(prefix, &arguments, &sys_name).await; let response = context.run_system(prefix, &arguments, &sys_name).await;
let Response::Data(data) = response else {
let lines = match response { return;
Response::Lines(lines) => lines,
Response::InvalidArgument => context.run_invalid_system(prefix, &arguments).await,
_ => return,
}; };
for line in lines { for (idx, line) in data.data.iter().enumerate() {
context.privmsg(channel, &line) if idx == 0 && data.highlight {
context.privmsg(channel, &format!("{}: {}", prefix.nick, line))
} else {
context.privmsg(channel, &line)
}
} }
} }
} }

View File

@ -271,7 +271,7 @@ impl Context {
pub async fn run_system<'a>( pub async fn run_system<'a>(
&mut self, &mut self,
prefix: &'a IrcPrefix<'a>, prefix: &'a IrcPrefix<'a>,
arguments: &'a[&'a str], arguments: &'a [&'a str],
name: &str, name: &str,
) -> Response { ) -> Response {
let system = self.systems.get_mut(name).unwrap(); let system = self.systems.get_mut(name).unwrap();
@ -281,44 +281,36 @@ impl Context {
pub async fn run_default_system<'a>( pub async fn run_default_system<'a>(
&mut self, &mut self,
prefix: &'a IrcPrefix<'a>, prefix: &'a IrcPrefix<'a>,
arguments: &'a[&'a str], arguments: &'a [&'a str],
) -> Vec<String> { ) -> Response {
if self.default_system.is_none() { if self.invalid_system.is_none() {
return vec![]; return Response::Empty;
} }
if let Response::Lines(lines) = self.default_system.as_mut().unwrap().run( self.default_system.as_mut().unwrap().run(
prefix, prefix,
arguments, arguments,
&mut *self.factory.write().await, &mut *self.factory.write().await,
) { )
lines
} else {
return vec![];
}
} }
pub async fn run_invalid_system<'a>( pub async fn run_invalid_system<'a>(
&mut self, &mut self,
prefix: &'a IrcPrefix<'a>, prefix: &'a IrcPrefix<'a>,
arguments: &'a[&'a str], arguments: &'a [&'a str],
) -> Vec<String> { ) -> Response {
if self.invalid_system.is_none() { if self.invalid_system.is_none() {
return vec![]; return Response::Empty;
} }
if let Response::Lines(lines) = self.invalid_system.as_mut().unwrap().run( self.invalid_system.as_mut().unwrap().run(
prefix, prefix,
arguments, arguments,
&mut *self.factory.write().await, &mut *self.factory.write().await,
) { )
lines
} else {
return vec![];
}
} }
pub async fn run_interval_tasks(&mut self, tx: mpsc::Sender<Vec<String>>) { pub async fn run_interval_tasks(&mut self, tx: mpsc::Sender<Response>) {
for (task_duration, mut task) in std::mem::take(&mut self.interval_tasks) { for (task_duration, mut task) in std::mem::take(&mut self.interval_tasks) {
let fact = self.factory.clone(); let fact = self.factory.clone();
let task_tx = tx.clone(); let task_tx = tx.clone();
@ -334,11 +326,7 @@ impl Context {
&[], &[],
&mut *fact.write().await, &mut *fact.write().await,
); );
match resp { task_tx.send(resp).await.unwrap();
Response::Lines(lines) => task_tx.send(lines).await.unwrap(),
Response::Empty => continue,
Response::InvalidArgument => continue,
}
} }
}); });
} }
@ -554,7 +542,7 @@ impl Irc {
pub async fn run(&mut self) -> std::io::Result<()> { pub async fn run(&mut self) -> std::io::Result<()> {
self.connect().await?; self.connect().await?;
info!("Ready!"); info!("Ready!");
let (tx, mut rx) = mpsc::channel::<Vec<String>>(512); let (tx, mut rx) = mpsc::channel::<Response>(512);
{ {
let mut context = self.context.write().await; let mut context = self.context.write().await;
context.register(); context.register();
@ -586,11 +574,15 @@ impl Irc {
} }
} }
async fn handle_rx(rx: &mut mpsc::Receiver<Vec<String>>, arc_context: &RwLock<Context>) { async fn handle_rx(rx: &mut mpsc::Receiver<Response>, arc_context: &RwLock<Context>) {
while let Some(data) = rx.recv().await { while let Some(response) = rx.recv().await {
let mut context = arc_context.write().await; let mut context = arc_context.write().await;
for line in data { let Response::Data(data) = response else {
continue;
};
for line in data.data {
context.privmsg_all(&line); context.privmsg_all(&line);
} }
} }

View File

@ -125,17 +125,59 @@ pub(crate) trait SystemParam {
} }
} }
#[derive(Clone)] #[derive(Debug)]
pub struct ResponseData {
pub(crate) highlight: bool,
pub(crate) data: Vec<String>,
}
impl Default for ResponseData {
fn default() -> Self {
Self {
highlight: true,
data: Default::default(),
}
}
}
#[derive(Debug)]
pub enum Response { pub enum Response {
Lines(Vec<String>), Data(ResponseData),
Empty, Empty,
InvalidArgument, InvalidArgument,
} }
impl Into<Response> for ResponseData {
fn into(self) -> Response {
Response::Data(self)
}
}
pub trait IntoResponse { pub trait IntoResponse {
fn response(self) -> Response; fn response(self) -> Response;
} }
impl IntoResponse for ResponseData {
fn response(self) -> Response {
self.into()
}
}
impl<T: IntoResponse> IntoResponse for (bool, T) {
fn response(self) -> Response {
let resp = self.1.response();
match resp {
Response::Data(data) => ResponseData {
highlight: self.0,
data: data.data,
}
.into(),
_ => resp,
}
}
}
impl IntoResponse for () { impl IntoResponse for () {
fn response(self) -> Response { fn response(self) -> Response {
Response::Empty Response::Empty
@ -144,19 +186,31 @@ impl IntoResponse for () {
impl IntoResponse for String { impl IntoResponse for String {
fn response(self) -> Response { fn response(self) -> Response {
Response::Lines(vec![self]) ResponseData {
data: vec![self],
..Default::default()
}
.into()
} }
} }
impl IntoResponse for &str { impl IntoResponse for &str {
fn response(self) -> Response { fn response(self) -> Response {
Response::Lines(vec![self.to_owned()]) ResponseData {
data: vec![self.to_owned()],
..Default::default()
}
.into()
} }
} }
impl IntoResponse for Msg { impl IntoResponse for Msg {
fn response(self) -> Response { fn response(self) -> Response {
Response::Lines(vec![self.to_string()]) ResponseData {
data: vec![self.to_string()],
..Default::default()
}
.into()
} }
} }
@ -187,7 +241,11 @@ where
impl<T: std::fmt::Display> IntoResponse for Vec<T> { impl<T: std::fmt::Display> IntoResponse for Vec<T> {
fn response(self) -> Response { fn response(self) -> Response {
Response::Lines(self.iter().map(|elem| elem.to_string()).collect::<Vec<_>>()) ResponseData {
data: self.iter().map(|elem| elem.to_string()).collect::<Vec<_>>(),
..Default::default()
}
.into()
} }
} }
@ -195,7 +253,11 @@ macro_rules! impl_into_response_for_primitives {
($param:ident) => { ($param:ident) => {
impl IntoResponse for $param { impl IntoResponse for $param {
fn response(self) -> Response { fn response(self) -> Response {
Response::Lines(vec![self.to_string()]) ResponseData {
data: vec![self.to_string()],
..Default::default()
}
.into()
} }
} }
}; };