Skip to content

Commit

Permalink
Rework CreateScheduledEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrasnitski committed Jun 16, 2022
1 parent 207907c commit 894f8aa
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 79 deletions.
116 changes: 84 additions & 32 deletions src/builder/create_scheduled_event.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,63 @@
use std::collections::HashMap;

use crate::http::CacheHttp;
#[cfg(feature = "model")]
use crate::http::Http;
#[cfg(feature = "model")]
use crate::internal::prelude::*;
use crate::json::{json, Value};
#[cfg(feature = "model")]
use crate::model::channel::AttachmentType;
use crate::model::guild::ScheduledEventType;
use crate::model::id::ChannelId;
use crate::model::Timestamp;
use crate::json::{self, json, Value};
use crate::model::prelude::*;

#[derive(Clone, Debug)]
pub struct CreateScheduledEvent(pub HashMap<&'static str, Value>);
pub struct CreateScheduledEvent {
id: GuildId,
map: HashMap<&'static str, Value>,
}

impl CreateScheduledEvent {
/// Creates a builder with default values, setting the `privacy_level` to `GUILD_ONLY`. As this
/// is the only possible value of this field, it's only used at event creation, and we don't
/// even parse it into the `ScheduledEvent` struct.
pub(crate) fn new(id: GuildId) -> Self {
let mut map = HashMap::new();
map.insert("privacy_level", Value::from(2));

Self {
id,
map,
}
}

/// Sets the channel id of the scheduled event. Required if the [`kind`] of the event is
/// [`StageInstance`] or [`Voice`].
///
/// [`kind`]: CreateScheduledEvent::kind
/// [`StageInstance`]: ScheduledEventType::StageInstance
/// [`Voice`]: ScheduledEventType::Voice
pub fn channel_id<C: Into<ChannelId>>(&mut self, channel_id: C) -> &mut Self {
self.0.insert("channel_id", Value::from(channel_id.into().0));
#[must_use]
pub fn channel_id<C: Into<ChannelId>>(mut self, channel_id: C) -> Self {
self.map.insert("channel_id", Value::from(channel_id.into().0));
self
}

/// Sets the name of the scheduled event. Required to be set for event creation.
pub fn name(&mut self, name: impl Into<String>) -> &mut Self {
self.0.insert("name", Value::String(name.into()));
#[must_use]
pub fn name(mut self, name: impl Into<String>) -> Self {
self.map.insert("name", Value::String(name.into()));
self
}

/// Sets the description of the scheduled event.
pub fn description(&mut self, description: impl Into<String>) -> &mut Self {
self.0.insert("description", Value::String(description.into()));
#[must_use]
pub fn description(mut self, description: impl Into<String>) -> Self {
self.map.insert("description", Value::String(description.into()));
self
}

/// Sets the start time of the scheduled event. Required to be set for event creation.
#[inline]
pub fn start_time<T: Into<Timestamp>>(&mut self, timestamp: T) -> &mut Self {
#[must_use]
pub fn start_time<T: Into<Timestamp>>(mut self, timestamp: T) -> Self {
self._timestamp("scheduled_start_time", timestamp.into());
self
}
Expand All @@ -51,18 +68,20 @@ impl CreateScheduledEvent {
/// [`kind`]: CreateScheduledEvent::kind
/// [`External`]: ScheduledEventType::External
#[inline]
pub fn end_time<T: Into<Timestamp>>(&mut self, timestamp: T) -> &mut Self {
#[must_use]
pub fn end_time<T: Into<Timestamp>>(mut self, timestamp: T) -> Self {
self._timestamp("scheduled_end_time", timestamp.into());
self
}

fn _timestamp(&mut self, field: &'static str, timestamp: Timestamp) {
self.0.insert(field, Value::from(timestamp.to_string()));
self.map.insert(field, Value::from(timestamp.to_string()));
}

/// Sets the entity type of the scheduled event. Required to be set for event creation.
pub fn kind(&mut self, kind: ScheduledEventType) -> &mut Self {
self.0.insert("entity_type", Value::from(kind.num()));
#[must_use]
pub fn kind(mut self, kind: ScheduledEventType) -> Self {
self.map.insert("entity_type", Value::from(kind.num()));
self
}

Expand All @@ -71,11 +90,12 @@ impl CreateScheduledEvent {
///
/// [`kind`]: CreateScheduledEvent::kind
/// [`External`]: ScheduledEventType::External
pub fn location(&mut self, location: impl Into<String>) -> &mut Self {
#[must_use]
pub fn location(mut self, location: impl Into<String>) -> Self {
let obj = json!({
"location": location.into(),
});
self.0.insert("entity_metadata", obj);
self.map.insert("entity_metadata", obj);
self
}

Expand All @@ -87,25 +107,57 @@ impl CreateScheduledEvent {
/// on a path that doesn't exist.
#[cfg(feature = "model")]
pub async fn image<'a>(
&mut self,
mut self,
http: impl AsRef<Http>,
image: impl Into<AttachmentType<'a>>,
) -> Result<&mut Self> {
) -> Result<Self> {
let image_data = image.into().data(&http.as_ref().client).await?;
let image_string = format!("data:image/png;base64,{}", base64::encode(image_data));
self.0.insert("image", Value::from(image_string));
self.map.insert("image", Value::from(image_string));
Ok(self)
}
}

impl Default for CreateScheduledEvent {
/// Creates a builder with default values, setting the `privacy_level` to `GUILD_ONLY`. As this
/// is the only possible value of this field, it's only used at event creation, and we don't
/// even parse it into the `ScheduledEvent` struct.
fn default() -> Self {
let mut map = HashMap::new();
map.insert("privacy_level", Value::from(2));
/// Creates a new scheduled event in the guild with the data set, if any.
///
/// **Note**: Requres the [Manage Events] permission.
///
/// # Errors
///
/// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
///
/// [Manage Events]: Permissions::MANAGE_EVENTS
pub async fn execute(self, http: impl AsRef<Http>) -> Result<ScheduledEvent> {
let map = json::hashmap_to_json_map(self.map);

http.as_ref().create_scheduled_event(self.id.into(), &map, None).await
}

/// Creates a new scheduled event in the guild with the data set, if any.
///
/// **Note**: Requres the [Manage Events] permission.
///
/// # Errors
///
/// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
/// does not have permission to manage scheduled events.
///
/// Otherwise will return [`Error::Http`] if the current user does not have permission.
///
/// [Manage Events]: Permissions::MANAGE_EVENTS
pub async fn execute_with_cache(self, cache_http: impl CacheHttp) -> Result<ScheduledEvent> {
#[cfg(feature = "cache")]
{
if let Some(cache) = cache_http.cache() {
if let Some(guild) = cache.guild(self.id) {
let req = Permissions::MANAGE_EVENTS;

if !guild.has_perms(&cache_http, req).await {
return Err(Error::Model(ModelError::InvalidPermissions(req)));
}
}
}
}

CreateScheduledEvent(map)
self.execute(cache_http.http()).await
}
}
23 changes: 4 additions & 19 deletions src/model/guild/guild_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,29 +332,14 @@ impl GuildId {
Ok(role)
}

/// Creates a new scheduled event in the guild with the data set, if any.
/// Returns a request builder that, when executed, will create a new scheduled event in the
/// guild.
///
/// **Note**: Requres the [Manage Events] permission.
///
/// # Errors
///
/// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
///
/// [Manage Events]: Permissions::MANAGE_EVENTS
pub async fn create_scheduled_event<F>(
&self,
http: impl AsRef<Http>,
f: F,
) -> Result<ScheduledEvent>
where
F: FnOnce(&mut CreateScheduledEvent) -> &mut CreateScheduledEvent,
{
let mut builder = CreateScheduledEvent::default();
f(&mut builder);

let map = json::hashmap_to_json_map(builder.0);

http.as_ref().create_scheduled_event(self.0, &map, None).await
pub async fn create_scheduled_event(&self) -> CreateScheduledEvent {
CreateScheduledEvent::new(*self)
}

/// Returns a request builder that, when executed, will create a new sticker in the guild.
Expand Down
32 changes: 4 additions & 28 deletions src/model/guild/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -874,38 +874,14 @@ impl Guild {
self.id.create_role(cache_http.http(), f).await
}

/// Creates a new scheduled event in the guild with the data set, if any.
/// Returns a request builder that, when executed, will create a new scheduled event in the
/// guild.
///
/// **Note**: Requres the [Manage Events] permission.
///
/// # Errors
///
/// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
/// does not have permission to manage scheduled events.
///
/// Otherwise will return [`Error::Http`] if the current user does not have permission.
///
/// [Manage Events]: Permissions::MANAGE_EVENTS
pub async fn create_scheduled_event<F>(
&self,
cache_http: impl CacheHttp,
f: F,
) -> Result<ScheduledEvent>
where
F: FnOnce(&mut CreateScheduledEvent) -> &mut CreateScheduledEvent,
{
#[cfg(feature = "cache")]
{
if cache_http.cache().is_some() {
let req = Permissions::MANAGE_EVENTS;

if !self.has_perms(&cache_http, req).await {
return Err(Error::Model(ModelError::InvalidPermissions(req)));
}
}
}

self.id.create_scheduled_event(cache_http.http(), f).await
pub async fn create_scheduled_event(&self) -> CreateScheduledEvent {
CreateScheduledEvent::new(self.id)
}

/// Returns a request builder that, when executed, will create a new sticker in the guild.
Expand Down

0 comments on commit 894f8aa

Please sign in to comment.