aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/model/channel/message.rs2
-rw-r--r--src/model/mod.rs53
-rw-r--r--src/model/utils.rs31
3 files changed, 83 insertions, 3 deletions
diff --git a/src/model/channel/message.rs b/src/model/channel/message.rs
index e092703..930c046 100644
--- a/src/model/channel/message.rs
+++ b/src/model/channel/message.rs
@@ -48,7 +48,7 @@ pub struct Message {
/// Array of users mentioned in the message.
pub mentions: Vec<User>,
/// Non-repeating number used for ensuring message order.
- pub nonce: Option<String>,
+ pub nonce: Option<Snowflake>,
/// Indicator of whether the message is pinned.
pub pinned: bool,
/// Array of reactions performed on the message.
diff --git a/src/model/mod.rs b/src/model/mod.rs
index bc414c7..ace5969 100644
--- a/src/model/mod.rs
+++ b/src/model/mod.rs
@@ -53,7 +53,51 @@ use ::utils::Colour;
fn default_true() -> bool { true }
-macro_rules! id {
+macro_rules! id_i64 {
+ ($(#[$attr:meta] $name:ident;)*) => {
+ $(
+ #[$attr]
+ #[derive(Copy, Clone, Debug, Eq, Hash, PartialOrd, Ord, Serialize)]
+ #[allow(derive_hash_xor_eq)]
+ pub struct $name(pub i64);
+
+ impl $name {
+ /// Retrieves the time that the Id was created at.
+ pub fn created_at(&self) -> NaiveDateTime {
+ let offset = (self.0 >> 22) / 1000;
+
+ NaiveDateTime::from_timestamp(1420070400 + offset, 0)
+ }
+ }
+
+ impl From<i64> for $name {
+ fn from(v: i64) -> $name {
+ $name(v)
+ }
+ }
+
+ impl PartialEq for $name {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+
+ impl PartialEq<i64> for $name {
+ fn eq(&self, u: &i64) -> bool {
+ self.0 == *u
+ }
+ }
+
+ impl<'de> Deserialize<'de> for $name {
+ fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
+ deserializer.deserialize_i64(I64Visitor).map($name)
+ }
+ }
+ )*
+ };
+}
+
+macro_rules! id_u64 {
($(#[$attr:meta] $name:ident;)*) => {
$(
#[$attr]
@@ -97,7 +141,7 @@ macro_rules! id {
}
}
-id! {
+id_u64! {
/// An identifier for a Channel
ChannelId;
/// An identifier for an Emoji
@@ -116,6 +160,11 @@ id! {
WebhookId;
}
+id_i64! {
+ /// An identifier for a general-purpose signed snowflake.
+ Snowflake;
+}
+
/// A container for guilds.
///
/// This is used to differentiate whether a guild itself can be used or whether
diff --git a/src/model/utils.rs b/src/model/utils.rs
index f88ecf5..6363fb6 100644
--- a/src/model/utils.rs
+++ b/src/model/utils.rs
@@ -240,3 +240,34 @@ impl<'de> Visitor<'de> for U64Visitor {
Ok(v)
}
}
+
+pub struct I64Visitor;
+
+impl<'de> Visitor<'de> for I64Visitor {
+ type Value = i64;
+
+ fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
+ formatter.write_str("identifier")
+ }
+
+ fn visit_str<E: DeError>(self, v: &str) -> StdResult<Self::Value, E> {
+ match v.parse::<i64>() {
+ Ok(v) => Ok(v),
+ Err(_) => {
+ let mut s = String::new();
+ s.push_str("Unknown i64 value: ");
+ s.push_str(v);
+
+ Err(DeError::custom(s))
+ },
+ }
+ }
+
+ fn visit_i64<E: DeError>(self, v: i64) -> StdResult<Self::Value, E> {
+ Ok(v)
+ }
+
+ fn visit_u64<E: DeError>(self, v: u64) -> StdResult<Self::Value, E> {
+ Ok(v as i64)
+ }
+}