Compare commits

..

No commits in common. "fe8106d2a1dd49ba05c9a41dbb156d1e8cf1d7cc" and "8e25f401a5c83157daa4f12946a2ea6322783163" have entirely different histories.

7 changed files with 29 additions and 58 deletions

View File

@ -40,19 +40,10 @@ impl GatewayHandle {
.unwrap();
}
/// Recursively observes a [`Shared`] object, by making sure all [`Composite `] fields within
/// that object and its children are being watched.
///
/// Observing means, that if new information arrives about the observed object or its children,
/// the object automatically gets updated, without you needing to request new information about
/// the object in question from the API, which is expensive and can lead to rate limiting.
///
/// The [`Shared`] object returned by this method points to a different object than the one
/// being supplied as a &self function argument.
pub async fn observe<T: Updateable + Clone + Debug + Composite<T>>(
&self,
object: Shared<T>,
) -> Shared<T> {
object: Arc<RwLock<T>>,
) -> Arc<RwLock<T>> {
let mut store = self.store.lock().await;
let id = object.read().unwrap().id();
if let Some(channel) = store.get(&id) {
@ -93,7 +84,7 @@ impl GatewayHandle {
/// with all of its observable fields being observed.
pub async fn observe_and_into_inner<T: Updateable + Clone + Debug + Composite<T>>(
&self,
object: Shared<T>,
object: Arc<RwLock<T>>,
) -> T {
let channel = self.observe(object.clone()).await;
let object = channel.read().unwrap().clone();

View File

@ -122,11 +122,3 @@ impl<T: WebSocketEvent> GatewayEvent<T> {
}
}
}
/// A type alias for [`Arc<RwLock<T>>`], used to make the public facing API concerned with
/// Composite structs more ergonomic.
/// ## Note
///
/// While `T` does not have to implement `Composite` to be used with `Shared`,
/// the primary use of `Shared` is with types that implement `Composite`.
pub type Shared<T> = Arc<RwLock<T>>;

View File

@ -23,8 +23,6 @@ pub use user_settings::*;
pub use voice_state::*;
pub use webhook::*;
use crate::gateway::Shared;
#[cfg(feature = "client")]
use crate::gateway::Updateable;
@ -71,9 +69,9 @@ pub trait Composite<T: Updateable + Clone + Debug> {
async fn watch_whole(self, gateway: &GatewayHandle) -> Self;
async fn option_observe_fn(
value: Option<Shared<T>>,
value: Option<Arc<RwLock<T>>>,
gateway: &GatewayHandle,
) -> Option<Shared<T>>
) -> Option<Arc<RwLock<T>>>
where
T: Composite<T> + Debug,
{
@ -86,9 +84,9 @@ pub trait Composite<T: Updateable + Clone + Debug> {
}
async fn option_vec_observe_fn(
value: Option<Vec<Shared<T>>>,
value: Option<Vec<Arc<RwLock<T>>>>,
gateway: &GatewayHandle,
) -> Option<Vec<Shared<T>>>
) -> Option<Vec<Arc<RwLock<T>>>>
where
T: Composite<T>,
{
@ -103,14 +101,17 @@ pub trait Composite<T: Updateable + Clone + Debug> {
}
}
async fn value_observe_fn(value: Shared<T>, gateway: &GatewayHandle) -> Shared<T>
async fn value_observe_fn(value: Arc<RwLock<T>>, gateway: &GatewayHandle) -> Arc<RwLock<T>>
where
T: Composite<T>,
{
gateway.observe(value).await
}
async fn vec_observe_fn(value: Vec<Shared<T>>, gateway: &GatewayHandle) -> Vec<Shared<T>>
async fn vec_observe_fn(
value: Vec<Arc<RwLock<T>>>,
gateway: &GatewayHandle,
) -> Vec<Arc<RwLock<T>>>
where
T: Composite<T>,
{
@ -121,19 +122,3 @@ pub trait Composite<T: Updateable + Clone + Debug> {
vec
}
}
pub trait IntoShared {
/// Uses [`Shared`] to provide an ergonomic alternative to `Arc::new(RwLock::new(obj))`.
///
/// [`Shared<Self>`] can then be observed using the [`Gateway`], turning the underlying
/// `dyn Composite<Self>` into a self-updating struct, which is a tracked variant of a chorus
/// entity struct, updating its' held information when new information concerning itself arrives
/// over the [`Gateway`] connection, reducing the need for expensive network-API calls.
fn into_shared(self) -> Shared<Self>;
}
impl<T: Sized> IntoShared for T {
fn into_shared(self) -> Shared<Self> {
Arc::new(RwLock::new(self))
}
}

View File

@ -1,5 +1,6 @@
use chorus::gateway::{Gateway, Shared};
use chorus::types::IntoShared;
use std::sync::{Arc, RwLock};
use chorus::gateway::Gateway;
use chorus::{
instance::{ChorusUser, Instance},
types::{
@ -15,9 +16,9 @@ pub(crate) struct TestBundle {
pub urls: UrlBundle,
pub user: ChorusUser,
pub instance: Instance,
pub guild: Shared<Guild>,
pub role: Shared<RoleObject>,
pub channel: Shared<Channel>,
pub guild: Arc<RwLock<Guild>>,
pub role: Arc<RwLock<RoleObject>>,
pub channel: Arc<RwLock<Channel>>,
}
#[allow(unused)]
@ -118,9 +119,9 @@ pub(crate) async fn setup() -> TestBundle {
urls,
user,
instance,
guild: guild.into_shared(),
role: role.into_shared(),
channel: channel.into_shared(),
guild: Arc::new(RwLock::new(guild)),
role: Arc::new(RwLock::new(role)),
channel: Arc::new(RwLock::new(channel)),
}
}

View File

@ -1,8 +1,10 @@
mod common;
use std::sync::{Arc, RwLock};
use chorus::errors::GatewayError;
use chorus::gateway::*;
use chorus::types::{self, ChannelModifySchema, IntoShared, RoleCreateModifySchema, RoleObject};
use chorus::types::{self, ChannelModifySchema, RoleCreateModifySchema, RoleObject};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg(target_arch = "wasm32")]
@ -98,7 +100,7 @@ async fn test_recursive_self_updating_structs() {
bundle
.user
.gateway
.observe(role.clone().into_shared())
.observe(Arc::new(RwLock::new(role.clone())))
.await;
// Update Guild and check for Guild
let inner_guild = guild.read().unwrap().clone();
@ -111,7 +113,7 @@ async fn test_recursive_self_updating_structs() {
let role_inner = bundle
.user
.gateway
.observe_and_into_inner(role.clone().into_shared())
.observe_and_into_inner(Arc::new(RwLock::new(role.clone())))
.await;
assert_eq!(role_inner.name, "yippieee");
// Check if the change propagated