1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::convert::TryFrom;
use std::fmt;
use serde::{Serialize, Deserialize, ser::Serializer, de::{self, Deserializer, Visitor}};
use chrono::{DateTime, Utc, TimeZone};

pub struct InvalidSnowflake;

impl fmt::Debug for InvalidSnowflake {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.write_str("invalid snowflake")
	}
}

impl fmt::Display for InvalidSnowflake {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.write_str("invalid snowflake")
	}
}

impl std::error::Error for InvalidSnowflake { }

impl From<std::num::ParseIntError> for InvalidSnowflake {
	fn from(_: std::num::ParseIntError) -> InvalidSnowflake {
		InvalidSnowflake
	}
}

#[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub struct Snowflake(u64);

impl Snowflake {
	pub fn as_datetime(self) -> DateTime<Utc> {
		let ts = (self.0 >> 22) + 1420070400000;
		Utc.timestamp_millis(ts as i64)
	}
}

impl fmt::Debug for Snowflake {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "<{}>", self.0)
	}
}

impl fmt::Display for Snowflake {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "{}", self.0)
	}
}

impl TryFrom<String> for Snowflake {
	type Error = InvalidSnowflake;

	fn try_from(value: String) -> Result<Self, Self::Error> {
		Ok(Snowflake(value.parse()?))
	}
}

impl From<u64> for Snowflake {
	fn from(value: u64) -> Self {
		Snowflake(value)
	}
}

impl Into<u64> for Snowflake {
	fn into(self) -> u64 {
		self.0
	}
}

impl std::str::FromStr for Snowflake {
	type Err = <u64 as std::str::FromStr>::Err;
	fn from_str(s: &str) -> Result<Self, Self::Err> {
		Ok(Snowflake(<u64 as std::str::FromStr>::from_str(s)?))
	}
}

impl PartialOrd for Snowflake {
	fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
		self.0.partial_cmp(&other.0)
	}
}

impl Ord for Snowflake {
	fn cmp(&self, other: &Self) -> std::cmp::Ordering {
		self.0.cmp(&other.0)
	}
}

impl Serialize for Snowflake {
	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
		let val = self.0.to_string();
		serializer.serialize_str(&val)
	}
}

impl<'de> Deserialize<'de> for Snowflake {
	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
		deserializer.deserialize_any(SnowflakeVisitor)
	}
}

struct SnowflakeVisitor;
impl<'de> Visitor<'de> for SnowflakeVisitor {
	type Value = Snowflake;

	fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.write_str("an unsigned integer encoded as a string or integer")
	}

	fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: de::Error {
		Ok(Snowflake(v.parse().map_err(|_| de::Error::invalid_value(de::Unexpected::Other("non-integral string"), &self))?))
	}

	fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> where E: de::Error {
		Ok(Snowflake(v))
	}

	fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> where E: de::Error {
		self.visit_u64(v as u64)
	}
}