glyde/id

Discord IDs, called snowflakes. Always a String: Discord sends them as JSON strings and nothing ever does arithmetic on one.

Each is tagged with what it identifies, so swapping the two snowflakes in /channels/{channel_id}/messages/{message_id} will not compile.

Types

pub type Application
pub type ApplicationId =
  Id(Application)
pub type Attachment
pub type AttachmentId =
  Id(Attachment)
pub type Channel
pub type ChannelId =
  Id(Channel)

An application command, called a slash command in the UI.

pub type Command
pub type CommandId =
  Id(Command)
pub type Emoji
pub type EmojiId =
  Id(Emoji)
pub type Guild
pub type GuildId =
  Id(Guild)

Id

opaque </>
pub opaque type Id(kind)

A guild integration, such as a linked Twitch or YouTube account.

pub type Integration
pub type IntegrationId =
  Id(Integration)
pub type Interaction
pub type InteractionId =
  Id(Interaction)
pub type Message
pub type MessageId =
  Id(Message)

A permission overwrite, which is addressed by the id of the role or member it applies to. model/channel.OverwriteTarget says which of the two.

pub type Overwrite
pub type OverwriteId =
  Id(Overwrite)
pub type Role
pub type RoleId =
  Id(Role)
pub type ScheduledEvent
pub type ScheduledEventId =
  Id(ScheduledEvent)

A monetisation SKU.

pub type Sku
pub type SkuId =
  Id(Sku)
pub type Sticker
pub type StickerId =
  Id(Sticker)

A subscription listing, used by role subscriptions.

pub type SubscriptionListing
pub type SubscriptionListingId =
  Id(SubscriptionListing)

Names a tag as a value, so retag can be told which one to produce. Empty and opaque: the constants below are the only ones there are.

pub opaque type Tag(kind)
pub type User
pub type UserId =
  Id(User)
pub type Webhook
pub type WebhookId =
  Id(Webhook)

Values

pub const application: Tag(Application)
pub const attachment: Tag(Attachment)
pub const channel: Tag(Channel)
pub const command: Tag(Command)
pub fn compare(a: Id(kind), b: Id(kind)) -> order.Order

Numerically, which for snowflakes is oldest first. Length first because string order is wrong: IDs run 15 to 19 digits with no leading zero.

pub fn created_at_ms(id: Id(kind)) -> Result(Int, Nil)

When this thing was created, in milliseconds since the Unix epoch. Error when the ID is not a snowflake: not a number at all, or wider than one. parse rejects both, so only an ID minted with from_string can fail.

pub fn created_at_ms_or(
  id: Id(kind),
  default default: Int,
) -> Int

created_at_ms for a caller that has to answer with a number either way. discord_epoch_ms is usually the default to reach for: it reads as the oldest snowflake there is, so an ID that is not one sorts as ancient rather than as this instant.

pub fn decoder() -> decode.Decoder(Id(kind))

Strings only: Discord always sends a snowflake as a JSON string, so a number in that slot is a malformed payload.

pub const discord_epoch_ms: Int

Discord’s epoch, 2015-01-01T00:00:00Z, in milliseconds.

pub const emoji: Tag(Emoji)
pub fn from_string(text: String) -> Id(kind)

An ID minted from a string you trust: a literal, or text you have already checked. Does not validate, and IDs go straight into request paths, so parse anything that came from outside.

pub const guild: Tag(Guild)
pub const integration: Tag(Integration)
pub const interaction: Tag(Interaction)
pub const message: Tag(Message)
pub const overwrite: Tag(Overwrite)
pub fn parse(text: String) -> Result(Id(kind), Nil)

An ID from untrusted input: digits only, no leading zero and no wider than a snowflake, which is every ID Discord issues. Rejects @me and anything with a path separator.

pub fn retag(id: Id(a), to tag: Tag(b)) -> Id(b)

The same ID under a different tag, for the places Discord hands one thing out under two names. Only relabels an ID you already hold: unlike from_string it cannot bring new text in.

The destination is a tag value rather than inference, so the call site says what it is making and the compiler holds you to it:

id.retag(overwrite.id, to: id.role)
pub const role: Tag(Role)
pub const scheduled_event: Tag(ScheduledEvent)
pub const sku: Tag(Sku)
pub const sticker: Tag(Sticker)
pub const subscription_listing: Tag(SubscriptionListing)
pub fn to_json(id: Id(kind)) -> json.Json
pub fn to_string(id: Id(kind)) -> String
pub const user: Tag(User)
pub const webhook: Tag(Webhook)
Search Document