1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

lift requirement on anyhow for handler function

This commit is contained in:
mat 2024-12-23 10:34:44 +00:00
parent 1609b90a93
commit 8772661772
3 changed files with 47 additions and 31 deletions

View file

@ -12,7 +12,6 @@ pre-release-replacements = [
]
[dependencies]
anyhow = { workspace = true }
#async-trait = { workspace = true }
azalea-auth = { version = "0.11.0", path = "../azalea-auth" }
azalea-block = { version = "0.11.0", path = "../azalea-block" }
@ -50,6 +49,7 @@ uuid = { workspace = true }
criterion = { workspace = true }
parking_lot = { workspace = true, features = ["deadlock_detection"] }
rand = { workspace = true }
anyhow = { workspace = true }
[features]
default = ["log", "serde"]

View file

@ -44,8 +44,7 @@ use protocol::{resolver::ResolverError, ServerAddress};
use swarm::SwarmBuilder;
use thiserror::Error;
pub type BoxHandleFn<S> =
Box<dyn Fn(Client, azalea_client::Event, S) -> BoxFuture<'static, Result<(), anyhow::Error>>>;
pub type BoxHandleFn<S, R> = Box<dyn Fn(Client, azalea_client::Event, S) -> BoxFuture<'static, R>>;
pub type HandleFn<S, Fut> = fn(Client, azalea_client::Event, S) -> Fut;
#[derive(Error, Debug)]
@ -74,19 +73,20 @@ pub enum StartError {
/// # Ok(())
/// # }
/// ```
pub struct ClientBuilder<S>
pub struct ClientBuilder<S, R>
where
S: Default + Send + Sync + Clone + Component + 'static,
R: Send + 'static,
{
/// Internally, ClientBuilder is just a wrapper over SwarmBuilder since it's
/// technically just a subset of it so we can avoid duplicating code this
/// way.
swarm: SwarmBuilder<S, swarm::NoSwarmState>,
swarm: SwarmBuilder<S, swarm::NoSwarmState, R, ()>,
}
impl ClientBuilder<NoState> {
impl ClientBuilder<NoState, ()> {
/// Start building a client that can join the world.
#[must_use]
pub fn new() -> ClientBuilder<NoState> {
pub fn new() -> Self {
Self::new_without_plugins()
.add_plugins(DefaultPlugins)
.add_plugins(DefaultBotPlugins)
@ -116,7 +116,7 @@ impl ClientBuilder<NoState> {
/// # }
/// ```
#[must_use]
pub fn new_without_plugins() -> ClientBuilder<NoState> {
pub fn new_without_plugins() -> Self {
Self {
swarm: SwarmBuilder::new_without_plugins(),
}
@ -139,19 +139,21 @@ impl ClientBuilder<NoState> {
/// }
/// ```
#[must_use]
pub fn set_handler<S, Fut>(self, handler: HandleFn<S, Fut>) -> ClientBuilder<S>
pub fn set_handler<S, Fut, R>(self, handler: HandleFn<S, Fut>) -> ClientBuilder<S, R>
where
S: Default + Send + Sync + Clone + Component + 'static,
Fut: Future<Output = Result<(), anyhow::Error>> + Send + 'static,
Fut: Future<Output = R> + Send + 'static,
R: Send + 'static,
{
ClientBuilder {
swarm: self.swarm.set_handler(handler),
}
}
}
impl<S> ClientBuilder<S>
impl<S, R> ClientBuilder<S, R>
where
S: Default + Send + Sync + Clone + Component + 'static,
R: Send + 'static,
{
/// Set the client state instead of initializing defaults.
#[must_use]
@ -206,7 +208,7 @@ where
self.swarm.start_with_default_opts(address, opts).await
}
}
impl Default for ClientBuilder<NoState> {
impl Default for ClientBuilder<NoState, ()> {
fn default() -> Self {
Self::new()
}

View file

@ -47,7 +47,15 @@ pub struct Swarm {
}
/// Create a new [`Swarm`].
pub struct SwarmBuilder<S, SS>
///
/// The generics of this struct stand for the following:
/// - S: State
/// - SS: Swarm State
/// - R: Return type of the handler
/// - SR: Return type of the swarm handler
///
/// You shouldn't have to manually set them though, they'll be inferred for you.
pub struct SwarmBuilder<S, SS, R, SR>
where
S: Send + Sync + Clone + Component + 'static,
SS: Default + Send + Sync + Clone + Resource + 'static,
@ -61,10 +69,10 @@ where
/// The state for the overall swarm.
pub(crate) swarm_state: SS,
/// The function that's called every time a bot receives an [`Event`].
pub(crate) handler: Option<BoxHandleFn<S>>,
pub(crate) handler: Option<BoxHandleFn<S, R>>,
/// The function that's called every time the swarm receives a
/// [`SwarmEvent`].
pub(crate) swarm_handler: Option<BoxSwarmHandleFn<SS>>,
pub(crate) swarm_handler: Option<BoxSwarmHandleFn<SS, SR>>,
/// How long we should wait between each bot joining the server. Set to
/// None to have every bot connect at the same time. None is different than
@ -72,10 +80,10 @@ where
/// the previous one to be ready.
pub(crate) join_delay: Option<std::time::Duration>,
}
impl SwarmBuilder<NoState, NoSwarmState> {
impl SwarmBuilder<NoState, NoSwarmState, (), ()> {
/// Start creating the swarm.
#[must_use]
pub fn new() -> SwarmBuilder<NoState, NoSwarmState> {
pub fn new() -> Self {
Self::new_without_plugins()
.add_plugins(DefaultPlugins)
.add_plugins(DefaultBotPlugins)
@ -108,7 +116,7 @@ impl SwarmBuilder<NoState, NoSwarmState> {
/// # }
/// ```
#[must_use]
pub fn new_without_plugins() -> SwarmBuilder<NoState, NoSwarmState> {
pub fn new_without_plugins() -> Self {
SwarmBuilder {
// we create the app here so plugins can add onto it.
// the schedules won't run until [`Self::start`] is called.
@ -123,7 +131,7 @@ impl SwarmBuilder<NoState, NoSwarmState> {
}
}
impl<SS> SwarmBuilder<NoState, SS>
impl<SS, R, SR> SwarmBuilder<NoState, SS, R, SR>
where
SS: Default + Send + Sync + Clone + Resource + 'static,
{
@ -154,9 +162,9 @@ where
/// # }
/// ```
#[must_use]
pub fn set_handler<S, Fut>(self, handler: HandleFn<S, Fut>) -> SwarmBuilder<S, SS>
pub fn set_handler<S, Fut, Ret>(self, handler: HandleFn<S, Fut>) -> SwarmBuilder<S, SS, Ret, SR>
where
Fut: Future<Output = Result<(), anyhow::Error>> + Send + 'static,
Fut: Future<Output = Ret> + Send + 'static,
S: Send + Sync + Clone + Component + Default + 'static,
{
SwarmBuilder {
@ -171,7 +179,7 @@ where
}
}
impl<S> SwarmBuilder<S, NoSwarmState>
impl<S, R, SR> SwarmBuilder<S, NoSwarmState, R, SR>
where
S: Send + Sync + Clone + Component + 'static,
{
@ -203,10 +211,13 @@ where
/// }
/// ```
#[must_use]
pub fn set_swarm_handler<SS, Fut>(self, handler: SwarmHandleFn<SS, Fut>) -> SwarmBuilder<S, SS>
pub fn set_swarm_handler<SS, Fut, SRet>(
self,
handler: SwarmHandleFn<SS, Fut>,
) -> SwarmBuilder<S, SS, R, SRet>
where
SS: Default + Send + Sync + Clone + Resource + 'static,
Fut: Future<Output = Result<(), anyhow::Error>> + Send + 'static,
Fut: Future<Output = SRet> + Send + 'static,
{
SwarmBuilder {
handler: self.handler,
@ -222,10 +233,12 @@ where
}
}
impl<S, SS> SwarmBuilder<S, SS>
impl<S, SS, R, SR> SwarmBuilder<S, SS, R, SR>
where
S: Send + Sync + Clone + Component + 'static,
SS: Default + Send + Sync + Clone + Resource + 'static,
R: Send + 'static,
SR: Send + 'static,
{
/// Add a vec of [`Account`]s to the swarm.
///
@ -354,9 +367,10 @@ where
};
let address: ServerAddress = default_join_opts.custom_address.clone().unwrap_or(address);
let resolved_address: SocketAddr = match default_join_opts.custom_resolved_address {
Some(resolved_address) => resolved_address,
None => resolver::resolve_address(&address).await?,
let resolved_address = if let Some(a) = default_join_opts.custom_resolved_address {
a
} else {
resolver::resolve_address(&address).await?
};
let instance_container = Arc::new(RwLock::new(InstanceContainer::default()));
@ -476,7 +490,7 @@ where
}
}
impl Default for SwarmBuilder<NoState, NoSwarmState> {
impl Default for SwarmBuilder<NoState, NoSwarmState, (), ()> {
fn default() -> Self {
Self::new()
}
@ -500,8 +514,8 @@ pub enum SwarmEvent {
}
pub type SwarmHandleFn<SS, Fut> = fn(Swarm, SwarmEvent, SS) -> Fut;
pub type BoxSwarmHandleFn<SS> =
Box<dyn Fn(Swarm, SwarmEvent, SS) -> BoxFuture<'static, Result<(), anyhow::Error>> + Send>;
pub type BoxSwarmHandleFn<SS, R> =
Box<dyn Fn(Swarm, SwarmEvent, SS) -> BoxFuture<'static, R> + Send>;
/// Make a bot [`Swarm`].
///