aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azalea/Cargo.toml2
-rw-r--r--azalea/src/lib.rs24
-rw-r--r--azalea/src/swarm/mod.rs52
3 files changed, 47 insertions, 31 deletions
diff --git a/azalea/Cargo.toml b/azalea/Cargo.toml
index 9f493504..ab11ccb3 100644
--- a/azalea/Cargo.toml
+++ b/azalea/Cargo.toml
@@ -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"]
diff --git a/azalea/src/lib.rs b/azalea/src/lib.rs
index 5e412f52..e8a85101 100644
--- a/azalea/src/lib.rs
+++ b/azalea/src/lib.rs
@@ -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()
}
diff --git a/azalea/src/swarm/mod.rs b/azalea/src/swarm/mod.rs
index c79e6685..18bde3f1 100644
--- a/azalea/src/swarm/mod.rs
+++ b/azalea/src/swarm/mod.rs
@@ -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`].
///