Better response + argument len managed at lib level

This commit is contained in:
wrk 2023-05-31 10:16:35 +02:00
parent 0e901d67c3
commit 91efdbe29f
4 changed files with 48 additions and 25 deletions

View File

@ -132,12 +132,14 @@ impl Irc {
.run_system(prefix, elements.collect(), &sys_name)
.await;
if response.0.is_none() {
return;
}
for line in response.0.unwrap() {
context.privmsg(channel, &line)
match response {
crate::system::Response::Lines(lines) => {
for line in lines {
context.privmsg(channel, &line)
}
}
crate::system::Response::Empty => return,
crate::system::Response::InvalidArgument => return,
}
}
}

View File

@ -321,10 +321,11 @@ impl Context {
&[],
&mut *fact.write().await,
);
if resp.0.is_none() {
continue;
match resp {
Response::Lines(lines) => task_tx.send(lines).await.unwrap(),
Response::Empty => continue,
Response::InvalidArgument => continue,
}
task_tx.send(resp.0.unwrap()).await.unwrap()
}
});
}

View File

@ -38,7 +38,12 @@ macro_rules! impl_system {
}
$(
if !$params::valid(prefix, arguments, &factory) {
return Response::InvalidArgument;
}
let $params = $params::retrieve(prefix, arguments, &factory);
)*
call_inner(&mut self.f, $($params),*)
@ -109,11 +114,22 @@ pub(crate) type StoredSystem = Box<dyn for<'a> System + Send + Sync>;
pub(crate) trait SystemParam {
type Item<'new>;
fn retrieve<'r>(prefix: &'r IrcPrefix, arguments: &'r[&'r str], factory: &'r Factory) -> Self::Item<'r>;
fn retrieve<'r>(
prefix: &'r IrcPrefix,
arguments: &'r [&'r str],
factory: &'r Factory,
) -> Self::Item<'r>;
fn valid(prefix: &IrcPrefix, arguments: &[&str], factory: &Factory) -> bool {
true
}
}
#[derive(Clone)]
pub struct Response(pub Option<Vec<String>>);
pub enum Response {
Lines(Vec<String>),
Empty,
InvalidArgument,
}
pub trait IntoResponse {
fn response(self) -> Response;
@ -121,25 +137,25 @@ pub trait IntoResponse {
impl IntoResponse for () {
fn response(self) -> Response {
Response(None)
Response::Empty
}
}
impl IntoResponse for String {
fn response(self) -> Response {
Response(Some(vec![self]))
Response::Lines(vec![self])
}
}
impl IntoResponse for &str {
fn response(self) -> Response {
Response(Some(vec![self.to_owned()]))
Response::Lines(vec![self.to_owned()])
}
}
impl IntoResponse for Msg {
fn response(self) -> Response {
Response(Some(vec![self.to_string()]))
Response::Lines(vec![self.to_string()])
}
}
@ -163,16 +179,14 @@ where
fn response(self) -> Response {
match self {
Some(s) => s.response(),
None => Response(None),
None => Response::Empty,
}
}
}
impl<T: std::fmt::Display> IntoResponse for Vec<T> {
fn response(self) -> Response {
Response(Some(
self.iter().map(|elem| elem.to_string()).collect::<Vec<_>>(),
))
Response::Lines(self.iter().map(|elem| elem.to_string()).collect::<Vec<_>>())
}
}
@ -180,7 +194,7 @@ macro_rules! impl_into_response_for_primitives {
($param:ident) => {
impl IntoResponse for $param {
fn response(self) -> Response {
Response(Some(vec![self.to_string()]))
Response::Lines(vec![self.to_string()])
}
}
};

View File

@ -108,9 +108,9 @@ impl<'a> SystemParam for IrcPrefix<'a> {
}
}
pub struct Arguments<'a>(&'a [&'a str]);
pub struct Arguments<'a, const N: usize>(&'a [&'a str]);
impl<'a> Deref for Arguments<'a> {
impl<'a, const N: usize> Deref for Arguments<'a, N> {
type Target = &'a [&'a str];
fn deref(&self) -> &Self::Target {
@ -118,14 +118,20 @@ impl<'a> Deref for Arguments<'a> {
}
}
impl<'a> SystemParam for Arguments<'a> {
type Item<'new> = Arguments<'new>;
impl<'a, const N: usize> SystemParam for Arguments<'a, N> {
type Item<'new> = Arguments<'new, N>;
fn retrieve<'r>(
_prefix: &'r IrcPrefix,
arguments: &'r [&'r str],
_factory: &'r Factory,
) -> Self::Item<'r> {
Arguments(arguments)
Arguments(&arguments[..N])
}
fn valid(_prefix: &IrcPrefix,
arguments: &[&str],
_factory: &Factory,) -> bool {
arguments.len() == N
}
}