From 97e68c7b585c6add3434ca601675bd2adaaaab8b Mon Sep 17 00:00:00 2001 From: TopiSenpai Date: Sun, 23 Jan 2022 17:12:20 +0100 Subject: [PATCH] add snowflake type and readme --- .gitignore | 1 + README.md | 47 ++++++++++++++++++++++++++++++++++++++- go.mod | 3 +++ go.sum | 0 snowflake.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 go.mod create mode 100644 go.sum create mode 100644 snowflake.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/README.md b/README.md index 03c647e..dc8fabc 100644 --- a/README.md +++ b/README.md @@ -1 +1,46 @@ -# Snowflake \ No newline at end of file +[![Go Reference](https://pkg.go.dev/badge/github.com/DisgoOrg/snowflake.svg)](https://pkg.go.dev/github.com/DisgoOrg/disgo) +[![Go Version](https://img.shields.io/github/go-mod/go-version/DisgoOrg/snowflake)](https://golang.org/doc/devel/release.html) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/DisgoOrg/disgo/blob/master/LICENSE) +[![Disgo Version](https://img.shields.io/github/v/tag/DisgoOrg/snowflake?label=release)](https://github.com/DisgoOrg/disgo/releases/latest) +[![Disgo Discord](https://discord.com/api/guilds/817327181659111454/widget.png)](https://discord.gg/TewhTfDpvW) + +# snowflake + +snowflake is a golang library for parsing [snowflake IDs](https://docs.snowflake.com) from discord. +This package provides a custom `snowflake` type which has various utility methods for parsing snowflake IDs. + +### Installing + +```sh +go get github.com/DisgoOrg/snowflake +``` + +## Usage + +```go + +id := Snowflake("123456789012345678") + +// deconstructs the snowflake ID into its components timestamp, worker ID, process ID, and increment +id.Deconstruct() + +// time.Time when the snowflake was generated +id.Time() + +// returns the string representation of the snowflake ID +id.String() + +// returns the int64 representation of the snowflake ID +id.Int64() + +// returns a new snowflake with worker ID, process ID, and increment set to 0 +// this can be used for various pagination requests to the discord api +id = NewSnowflake(time.Now()) + +// returns a snowflake from an environment variable +id = NewSnowflakeEnv("guild_id") +``` + +## License + +Distributed under the [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/DisgoOrg/disgo/blob/master/LICENSE). See LICENSE for more information. diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..850363b --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/DisgoOrg/snowflake + +go 1.18 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/snowflake.go b/snowflake.go new file mode 100644 index 0000000..6ee8116 --- /dev/null +++ b/snowflake.go @@ -0,0 +1,62 @@ +package snowflake + +import ( + "os" + "strconv" + "time" +) + +var Epoch int64 = 1420070400000 + +// NewSnowflake returns a new Snowflake based on the given time.Time +//goland:noinspection GoUnusedExportedFunction +func NewSnowflake(timestamp time.Time) Snowflake { + return Snowflake(strconv.FormatInt(((timestamp.UnixNano()/1_000_000)-Epoch)<<22, 10)) +} + +// NewSnowflakeEnv returns a new Snowflake from an environment variable +//goland:noinspection GoUnusedExportedFunction +func NewSnowflakeEnv(key string) Snowflake { + return Snowflake(os.Getenv(key)) +} + +// Snowflake is a general utility type around discord's IDs +type Snowflake string + +// String returns the string representation of the Snowflake +func (s Snowflake) String() string { + return string(s) +} + +// Int64 returns the int64 representation of the Snowflake +func (s Snowflake) Int64() int64 { + snowflake, err := strconv.ParseInt(s.String(), 10, 64) + if err != nil { + panic(err.Error()) + } + return snowflake +} + +// Deconstruct returns DeconstructedSnowflake (https://discord.com/developers/docs/reference#snowflakes-snowflake-id-format-structure-left-to-right) +func (s Snowflake) Deconstruct() DeconstructedSnowflake { + snowflake := s.Int64() + return DeconstructedSnowflake{ + Time: time.Unix(0, ((snowflake>>22)+Epoch)*1_000_000), + WorkerID: (snowflake & 0x3E0000) >> 17, + ProcessID: (snowflake & 0x1F000) >> 12, + Increment: snowflake & 0xFFF, + } +} + +// Time returns the time.Time when the snowflake was created +func (s Snowflake) Time() time.Time { + return s.Deconstruct().Time +} + +// DeconstructedSnowflake contains the properties used by Discord for each CommandID +type DeconstructedSnowflake struct { + Time time.Time + WorkerID int64 + ProcessID int64 + Increment int64 +}