ircie/src/system_params.rs

225 lines
4.9 KiB
Rust
Raw Normal View History

2023-05-29 07:11:41 -07:00
use std::{
any::{Any, TypeId},
collections::HashMap,
ops::{Deref, DerefMut},
};
2023-06-08 17:02:16 -07:00
use crate::{factory::Factory, system::SystemParam, IrcContext, IrcPrefix};
2023-05-29 07:11:41 -07:00
#[derive(Debug)]
pub struct Res<'a, T: 'static> {
value: &'a T,
}
impl<'a, T: 'static> Deref for Res<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.value
}
}
impl<'a, T: 'static> AsRef<T> for Res<'a, T> {
fn as_ref(&self) -> &T {
self.value
}
}
impl<'res, T: 'static> SystemParam for Res<'res, T> {
type Item<'new> = Res<'new, T>;
2023-05-30 14:56:59 -07:00
fn retrieve<'r>(
_prefix: &'r IrcPrefix,
2023-06-08 17:02:16 -07:00
_channel: &str,
2023-05-30 14:56:59 -07:00
_arguments: &'r [&'r str],
2023-06-08 17:02:16 -07:00
_context: &'r IrcContext,
2023-05-30 14:56:59 -07:00
factory: &'r Factory,
) -> Self::Item<'r> {
2023-05-29 07:11:41 -07:00
Res {
value: &factory
.resources
.get(&TypeId::of::<T>())
.unwrap()
.downcast_ref()
.unwrap(),
}
}
}
pub struct ResMut<'a, T: 'static> {
value: &'a mut T,
}
impl<'a, T: 'static> Deref for ResMut<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.value
}
}
impl<'a, T: 'static> DerefMut for ResMut<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.value
}
}
impl<'a, T: 'static> AsRef<T> for ResMut<'a, T> {
fn as_ref(&self) -> &T {
self.value
}
}
impl<'a, T: 'static> AsMut<T> for ResMut<'a, T> {
fn as_mut(&mut self) -> &mut T {
&mut self.value
}
}
impl<'res, T: 'static> SystemParam for ResMut<'res, T> {
type Item<'new> = ResMut<'new, T>;
2023-05-30 14:56:59 -07:00
fn retrieve<'r>(
_prefix: &'r IrcPrefix,
2023-06-08 17:02:16 -07:00
_channel: &str,
2023-05-30 14:56:59 -07:00
_arguments: &'r [&'r str],
2023-06-08 17:02:16 -07:00
_context: &'r IrcContext,
2023-05-30 14:56:59 -07:00
factory: &'r Factory,
) -> Self::Item<'r> {
let const_ptr = &factory.resources as *const HashMap<TypeId, Box<dyn Any + Send + Sync>>;
2023-05-29 07:11:41 -07:00
let mut_ptr = const_ptr as *mut HashMap<TypeId, Box<dyn Any>>;
let res_mut = unsafe { &mut *mut_ptr };
ResMut {
value: res_mut
.get_mut(&TypeId::of::<T>())
.unwrap()
.downcast_mut()
.unwrap(),
}
}
}
impl<'a> SystemParam for IrcPrefix<'a> {
type Item<'new> = IrcPrefix<'new>;
2023-05-30 14:56:59 -07:00
fn retrieve<'r>(
prefix: &'r IrcPrefix,
2023-06-08 17:02:16 -07:00
_channel: &str,
2023-05-30 14:56:59 -07:00
_arguments: &'r [&'r str],
2023-06-08 17:02:16 -07:00
_context: &'r IrcContext,
2023-05-30 14:56:59 -07:00
_factory: &'r Factory,
) -> Self::Item<'r> {
2023-05-29 07:11:41 -07:00
prefix.clone()
}
}
2023-05-30 14:56:59 -07:00
2023-06-08 17:02:16 -07:00
pub struct Channel<'a>(&'a str);
impl<'a> Deref for Channel<'a> {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> SystemParam for Channel<'a> {
type Item<'new> = Channel<'new>;
fn retrieve<'r>(
_prefix: &'r IrcPrefix,
channel: &'r str,
_arguments: &'r [&'r str],
_context: &'r IrcContext,
_factory: &'r Factory,
) -> Self::Item<'r> {
Channel(channel)
}
}
2023-06-08 18:36:07 -07:00
#[derive(Debug)]
2023-06-01 15:20:46 -07:00
pub struct AnyArguments<'a>(&'a [&'a str]);
impl<'a> Deref for AnyArguments<'a> {
type Target = &'a [&'a str];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> SystemParam for AnyArguments<'a> {
type Item<'new> = AnyArguments<'new>;
fn retrieve<'r>(
_prefix: &'r IrcPrefix,
2023-06-08 17:02:16 -07:00
_channel: &str,
2023-06-01 15:20:46 -07:00
arguments: &'r [&'r str],
2023-06-08 17:02:16 -07:00
_context: &'r IrcContext,
2023-06-01 15:20:46 -07:00
_factory: &'r Factory,
) -> Self::Item<'r> {
AnyArguments(&arguments)
}
}
pub struct Arguments<'a, const N: usize>(&'a [&'a str]);
2023-05-30 14:56:59 -07:00
impl<'a, const N: usize> Deref for Arguments<'a, N> {
2023-05-30 14:56:59 -07:00
type Target = &'a [&'a str];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a, const N: usize> SystemParam for Arguments<'a, N> {
type Item<'new> = Arguments<'new, N>;
2023-05-30 14:56:59 -07:00
fn retrieve<'r>(
_prefix: &'r IrcPrefix,
2023-06-08 17:02:16 -07:00
_channel: &str,
2023-05-30 14:56:59 -07:00
arguments: &'r [&'r str],
2023-06-08 17:02:16 -07:00
_context: &'r IrcContext,
2023-05-30 14:56:59 -07:00
_factory: &'r Factory,
) -> Self::Item<'r> {
Arguments(&arguments[..N])
}
2023-05-31 01:17:39 -07:00
fn valid(_prefix: &IrcPrefix, arguments: &[&str], _factory: &Factory) -> bool {
arguments.len() == N
2023-05-30 14:56:59 -07:00
}
}
2023-06-08 17:02:16 -07:00
pub struct Context<'a>(&'a mut IrcContext);
impl<'a> Deref for Context<'a> {
type Target = IrcContext;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> DerefMut for Context<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<'a> SystemParam for Context<'a> {
type Item<'new> = Context<'new>;
fn retrieve<'r>(
_prefix: &'r IrcPrefix,
_channel: &str,
_arguments: &'r [&'r str],
context: &'r IrcContext,
_factory: &'r Factory,
) -> Self::Item<'r> {
let const_ptr = context as *const IrcContext;
let mut_ptr = const_ptr as *mut IrcContext;
let ctx_mut = unsafe { &mut *mut_ptr };
Context(ctx_mut)
}
}