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;
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;
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;
}
let response = context.run_system(prefix, &arguments, &sys_name).await;
let lines = match response {
Response::Lines(lines) => lines,
Response::InvalidArgument => context.run_invalid_system(prefix, &arguments).await,
_ => return,
let Response::Data(data) = response else {
return;
};
for line in lines {
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)
}
}
}
}

View File

@ -282,43 +282,35 @@ impl Context {
&mut self,
prefix: &'a IrcPrefix<'a>,
arguments: &'a [&'a str],
) -> Vec<String> {
if self.default_system.is_none() {
return vec![];
) -> Response {
if self.invalid_system.is_none() {
return Response::Empty;
}
if let Response::Lines(lines) = self.default_system.as_mut().unwrap().run(
self.default_system.as_mut().unwrap().run(
prefix,
arguments,
&mut *self.factory.write().await,
) {
lines
} else {
return vec![];
}
)
}
pub async fn run_invalid_system<'a>(
&mut self,
prefix: &'a IrcPrefix<'a>,
arguments: &'a [&'a str],
) -> Vec<String> {
) -> Response {
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,
arguments,
&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) {
let fact = self.factory.clone();
let task_tx = tx.clone();
@ -334,11 +326,7 @@ impl Context {
&[],
&mut *fact.write().await,
);
match resp {
Response::Lines(lines) => task_tx.send(lines).await.unwrap(),
Response::Empty => continue,
Response::InvalidArgument => continue,
}
task_tx.send(resp).await.unwrap();
}
});
}
@ -554,7 +542,7 @@ impl Irc {
pub async fn run(&mut self) -> std::io::Result<()> {
self.connect().await?;
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;
context.register();
@ -586,11 +574,15 @@ impl Irc {
}
}
async fn handle_rx(rx: &mut mpsc::Receiver<Vec<String>>, arc_context: &RwLock<Context>) {
while let Some(data) = rx.recv().await {
async fn handle_rx(rx: &mut mpsc::Receiver<Response>, arc_context: &RwLock<Context>) {
while let Some(response) = rx.recv().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);
}
}

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 {
Lines(Vec<String>),
Data(ResponseData),
Empty,
InvalidArgument,
}
impl Into<Response> for ResponseData {
fn into(self) -> Response {
Response::Data(self)
}
}
pub trait IntoResponse {
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 () {
fn response(self) -> Response {
Response::Empty
@ -144,19 +186,31 @@ impl IntoResponse for () {
impl IntoResponse for String {
fn response(self) -> Response {
Response::Lines(vec![self])
ResponseData {
data: vec![self],
..Default::default()
}
.into()
}
}
impl IntoResponse for &str {
fn response(self) -> Response {
Response::Lines(vec![self.to_owned()])
ResponseData {
data: vec![self.to_owned()],
..Default::default()
}
.into()
}
}
impl IntoResponse for Msg {
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> {
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) => {
impl IntoResponse for $param {
fn response(self) -> Response {
Response::Lines(vec![self.to_string()])
ResponseData {
data: vec![self.to_string()],
..Default::default()
}
.into()
}
}
};