twilight_model/id/
mod.rs

1//! ID with type-safe markers for each resource.
2//!
3//! When IDs are simple 64-bit integers then it may be easy to accidentally use
4//! the ID of a role in place of where one means to use the ID of a user. This
5//! is a programmatic error; it's on the programmer to notice. By using IDs with
6//! typed markers, it can be ensured that only an ID with a guild marker is used
7//! where an ID with a guild marker is requested.
8//!
9//! # Parsing
10//!
11//! IDs may be initialized or parsed in a variety of manners depending on the
12//! context:
13//!
14//! - `serde` deserialization
15//! - [`std::str::FromStr`]
16//! - [`std::convert::TryFrom`]\<i64>
17//! - [`std::convert::TryFrom`]\<u64>
18//! - [`Id::new`]
19//! - [`Id::new_checked`]
20//! - [`Id::new_unchecked`]
21//! - [`std::convert::From`]<[`std::num::NonZeroU64`]>
22//!
23//! # Casting between resource types
24//!
25//! Discord may have constraints where IDs are the same across resources. For
26//! example, the `@everyone` role of a guild has the same ID as the guild
27//! itself. In this case, all one needs to do is use the guild's ID in place of
28//! a role in order to operate on the `@everyone` role of the guild. IDs can be
29//! easily casted in order to fulfill this:
30//!
31//! ```
32//! use twilight_model::id::{
33//!     marker::{GuildMarker, RoleMarker},
34//!     Id,
35//! };
36//!
37//! // Often Rust's type inference will be able to infer the type of ID.
38//! let guild_id = Id::<GuildMarker>::new(123);
39//! let role_id = guild_id.cast::<RoleMarker>();
40//!
41//! assert_eq!(guild_id.get(), role_id.get());
42//! ```
43
44pub mod marker;
45
46mod anonymizable;
47
48pub use anonymizable::AnonymizableId;
49
50use serde::{
51    de::{Deserialize, Deserializer, Error as DeError, Unexpected, Visitor},
52    ser::{Serialize, Serializer},
53};
54use std::{
55    any,
56    cmp::Ordering,
57    fmt::{Debug, Display, Formatter, Result as FmtResult},
58    hash::{Hash, Hasher},
59    marker::PhantomData,
60    num::{NonZeroI64, NonZeroU64, ParseIntError, TryFromIntError},
61    str::FromStr,
62};
63
64/// ID of a resource, such as the ID of a [channel] or [user].
65///
66/// Markers themselves perform no logical action, and are only used to ensure
67/// that IDs of incorrect types aren't used. Read the [marker documentation] for
68/// additional information.
69///
70/// # serde
71///
72/// This ID deserializes from both integers and strings and serializes into a
73/// string.
74///
75/// [channel]: marker::ChannelMarker
76/// [marker documentation]: marker
77/// [user]: marker::UserMarker
78#[repr(transparent)]
79pub struct Id<T> {
80    phantom: PhantomData<fn(T) -> T>,
81    value: NonZeroU64,
82}
83
84impl<T> Id<T> {
85    const fn from_nonzero(value: NonZeroU64) -> Self {
86        Self {
87            phantom: PhantomData,
88            value,
89        }
90    }
91    /// Create a new ID, panicking if the value is zero.
92    ///
93    /// This is primarily useful in const contexts where you are passing a
94    /// hardcoded value.
95    ///
96    /// Refer to [`new_checked`] for a checked alternative to this method.
97    ///
98    /// # Examples
99    ///
100    /// ```
101    /// use twilight_model::id::{marker::GenericMarker, Id};
102    ///
103    /// const ID: Id<GenericMarker> = Id::new(123);
104    ///
105    /// println!("id: {ID}");
106    /// ```
107    ///
108    /// # Panics
109    ///
110    /// Panics if the value is 0.
111    ///
112    /// [`new_checked`]: Self::new_checked
113    #[track_caller]
114    pub const fn new(n: u64) -> Self {
115        if let Some(id) = Self::new_checked(n) {
116            id
117        } else {
118            panic!("value is zero");
119        }
120    }
121
122    /// Create an ID without checking if the value is non-zero.
123    ///
124    /// Equivalent to [`NonZeroU64::new_unchecked`].
125    ///
126    /// # Safety
127    ///
128    /// The value must not be zero.
129    #[allow(unsafe_code)]
130    pub const unsafe fn new_unchecked(n: u64) -> Self {
131        Self::from_nonzero(NonZeroU64::new_unchecked(n))
132    }
133
134    /// Create an ID if the provided value is not zero.
135    ///
136    /// # Examples
137    ///
138    /// ```
139    /// use twilight_model::id::{marker::GenericMarker, Id};
140    ///
141    /// assert!(Id::<GenericMarker>::new_checked(123).is_some());
142    /// assert!(Id::<GenericMarker>::new_checked(0).is_none());
143    /// ```
144    ///
145    /// Equivalent to [`NonZeroU64::new`].
146    pub const fn new_checked(n: u64) -> Option<Self> {
147        if let Some(n) = NonZeroU64::new(n) {
148            Some(Self::from_nonzero(n))
149        } else {
150            None
151        }
152    }
153
154    /// Return the inner primitive value.
155    ///
156    /// Equivalent to [`NonZeroU64::get`].
157    ///
158    /// # Examples
159    ///
160    /// Create an ID with a value and then confirm its inner value:
161    ///
162    /// ```
163    /// use twilight_model::id::{marker::ChannelMarker, Id};
164    ///
165    /// let channel_id = Id::<ChannelMarker>::new(7);
166    ///
167    /// assert_eq!(7, channel_id.get());
168    /// ```
169    pub const fn get(self) -> u64 {
170        self.value.get()
171    }
172
173    /// Return the [`NonZeroU64`] representation of the ID.
174    ///
175    /// # Examples
176    ///
177    /// Create an ID with a value and then confirm its nonzero value:
178    ///
179    /// ```
180    /// use std::num::NonZeroU64;
181    /// use twilight_model::id::{marker::ChannelMarker, Id};
182    ///
183    /// let channel_id = Id::<ChannelMarker>::new(7);
184    ///
185    /// assert_eq!(NonZeroU64::new(7).unwrap(), channel_id.into_nonzero());
186    /// ```
187    pub const fn into_nonzero(self) -> NonZeroU64 {
188        self.value
189    }
190
191    /// Cast an ID from one type to another.
192    ///
193    /// # Examples
194    ///
195    /// Cast a role ID to a guild ID, useful for the `@everyone` role:
196    ///
197    /// ```
198    /// use twilight_model::id::{
199    ///     marker::{GuildMarker, RoleMarker},
200    ///     Id,
201    /// };
202    ///
203    /// let role_id: Id<RoleMarker> = Id::new(1);
204    ///
205    /// let guild_id: Id<GuildMarker> = role_id.cast();
206    /// assert_eq!(1, guild_id.get());
207    /// ```
208    pub const fn cast<New>(self) -> Id<New> {
209        Id::from_nonzero(self.value)
210    }
211}
212
213impl<T> Clone for Id<T> {
214    fn clone(&self) -> Self {
215        *self
216    }
217}
218
219impl<T> Copy for Id<T> {}
220
221impl<T> Debug for Id<T> {
222    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
223        f.write_str("Id")?;
224        let type_name = any::type_name::<T>();
225
226        // `any::type_name` will usually provide an FQN, so we'll do our best
227        // (and simplest) method here of removing it to only get the type name
228        // itself.
229        if let Some(position) = type_name.rfind("::") {
230            if let Some(slice) = type_name.get(position + 2..) {
231                f.write_str("<")?;
232                f.write_str(slice)?;
233                f.write_str(">")?;
234            }
235        }
236
237        f.write_str("(")?;
238        Debug::fmt(&self.value, f)?;
239
240        f.write_str(")")
241    }
242}
243
244impl<'de, T> Deserialize<'de> for Id<T> {
245    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
246        struct IdVisitor<T> {
247            phantom: PhantomData<T>,
248        }
249
250        impl<T> IdVisitor<T> {
251            const fn new() -> Self {
252                Self {
253                    phantom: PhantomData,
254                }
255            }
256        }
257
258        impl<'de, T> Visitor<'de> for IdVisitor<T> {
259            type Value = Id<T>;
260
261            fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult {
262                f.write_str("a discord snowflake")
263            }
264
265            fn visit_u64<E: DeError>(self, value: u64) -> Result<Self::Value, E> {
266                let value = NonZeroU64::new(value).ok_or_else(|| {
267                    DeError::invalid_value(Unexpected::Unsigned(value), &"non zero u64")
268                })?;
269
270                Ok(Id::from(value))
271            }
272
273            fn visit_i64<E: DeError>(self, value: i64) -> Result<Self::Value, E> {
274                let unsigned = u64::try_from(value).map_err(|_| {
275                    DeError::invalid_value(Unexpected::Signed(value), &"non zero u64")
276                })?;
277
278                self.visit_u64(unsigned)
279            }
280
281            fn visit_newtype_struct<D: Deserializer<'de>>(
282                self,
283                deserializer: D,
284            ) -> Result<Self::Value, D::Error> {
285                deserializer.deserialize_any(IdVisitor::new())
286            }
287
288            fn visit_str<E: DeError>(self, v: &str) -> Result<Self::Value, E> {
289                let value = v.parse().map_err(|_| {
290                    let unexpected = Unexpected::Str(v);
291
292                    DeError::invalid_value(unexpected, &"non zero u64 string")
293                })?;
294
295                self.visit_u64(value)
296            }
297        }
298
299        deserializer.deserialize_any(IdVisitor::new())
300    }
301}
302
303impl<T> Display for Id<T> {
304    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
305        Display::fmt(&self.value.get(), f)
306    }
307}
308
309impl<T> From<Id<T>> for u64 {
310    fn from(id: Id<T>) -> Self {
311        id.get()
312    }
313}
314
315impl<T> From<NonZeroU64> for Id<T> {
316    fn from(id: NonZeroU64) -> Self {
317        Self::from_nonzero(id)
318    }
319}
320
321impl<T> From<Id<T>> for NonZeroU64 {
322    fn from(id: Id<T>) -> Self {
323        id.into_nonzero()
324    }
325}
326
327impl<T> FromStr for Id<T> {
328    type Err = ParseIntError;
329
330    fn from_str(s: &str) -> Result<Self, Self::Err> {
331        NonZeroU64::from_str(s).map(Self::from_nonzero)
332    }
333}
334
335impl<T> Eq for Id<T> {}
336
337impl<T> Hash for Id<T> {
338    fn hash<U: Hasher>(&self, state: &mut U) {
339        state.write_u64(self.value.get());
340    }
341}
342
343impl<T> Ord for Id<T> {
344    fn cmp(&self, other: &Self) -> Ordering {
345        self.value.cmp(&other.value)
346    }
347}
348
349impl<T> PartialEq for Id<T> {
350    fn eq(&self, other: &Self) -> bool {
351        self.value == other.value
352    }
353}
354
355impl<T> PartialEq<i64> for Id<T> {
356    fn eq(&self, other: &i64) -> bool {
357        u64::try_from(*other).is_ok_and(|v| v == self.value.get())
358    }
359}
360
361impl<T> PartialEq<Id<T>> for i64 {
362    fn eq(&self, other: &Id<T>) -> bool {
363        u64::try_from(*self).is_ok_and(|v| v == other.value.get())
364    }
365}
366
367impl<T> PartialEq<u64> for Id<T> {
368    fn eq(&self, other: &u64) -> bool {
369        self.value.get() == *other
370    }
371}
372
373impl<T> PartialEq<Id<T>> for u64 {
374    fn eq(&self, other: &Id<T>) -> bool {
375        other.value.get() == *self
376    }
377}
378
379impl<T> PartialOrd for Id<T> {
380    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
381        Some(self.cmp(other))
382    }
383}
384
385impl<T> Serialize for Id<T> {
386    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
387        serializer.serialize_newtype_struct("Id", &self.to_string())
388    }
389}
390
391impl<T> TryFrom<i64> for Id<T> {
392    type Error = TryFromIntError;
393
394    fn try_from(value: i64) -> Result<Self, Self::Error> {
395        let signed_nonzero = NonZeroI64::try_from(value)?;
396        let unsigned_nonzero = NonZeroU64::try_from(signed_nonzero)?;
397
398        Ok(Self::from_nonzero(unsigned_nonzero))
399    }
400}
401
402impl<T> TryFrom<u64> for Id<T> {
403    type Error = TryFromIntError;
404
405    fn try_from(value: u64) -> Result<Self, Self::Error> {
406        let nonzero = NonZeroU64::try_from(value)?;
407
408        Ok(Self::from_nonzero(nonzero))
409    }
410}
411
412#[cfg(test)]
413mod tests {
414    use super::{
415        marker::{
416            ApplicationMarker, AttachmentMarker, AuditLogEntryMarker, ChannelMarker, CommandMarker,
417            CommandVersionMarker, EmojiMarker, EntitlementMarker, GenericMarker, GuildMarker,
418            IntegrationMarker, InteractionMarker, MessageMarker, RoleMarker,
419            RoleSubscriptionSkuMarker, SkuMarker, StageMarker, UserMarker, WebhookMarker,
420        },
421        Id,
422    };
423    use serde::{Deserialize, Serialize};
424    use serde_test::Token;
425    use static_assertions::assert_impl_all;
426    use std::{
427        collections::hash_map::DefaultHasher,
428        error::Error,
429        fmt::{Debug, Display},
430        hash::{Hash, Hasher},
431        num::NonZeroU64,
432        str::FromStr,
433    };
434
435    assert_impl_all!(ApplicationMarker: Debug, Send, Sync);
436    assert_impl_all!(AttachmentMarker: Debug, Send, Sync);
437    assert_impl_all!(AuditLogEntryMarker: Debug, Send, Sync);
438    assert_impl_all!(ChannelMarker: Debug, Send, Sync);
439    assert_impl_all!(CommandMarker: Debug, Send, Sync);
440    assert_impl_all!(CommandVersionMarker: Debug, Send, Sync);
441    assert_impl_all!(EmojiMarker: Debug, Send, Sync);
442    assert_impl_all!(EntitlementMarker: Debug, Send, Sync);
443    assert_impl_all!(SkuMarker: Debug, Send, Sync);
444    assert_impl_all!(GenericMarker: Debug, Send, Sync);
445    assert_impl_all!(GuildMarker: Debug, Send, Sync);
446    assert_impl_all!(IntegrationMarker: Debug, Send, Sync);
447    assert_impl_all!(InteractionMarker: Debug, Send, Sync);
448    assert_impl_all!(MessageMarker: Debug, Send, Sync);
449    assert_impl_all!(RoleMarker: Debug, Send, Sync);
450    assert_impl_all!(RoleSubscriptionSkuMarker: Debug, Send, Sync);
451    assert_impl_all!(StageMarker: Debug, Send, Sync);
452    assert_impl_all!(UserMarker: Debug, Send, Sync);
453    assert_impl_all!(WebhookMarker: Debug, Send, Sync);
454    assert_impl_all!(Id<GenericMarker>:
455        Clone, Copy, Debug, Deserialize<'static>, Display, Eq, From<NonZeroU64>,
456        FromStr, Hash, Into<NonZeroU64>, Into<u64>, Ord, PartialEq, PartialEq<i64>, PartialEq<u64>, PartialOrd, Send, Serialize, Sync,
457        TryFrom<i64>, TryFrom<u64>
458    );
459    // assert invariant
460    assert_impl_all!(Id<*const ()>: Send, Sync);
461
462    /// Test that various methods of initializing IDs are correct, such as via
463    /// [`Id::new`] or [`Id`]'s [`TryFrom`] implementations.
464    #[test]
465    fn initializers() -> Result<(), Box<dyn Error>> {
466        // `Id::new_checked`
467        assert!(Id::<GenericMarker>::new_checked(0).is_none());
468        assert_eq!(Some(1), Id::<GenericMarker>::new_checked(1).map(Id::get));
469
470        // `Id::new`
471        assert_eq!(1, Id::<GenericMarker>::new(1).get());
472
473        // `From`
474        assert_eq!(
475            123_u64,
476            Id::<GenericMarker>::from(NonZeroU64::new(123).expect("non zero"))
477        );
478
479        // `FromStr`
480        assert_eq!(123_u64, Id::<GenericMarker>::from_str("123")?);
481        assert!(Id::<GenericMarker>::from_str("0").is_err());
482        assert!(Id::<GenericMarker>::from_str("123a").is_err());
483
484        // `TryFrom`
485        assert!(Id::<GenericMarker>::try_from(-123_i64).is_err());
486        assert!(Id::<GenericMarker>::try_from(0_i64).is_err());
487        assert_eq!(123_u64, Id::<GenericMarker>::try_from(123_i64)?);
488        assert!(Id::<GenericMarker>::try_from(0_u64).is_err());
489        assert_eq!(123_u64, Id::<GenericMarker>::try_from(123_u64)?);
490
491        Ok(())
492    }
493
494    /// Test that conversion methods are correct.
495    #[test]
496    fn conversions() {
497        // `Into`
498        assert_eq!(1, u64::from(Id::<GenericMarker>::new(1)));
499        assert_eq!(
500            NonZeroU64::new(1).expect("non zero"),
501            NonZeroU64::from(Id::<GenericMarker>::new(1))
502        );
503    }
504
505    /// Test that creating an ID via [`Id::new`] with a value of zero panics.
506    #[should_panic(expected = "value is zero")]
507    #[test]
508    const fn test_new_checked_zero() {
509        _ = Id::<GenericMarker>::new(0);
510    }
511
512    /// Test that casting IDs maintains the original value.
513    #[test]
514    fn cast() {
515        let id = Id::<GenericMarker>::new(123);
516        assert_eq!(123_u64, id.cast::<RoleMarker>());
517    }
518
519    /// Test that debugging IDs formats the generic and value as a newtype.
520    #[test]
521    fn debug() {
522        let id = Id::<RoleMarker>::new(114_941_315_417_899_012);
523
524        assert_eq!("Id<RoleMarker>(114941315417899012)", format!("{id:?}"));
525    }
526
527    /// Test that display formatting an ID formats the value.
528    #[test]
529    fn display() {
530        let id = Id::<GenericMarker>::new(114_941_315_417_899_012);
531
532        assert_eq!("114941315417899012", id.to_string());
533    }
534
535    /// Test that hashing an ID is equivalent to hashing only its inner value.
536    #[test]
537    fn hash() {
538        let id = Id::<GenericMarker>::new(123);
539
540        let mut id_hasher = DefaultHasher::new();
541        id.hash(&mut id_hasher);
542
543        let mut value_hasher = DefaultHasher::new();
544        123_u64.hash(&mut value_hasher);
545
546        assert_eq!(id_hasher.finish(), value_hasher.finish());
547    }
548
549    /// Test that IDs are ordered exactly like their inner values.
550    #[test]
551    fn ordering() {
552        let lesser = Id::<GenericMarker>::new(911_638_235_594_244_096);
553        let center = Id::<GenericMarker>::new(911_638_263_322_800_208);
554        let greater = Id::<GenericMarker>::new(911_638_287_939_166_208);
555
556        assert!(center.cmp(&greater).is_lt());
557        assert!(center.cmp(&center).is_eq());
558        assert!(center.cmp(&lesser).is_gt());
559    }
560
561    #[allow(clippy::too_many_lines)]
562    #[test]
563    fn serde() {
564        serde_test::assert_tokens(
565            &Id::<ApplicationMarker>::new(114_941_315_417_899_012),
566            &[
567                Token::NewtypeStruct { name: "Id" },
568                Token::Str("114941315417899012"),
569            ],
570        );
571        serde_test::assert_de_tokens(
572            &Id::<ApplicationMarker>::new(114_941_315_417_899_012),
573            &[
574                Token::NewtypeStruct { name: "Id" },
575                Token::U64(114_941_315_417_899_012),
576            ],
577        );
578        serde_test::assert_tokens(
579            &Id::<AttachmentMarker>::new(114_941_315_417_899_012),
580            &[
581                Token::NewtypeStruct { name: "Id" },
582                Token::Str("114941315417899012"),
583            ],
584        );
585        serde_test::assert_de_tokens(
586            &Id::<AttachmentMarker>::new(114_941_315_417_899_012),
587            &[
588                Token::NewtypeStruct { name: "Id" },
589                Token::U64(114_941_315_417_899_012),
590            ],
591        );
592        serde_test::assert_tokens(
593            &Id::<AuditLogEntryMarker>::new(114_941_315_417_899_012),
594            &[
595                Token::NewtypeStruct { name: "Id" },
596                Token::Str("114941315417899012"),
597            ],
598        );
599        serde_test::assert_de_tokens(
600            &Id::<AuditLogEntryMarker>::new(114_941_315_417_899_012),
601            &[
602                Token::NewtypeStruct { name: "Id" },
603                Token::U64(114_941_315_417_899_012),
604            ],
605        );
606        serde_test::assert_tokens(
607            &Id::<ChannelMarker>::new(114_941_315_417_899_012),
608            &[
609                Token::NewtypeStruct { name: "Id" },
610                Token::Str("114941315417899012"),
611            ],
612        );
613        serde_test::assert_de_tokens(
614            &Id::<ChannelMarker>::new(114_941_315_417_899_012),
615            &[
616                Token::NewtypeStruct { name: "Id" },
617                Token::U64(114_941_315_417_899_012),
618            ],
619        );
620        serde_test::assert_tokens(
621            &Id::<CommandMarker>::new(114_941_315_417_899_012),
622            &[
623                Token::NewtypeStruct { name: "Id" },
624                Token::Str("114941315417899012"),
625            ],
626        );
627        serde_test::assert_de_tokens(
628            &Id::<CommandMarker>::new(114_941_315_417_899_012),
629            &[
630                Token::NewtypeStruct { name: "Id" },
631                Token::U64(114_941_315_417_899_012),
632            ],
633        );
634        serde_test::assert_tokens(
635            &Id::<CommandVersionMarker>::new(114_941_315_417_899_012),
636            &[
637                Token::NewtypeStruct { name: "Id" },
638                Token::Str("114941315417899012"),
639            ],
640        );
641        serde_test::assert_de_tokens(
642            &Id::<CommandVersionMarker>::new(114_941_315_417_899_012),
643            &[
644                Token::NewtypeStruct { name: "Id" },
645                Token::U64(114_941_315_417_899_012),
646            ],
647        );
648        serde_test::assert_tokens(
649            &Id::<EmojiMarker>::new(114_941_315_417_899_012),
650            &[
651                Token::NewtypeStruct { name: "Id" },
652                Token::Str("114941315417899012"),
653            ],
654        );
655        serde_test::assert_de_tokens(
656            &Id::<EmojiMarker>::new(114_941_315_417_899_012),
657            &[
658                Token::NewtypeStruct { name: "Id" },
659                Token::U64(114_941_315_417_899_012),
660            ],
661        );
662        serde_test::assert_tokens(
663            &Id::<EntitlementMarker>::new(114_941_315_417_899_012),
664            &[
665                Token::NewtypeStruct { name: "Id" },
666                Token::Str("114941315417899012"),
667            ],
668        );
669        serde_test::assert_de_tokens(
670            &Id::<EntitlementMarker>::new(114_941_315_417_899_012),
671            &[
672                Token::NewtypeStruct { name: "Id" },
673                Token::Str("114941315417899012"),
674            ],
675        );
676        serde_test::assert_tokens(
677            &Id::<SkuMarker>::new(114_941_315_417_899_012),
678            &[
679                Token::NewtypeStruct { name: "Id" },
680                Token::Str("114941315417899012"),
681            ],
682        );
683        serde_test::assert_de_tokens(
684            &Id::<SkuMarker>::new(114_941_315_417_899_012),
685            &[
686                Token::NewtypeStruct { name: "Id" },
687                Token::Str("114941315417899012"),
688            ],
689        );
690        serde_test::assert_tokens(
691            &Id::<GenericMarker>::new(114_941_315_417_899_012),
692            &[
693                Token::NewtypeStruct { name: "Id" },
694                Token::Str("114941315417899012"),
695            ],
696        );
697        serde_test::assert_de_tokens(
698            &Id::<GenericMarker>::new(114_941_315_417_899_012),
699            &[
700                Token::NewtypeStruct { name: "Id" },
701                Token::U64(114_941_315_417_899_012),
702            ],
703        );
704        serde_test::assert_tokens(
705            &Id::<GuildMarker>::new(114_941_315_417_899_012),
706            &[
707                Token::NewtypeStruct { name: "Id" },
708                Token::Str("114941315417899012"),
709            ],
710        );
711        serde_test::assert_de_tokens(
712            &Id::<GuildMarker>::new(114_941_315_417_899_012),
713            &[
714                Token::NewtypeStruct { name: "Id" },
715                Token::U64(114_941_315_417_899_012),
716            ],
717        );
718        serde_test::assert_tokens(
719            &Id::<IntegrationMarker>::new(114_941_315_417_899_012),
720            &[
721                Token::NewtypeStruct { name: "Id" },
722                Token::Str("114941315417899012"),
723            ],
724        );
725        serde_test::assert_de_tokens(
726            &Id::<IntegrationMarker>::new(114_941_315_417_899_012),
727            &[
728                Token::NewtypeStruct { name: "Id" },
729                Token::U64(114_941_315_417_899_012),
730            ],
731        );
732        serde_test::assert_tokens(
733            &Id::<InteractionMarker>::new(114_941_315_417_899_012),
734            &[
735                Token::NewtypeStruct { name: "Id" },
736                Token::Str("114941315417899012"),
737            ],
738        );
739        serde_test::assert_de_tokens(
740            &Id::<InteractionMarker>::new(114_941_315_417_899_012),
741            &[
742                Token::NewtypeStruct { name: "Id" },
743                Token::U64(114_941_315_417_899_012),
744            ],
745        );
746        serde_test::assert_tokens(
747            &Id::<MessageMarker>::new(114_941_315_417_899_012),
748            &[
749                Token::NewtypeStruct { name: "Id" },
750                Token::Str("114941315417899012"),
751            ],
752        );
753        serde_test::assert_de_tokens(
754            &Id::<MessageMarker>::new(114_941_315_417_899_012),
755            &[
756                Token::NewtypeStruct { name: "Id" },
757                Token::U64(114_941_315_417_899_012),
758            ],
759        );
760        serde_test::assert_tokens(
761            &Id::<RoleMarker>::new(114_941_315_417_899_012),
762            &[
763                Token::NewtypeStruct { name: "Id" },
764                Token::Str("114941315417899012"),
765            ],
766        );
767        serde_test::assert_de_tokens(
768            &Id::<RoleMarker>::new(114_941_315_417_899_012),
769            &[
770                Token::NewtypeStruct { name: "Id" },
771                Token::U64(114_941_315_417_899_012),
772            ],
773        );
774        serde_test::assert_tokens(
775            &Id::<RoleSubscriptionSkuMarker>::new(114_941_315_417_899_012),
776            &[
777                Token::NewtypeStruct { name: "Id" },
778                Token::Str("114941315417899012"),
779            ],
780        );
781        serde_test::assert_tokens(
782            &Id::<StageMarker>::new(114_941_315_417_899_012),
783            &[
784                Token::NewtypeStruct { name: "Id" },
785                Token::Str("114941315417899012"),
786            ],
787        );
788        serde_test::assert_de_tokens(
789            &Id::<StageMarker>::new(114_941_315_417_899_012),
790            &[
791                Token::NewtypeStruct { name: "Id" },
792                Token::U64(114_941_315_417_899_012),
793            ],
794        );
795        serde_test::assert_tokens(
796            &Id::<UserMarker>::new(114_941_315_417_899_012),
797            &[
798                Token::NewtypeStruct { name: "Id" },
799                Token::Str("114941315417899012"),
800            ],
801        );
802        serde_test::assert_de_tokens(
803            &Id::<UserMarker>::new(114_941_315_417_899_012),
804            &[
805                Token::NewtypeStruct { name: "Id" },
806                Token::U64(114_941_315_417_899_012),
807            ],
808        );
809        serde_test::assert_tokens(
810            &Id::<WebhookMarker>::new(114_941_315_417_899_012),
811            &[
812                Token::NewtypeStruct { name: "Id" },
813                Token::Str("114941315417899012"),
814            ],
815        );
816        serde_test::assert_de_tokens(
817            &Id::<WebhookMarker>::new(114_941_315_417_899_012),
818            &[
819                Token::NewtypeStruct { name: "Id" },
820                Token::U64(114_941_315_417_899_012),
821            ],
822        );
823        serde_test::assert_de_tokens(
824            &Id::<WebhookMarker>::new(114_941_315_417_899_012),
825            &[
826                Token::NewtypeStruct { name: "Id" },
827                Token::I64(114_941_315_417_899_012),
828            ],
829        );
830    }
831}