Skip to content

Commit

Permalink
working here now
Browse files Browse the repository at this point in the history
  • Loading branch information
Xavrax committed Aug 29, 2023
1 parent 1198cec commit 6d76f27
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/core/transport_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ impl TransportRequest {
{
// Request configured endpoint.
let response = transport.send(self.clone()).await?;

Self::deserialize(
response.clone(),
Box::new(move |bytes| deserializer.deserialize(bytes)),
Expand Down
30 changes: 22 additions & 8 deletions src/dx/presence/builders/here_now.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
//! The [`HereNowRequestBuilder`] lets you make and execute a Here Now request
//! that will associate a user with a channel.
use core::ops::Deref;

use derive_builder::Builder;

use crate::{
Expand Down Expand Up @@ -59,10 +61,6 @@ pub struct HereNowRequest<T, D> {
)]
pub(in crate::dx::presence) channel_groups: Vec<String>,

/// Identifier of the user for which to retrieve occupancy information.
#[builder(field(vis = "pub(in crate::dx::presence)"), setter(strip_option, into))]
pub(in crate::dx::presence) user_id: String,

/// Whether to include UUIDs of users subscribed to the channel(s).
#[builder(
field(vis = "pub(in crate::dx::presence)"),
Expand Down Expand Up @@ -92,8 +90,6 @@ impl<T, D> HereNowRequestBuilder<T, D> {
builders::validate_configuration(&self.pubnub_client).and_then(|_| {
if channels_len == groups_len && channels_len == 0 {
Err("Either channels or channel groups should be provided".into())
} else if self.user_id.is_none() {
Err("User id is missing".into())
} else {
Ok(())
}
Expand Down Expand Up @@ -126,11 +122,15 @@ impl<T, D> HereNowRequest<T, D> {
query.insert("disable_uuids".into(), "1".into());
});

query.insert(
"uuid".into(),
self.pubnub_client.config.user_id.deref().clone(),
);

Ok(TransportRequest {
path: format!(
"/v2/presence/sub-key/{sub_key}/channel/{}/uuid/{}/data",
"/v2/presence/sub-key/{sub_key}/channel/{}",
url_encoded_channels(&self.channels),
url_encode_extended(self.user_id.as_bytes(), UrlEncodeExtension::NonChannelPath)
),
query_parameters: query,
method: TransportMethod::Get,
Expand All @@ -147,13 +147,27 @@ where
{
/// Build and call asynchronous request.
pub async fn execute(self) -> Result<HereNowResult, PubNubError> {
let name_replacement = self
.channels
.as_ref()
.map(|channels| (channels.len() == 1).then(|| channels[0].clone()))
.flatten();

let request = self.request()?;
let transport_request = request.transport_request()?;
let client = request.pubnub_client.clone();
let deserializer = client.deserializer.clone();

transport_request
.send::<HereNowResponseBody, _, _, _>(&client.transport, deserializer)
.await
.map(|mut result: HereNowResult| {
name_replacement.is_some().then(|| {
result.channels[0].name = name_replacement.expect("Cannot be None");
});

result
})
}
}

Expand Down
81 changes: 54 additions & 27 deletions src/dx/presence/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ pub struct HereNowResponseChannelIdentifier {
pub occupancy: u32,

/// List of users in channel.
pub uuids: Vec<HereNowResponseUserIdentifier>,
pub uuids: Option<Vec<HereNowResponseUserIdentifier>>,
}

/// Possible variants of user identifier in here now response.
Expand All @@ -492,6 +492,12 @@ pub enum HereNowResponseUserIdentifier {
/// User identifier is a string.
String(String),

/// User identifier is a map of uuids
Map {
/// User identifier.
uuid: String,
},

/// User identifier is a map of channel names to their states.
WithState {
/// User identifier.
Expand Down Expand Up @@ -519,20 +525,28 @@ impl TryFrom<HereNowResponseBody> for HereNowResult {
let occupants = single
.payload
.uuids
.iter()
.map(|uuid| match uuid {
HereNowResponseUserIdentifier::String(uuid) => HereNowUser {
user_id: uuid.clone(),
state: None,
},
HereNowResponseUserIdentifier::WithState { uuid, state } => {
HereNowUser {
user_id: uuid.clone(),
state: Some(state.clone()),
}
}
.map(|maybe_uuids| {
maybe_uuids
.iter()
.map(|uuid| match uuid {
HereNowResponseUserIdentifier::String(uuid) => HereNowUser {
user_id: uuid.clone(),
state: None,
},
HereNowResponseUserIdentifier::Map { uuid } => HereNowUser {
user_id: uuid.clone(),
state: None,
},
HereNowResponseUserIdentifier::WithState { uuid, state } => {
HereNowUser {
user_id: uuid.clone(),
state: Some(state.clone()),
}
}
})
.collect()
})
.collect();
.unwrap_or_default();

let channels = vec![HereNowChannel {
name: "".into(),
Expand All @@ -559,20 +573,33 @@ impl TryFrom<HereNowResponseBody> for HereNowResult {

let occupants = channel
.uuids
.into_iter()
.map(|uuid| match uuid {
HereNowResponseUserIdentifier::String(uuid) => HereNowUser {
user_id: uuid.clone(),
state: None,
},
HereNowResponseUserIdentifier::WithState { uuid, state } => {
HereNowUser {
user_id: uuid.clone(),
state: Some(state.clone()),
}
}
.map(|maybe_uuids| {
maybe_uuids
.into_iter()
.map(|uuid| match uuid {
HereNowResponseUserIdentifier::String(uuid) => {
HereNowUser {
user_id: uuid.clone(),
state: None,
}
}
HereNowResponseUserIdentifier::Map { uuid } => {
HereNowUser {
user_id: uuid.clone(),
state: None,
}
}
HereNowResponseUserIdentifier::WithState {
uuid,
state,
} => HereNowUser {
user_id: uuid.clone(),
state: Some(state.clone()),
},
})
.collect()
})
.collect();
.unwrap_or_default();

HereNowChannel {
name,
Expand Down

0 comments on commit 6d76f27

Please sign in to comment.