Compare commits
No commits in common. "fe8106d2a1dd49ba05c9a41dbb156d1e8cf1d7cc" and "8e25f401a5c83157daa4f12946a2ea6322783163" have entirely different histories.
fe8106d2a1
...
8e25f401a5
|
@ -40,19 +40,10 @@ impl GatewayHandle {
|
||||||
.unwrap();
|
.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>>(
|
pub async fn observe<T: Updateable + Clone + Debug + Composite<T>>(
|
||||||
&self,
|
&self,
|
||||||
object: Shared<T>,
|
object: Arc<RwLock<T>>,
|
||||||
) -> Shared<T> {
|
) -> Arc<RwLock<T>> {
|
||||||
let mut store = self.store.lock().await;
|
let mut store = self.store.lock().await;
|
||||||
let id = object.read().unwrap().id();
|
let id = object.read().unwrap().id();
|
||||||
if let Some(channel) = store.get(&id) {
|
if let Some(channel) = store.get(&id) {
|
||||||
|
@ -93,7 +84,7 @@ impl GatewayHandle {
|
||||||
/// with all of its observable fields being observed.
|
/// with all of its observable fields being observed.
|
||||||
pub async fn observe_and_into_inner<T: Updateable + Clone + Debug + Composite<T>>(
|
pub async fn observe_and_into_inner<T: Updateable + Clone + Debug + Composite<T>>(
|
||||||
&self,
|
&self,
|
||||||
object: Shared<T>,
|
object: Arc<RwLock<T>>,
|
||||||
) -> T {
|
) -> T {
|
||||||
let channel = self.observe(object.clone()).await;
|
let channel = self.observe(object.clone()).await;
|
||||||
let object = channel.read().unwrap().clone();
|
let object = channel.read().unwrap().clone();
|
||||||
|
|
|
@ -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>>;
|
|
||||||
|
|
|
@ -23,8 +23,6 @@ pub use user_settings::*;
|
||||||
pub use voice_state::*;
|
pub use voice_state::*;
|
||||||
pub use webhook::*;
|
pub use webhook::*;
|
||||||
|
|
||||||
use crate::gateway::Shared;
|
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use crate::gateway::Updateable;
|
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 watch_whole(self, gateway: &GatewayHandle) -> Self;
|
||||||
|
|
||||||
async fn option_observe_fn(
|
async fn option_observe_fn(
|
||||||
value: Option<Shared<T>>,
|
value: Option<Arc<RwLock<T>>>,
|
||||||
gateway: &GatewayHandle,
|
gateway: &GatewayHandle,
|
||||||
) -> Option<Shared<T>>
|
) -> Option<Arc<RwLock<T>>>
|
||||||
where
|
where
|
||||||
T: Composite<T> + Debug,
|
T: Composite<T> + Debug,
|
||||||
{
|
{
|
||||||
|
@ -86,9 +84,9 @@ pub trait Composite<T: Updateable + Clone + Debug> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn option_vec_observe_fn(
|
async fn option_vec_observe_fn(
|
||||||
value: Option<Vec<Shared<T>>>,
|
value: Option<Vec<Arc<RwLock<T>>>>,
|
||||||
gateway: &GatewayHandle,
|
gateway: &GatewayHandle,
|
||||||
) -> Option<Vec<Shared<T>>>
|
) -> Option<Vec<Arc<RwLock<T>>>>
|
||||||
where
|
where
|
||||||
T: Composite<T>,
|
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
|
where
|
||||||
T: Composite<T>,
|
T: Composite<T>,
|
||||||
{
|
{
|
||||||
gateway.observe(value).await
|
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
|
where
|
||||||
T: Composite<T>,
|
T: Composite<T>,
|
||||||
{
|
{
|
||||||
|
@ -121,19 +122,3 @@ pub trait Composite<T: Updateable + Clone + Debug> {
|
||||||
vec
|
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use chorus::gateway::{Gateway, Shared};
|
use std::sync::{Arc, RwLock};
|
||||||
use chorus::types::IntoShared;
|
|
||||||
|
use chorus::gateway::Gateway;
|
||||||
use chorus::{
|
use chorus::{
|
||||||
instance::{ChorusUser, Instance},
|
instance::{ChorusUser, Instance},
|
||||||
types::{
|
types::{
|
||||||
|
@ -15,9 +16,9 @@ pub(crate) struct TestBundle {
|
||||||
pub urls: UrlBundle,
|
pub urls: UrlBundle,
|
||||||
pub user: ChorusUser,
|
pub user: ChorusUser,
|
||||||
pub instance: Instance,
|
pub instance: Instance,
|
||||||
pub guild: Shared<Guild>,
|
pub guild: Arc<RwLock<Guild>>,
|
||||||
pub role: Shared<RoleObject>,
|
pub role: Arc<RwLock<RoleObject>>,
|
||||||
pub channel: Shared<Channel>,
|
pub channel: Arc<RwLock<Channel>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -118,9 +119,9 @@ pub(crate) async fn setup() -> TestBundle {
|
||||||
urls,
|
urls,
|
||||||
user,
|
user,
|
||||||
instance,
|
instance,
|
||||||
guild: guild.into_shared(),
|
guild: Arc::new(RwLock::new(guild)),
|
||||||
role: role.into_shared(),
|
role: Arc::new(RwLock::new(role)),
|
||||||
channel: channel.into_shared(),
|
channel: Arc::new(RwLock::new(channel)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use chorus::errors::GatewayError;
|
use chorus::errors::GatewayError;
|
||||||
use chorus::gateway::*;
|
use chorus::gateway::*;
|
||||||
use chorus::types::{self, ChannelModifySchema, IntoShared, RoleCreateModifySchema, RoleObject};
|
use chorus::types::{self, ChannelModifySchema, RoleCreateModifySchema, RoleObject};
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use wasm_bindgen_test::*;
|
use wasm_bindgen_test::*;
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
@ -98,7 +100,7 @@ async fn test_recursive_self_updating_structs() {
|
||||||
bundle
|
bundle
|
||||||
.user
|
.user
|
||||||
.gateway
|
.gateway
|
||||||
.observe(role.clone().into_shared())
|
.observe(Arc::new(RwLock::new(role.clone())))
|
||||||
.await;
|
.await;
|
||||||
// Update Guild and check for Guild
|
// Update Guild and check for Guild
|
||||||
let inner_guild = guild.read().unwrap().clone();
|
let inner_guild = guild.read().unwrap().clone();
|
||||||
|
@ -111,7 +113,7 @@ async fn test_recursive_self_updating_structs() {
|
||||||
let role_inner = bundle
|
let role_inner = bundle
|
||||||
.user
|
.user
|
||||||
.gateway
|
.gateway
|
||||||
.observe_and_into_inner(role.clone().into_shared())
|
.observe_and_into_inner(Arc::new(RwLock::new(role.clone())))
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(role_inner.name, "yippieee");
|
assert_eq!(role_inner.name, "yippieee");
|
||||||
// Check if the change propagated
|
// Check if the change propagated
|
||||||
|
|
Loading…
Reference in New Issue