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) .run_system(prefix, elements.collect(), &sys_name)
.await; .await;
if response.0.is_none() { match response {
return; crate::system::Response::Lines(lines) => {
} for line in lines {
context.privmsg(channel, &line)
for line in response.0.unwrap() { }
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, &mut *fact.write().await,
); );
if resp.0.is_none() { match resp {
continue; 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); let $params = $params::retrieve(prefix, arguments, &factory);
)* )*
call_inner(&mut self.f, $($params),*) 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 { pub(crate) trait SystemParam {
type Item<'new>; 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)] #[derive(Clone)]
pub struct Response(pub Option<Vec<String>>); pub enum Response {
Lines(Vec<String>),
Empty,
InvalidArgument,
}
pub trait IntoResponse { pub trait IntoResponse {
fn response(self) -> Response; fn response(self) -> Response;
@ -121,25 +137,25 @@ pub trait IntoResponse {
impl IntoResponse for () { impl IntoResponse for () {
fn response(self) -> Response { fn response(self) -> Response {
Response(None) Response::Empty
} }
} }
impl IntoResponse for String { impl IntoResponse for String {
fn response(self) -> Response { fn response(self) -> Response {
Response(Some(vec![self])) Response::Lines(vec![self])
} }
} }
impl IntoResponse for &str { impl IntoResponse for &str {
fn response(self) -> Response { fn response(self) -> Response {
Response(Some(vec![self.to_owned()])) Response::Lines(vec![self.to_owned()])
} }
} }
impl IntoResponse for Msg { impl IntoResponse for Msg {
fn response(self) -> Response { 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 { fn response(self) -> Response {
match self { match self {
Some(s) => s.response(), Some(s) => s.response(),
None => Response(None), None => Response::Empty,
} }
} }
} }
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(Some( Response::Lines(self.iter().map(|elem| elem.to_string()).collect::<Vec<_>>())
self.iter().map(|elem| elem.to_string()).collect::<Vec<_>>(),
))
} }
} }
@ -180,7 +194,7 @@ 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(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]; type Target = &'a [&'a str];
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@ -118,14 +118,20 @@ impl<'a> Deref for Arguments<'a> {
} }
} }
impl<'a> SystemParam for Arguments<'a> { impl<'a, const N: usize> SystemParam for Arguments<'a, N> {
type Item<'new> = Arguments<'new>; type Item<'new> = Arguments<'new, N>;
fn retrieve<'r>( fn retrieve<'r>(
_prefix: &'r IrcPrefix, _prefix: &'r IrcPrefix,
arguments: &'r [&'r str], arguments: &'r [&'r str],
_factory: &'r Factory, _factory: &'r Factory,
) -> Self::Item<'r> { ) -> Self::Item<'r> {
Arguments(arguments) Arguments(&arguments[..N])
}
fn valid(_prefix: &IrcPrefix,
arguments: &[&str],
_factory: &Factory,) -> bool {
arguments.len() == N
} }
} }