Skip to content

Commit 2959d6d

Browse files
committed
close #1: add a first enum implementation
1 parent 342091d commit 2959d6d

File tree

11 files changed

+2078
-21
lines changed

11 files changed

+2078
-21
lines changed

.gitignore

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,6 @@
1-
# If you prefer the allow list template instead of the deny list, see community template:
2-
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
3-
#
4-
# Binaries for programs and plugins
5-
*.exe
6-
*.exe~
7-
*.dll
8-
*.so
9-
*.dylib
10-
11-
# Test binary, built with `go test -c`
12-
*.test
13-
14-
# Output of the go coverage tool, specifically when used with LiteIDE
1+
# Trivy cache fodler
2+
.trivy
3+
# Task cache fodler
4+
.task
5+
# Coverage files
156
*.out
16-
17-
# Dependency directories (remove the comment below to include it)
18-
# vendor/
19-
20-
# Go workspace file
21-
go.work

.golangci.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
run:
2+
timeout: 5m
3+
modules-download-mode: readonly
4+
skip-files:
5+
- "example_*"
6+
7+
linters:
8+
enable:
9+
- errcheck
10+
- gosimple
11+
- govet
12+
- ineffassign
13+
- staticcheck
14+
- typecheck
15+
- unused
16+
- goimports
17+
- revive
18+
- nolintlint
19+
- usestdlibvars
20+
- tagliatelle
21+
- predeclared
22+
- errorlint
23+
- unconvert
24+
- tagalign
25+
- gofumpt
26+
- misspell
27+
- nonamedreturns
28+
- forbidigo
29+
30+
linters-settings:
31+
errcheck:
32+
# To check errors in type assertions
33+
check-type-assertions: true
34+
# To not allows to blank errors with _
35+
check-blank: true
36+
37+
misspell:
38+
# To set the language to check with
39+
locale: US
40+
41+
tagalign:
42+
# To not align tag
43+
align: false
44+
# To sort tags by name
45+
sort: true
46+
# To specify the order of tags, the other tags will be sorted by name
47+
order:
48+
- json
49+
50+
errorlint:
51+
# To check whether fmt.Errorf uses the %w verb for formatting errors
52+
errorf: true
53+
# To not allows more than 1 %w verb
54+
errorf-multi: false
55+
# To check for plain type assertions and type switches
56+
asserts: true
57+
# To check for plain error comparisons
58+
comparison: true
59+
60+
predeclared:
61+
# To not include method names and field names in checks
62+
q: false
63+
64+
tagliatelle:
65+
case:
66+
# Do not check field names in struct with the json tag
67+
use-field-name: false
68+
# Choose case for struct tags
69+
rules:
70+
json: snake
71+
72+
usestdlibvars:
73+
# To use http method string instead of the stdlib vars
74+
http-method: false
75+
76+
govet:
77+
# To enable all analyzers
78+
enable-all: true
79+
# To disable analyzers by name
80+
disable:
81+
- fieldalignment
82+
- shadow
83+
84+
gofumpt:
85+
# To use extra rules on top of gofmt
86+
extra-rules: true
87+
88+
forbidigo:
89+
forbid:
90+
- "fmt.Print*"
91+
92+
issues:
93+
exclude-use-default: false
94+
max-issues-per-linter: 0
95+
max-same-issues: 0
96+
exclude:
97+
- "exported: .*"
98+
- "package-comments: .*"

README.md

Lines changed: 194 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,195 @@
11
# go-struct-enum
2-
A fully featured Golang struct based enums
2+
3+
![Go Version](https://img.shields.io/github/go-mod/go-version/FabienMht/go-struct-enum.svg)
4+
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/FabienMht/go-struct-enum)
5+
[![Go Report Card](https://goreportcard.com/badge/github.com/FabienMht/go-struct-enum)](https://goreportcard.com/report/github.com/FabienMht/go-struct-enum)
6+
[![Sourcegraph](https://sourcegraph.com/github.com/FabienMht/go-struct-enum/-/badge.svg)](https://sourcegraph.com/github.com/FabienMht/go-struct-enum)
7+
[![Tag](https://img.shields.io/github/tag/FabienMht/go-struct-enum.svg)](https://github.com/FabienMht/go-struct-enum/tags)
8+
[![Contributors](https://img.shields.io/github/contributors/FabienMht/go-struct-enum)](https://github.com/FabienMht/go-struct-enum/graphs/contributors)
9+
[![License](https://img.shields.io/github/license/FabienMht/go-struct-enum)](./LICENSE)
10+
11+
A fully featured Golang struct based enums.
12+
It provides a simple way to declare enums and use them in structs.
13+
14+
**Enums are [harden](https://github.com/nikolaydubina/go-enum-example/tree/master) against:**
15+
- Arithmetics operations
16+
- Comparison operators except == and !=
17+
- Implicit cast of [untyped constants](https://medium.com/golangspec/untyped-constants-in-go-2c69eb519b5b) (use the based type instead of the enum type)
18+
19+
**An enum implements the following interfaces:**
20+
- `fmt.Stringer`
21+
- `json.Marshaler`
22+
- `json.Unmarshaler`
23+
- `sql.Scanner`
24+
- `driver.Valuer`
25+
26+
## Install
27+
28+
**Download it:**
29+
30+
```bash
31+
$ go get github.com/FabienMht/go-struct-enum
32+
```
33+
34+
**Add the following import:**
35+
36+
```go
37+
enum "github.com/FabienMht/go-struct-enum"
38+
```
39+
40+
## Usage
41+
42+
### Basic
43+
44+
Checkout the detailed example in the [documentation](https://pkg.go.dev/github.com/FabienMht/go-struct-enum#pkg-examples) for more information.
45+
46+
**Declare enum values:**
47+
48+
```go
49+
var (
50+
// Define States
51+
TestStateUnknown = &TestState{enum.New("")}
52+
TestStatePassed = &TestState{enum.New("passed")}
53+
TestStateSkipped = &TestState{enum.New("skipped")}
54+
TestStateFailed = &TestState{enum.New("failed")}
55+
56+
// Define the ordered list of states
57+
TestStates = []enum.Enummer[string]{
58+
TestStateUnknown,
59+
TestStatePassed,
60+
TestStateSkipped,
61+
TestStateFailed,
62+
}
63+
64+
// Define states parsers
65+
ParseTestState = enum.Parse(TestStates)
66+
MustParseTestState = enum.MustParse(TestStates)
67+
)
68+
69+
// Define the state enum
70+
type TestState struct {
71+
enum.Enum[string]
72+
}
73+
```
74+
75+
**Use enum values:**
76+
77+
```go
78+
// Parse a state
79+
state := ParseTestState("passed") // TestStatePassed
80+
// Or panic if the state is not valid
81+
state := MustParseTestState("passed") // TestStatePassed
82+
83+
// Get the state value
84+
state.Value() // "passed"
85+
// Check the enum value
86+
state.EqualValue("passed") // true
87+
```
88+
89+
**Use enum in structs:**
90+
91+
```go
92+
type Test struct {
93+
State *TestState `json:"state"`
94+
}
95+
96+
// Marshal a struct with an enum
97+
json.Marshal(&Test{State: TestStatePassed}) // {"state":"passed"}
98+
99+
// Unmarshal a struct with an enum
100+
var test Test
101+
json.Unmarshal([]byte(`{"state":"passed"}`), &test) // &Test{State: TestStatePassed}
102+
```
103+
104+
### Comparison
105+
106+
Checkout the detailed example in the [documentation](https://pkg.go.dev/github.com/FabienMht/go-struct-enum#pkg-examples) for more information.
107+
108+
**Define comparison functions:**
109+
110+
```go
111+
// Define the state enum
112+
type TestState struct {
113+
enum.Enum[string]
114+
}
115+
116+
func (ts *TestState) Equal(other *TestState) bool {
117+
return enum.Equal(ts, other)
118+
}
119+
120+
func (ts *TestState) GreaterThan(other *TestState) bool {
121+
return enum.GreaterThan(TestStates)(ts, other)
122+
}
123+
124+
func (ts *TestState) LessThan(other *TestState) bool {
125+
return enum.LessThan(TestStates)(ts, other)
126+
}
127+
128+
func (ts *TestState) GreaterThanOrEqual(other *TestState) bool {
129+
return enum.GreaterThanOrEqual(TestStates)(ts, other)
130+
}
131+
132+
func (ts *TestState) LessThanOrEqual(other *TestState) bool {
133+
return enum.LessThanOrEqual(TestStates)(ts, other)
134+
}
135+
```
136+
137+
**Use comparison functions:**
138+
139+
```go
140+
TestStatePassed.Equal(TestStatePassed) // true
141+
TestStatePassed.Equal(TestStateFailed) // false
142+
TestStatePassed.GreaterThan(TestStatePassed) // false
143+
TestStatePassed.GreaterThan(TestStateFailed) // false
144+
TestStatePassed.GreaterThanOrEqual(TestStatePassed) // true
145+
TestStatePassed.GreaterThanOrEqual(TestStateFailed) // false
146+
TestStatePassed.LessThan(TestStatePassed) // false
147+
TestStatePassed.LessThan(TestStateFailed) // true
148+
TestStatePassed.LessThanOrEqual(TestStatePassed) // true
149+
TestStatePassed.LessThanOrEqual(TestStateFailed) // true
150+
```
151+
152+
## Benchmark
153+
154+
```bash
155+
$ task bench
156+
task: [bench] go test -bench=. -benchmem
157+
goos: linux
158+
goarch: amd64
159+
pkg: github.com/FabienMht/go-struct-enum
160+
cpu: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
161+
BenchmarkParse-8 15764276 77.69 ns/op 48 B/op 1 allocs/op
162+
BenchmarkParsePrealloc-8 383380515 3.034 ns/op 0 B/op 0 allocs/op
163+
BenchmarkEqual-8 63047527 16.52 ns/op 0 B/op 0 allocs/op
164+
BenchmarkGreaterThan-8 6585123 187.9 ns/op 48 B/op 1 allocs/op
165+
BenchmarkGreaterThanPrealloc-8 10859983 108.9 ns/op 0 B/op 0 allocs/op
166+
BenchmarkGreaterThanOrEqual-8 6594724 184.5 ns/op 48 B/op 1 allocs/op
167+
BenchmarkGreaterThanOrEqualPrealloc-8 10677360 107.0 ns/op 0 B/op 0 allocs/op
168+
BenchmarkLessThan-8 6341217 183.0 ns/op 48 B/op 1 allocs/op
169+
BenchmarkLessThanPrealloc-8 10930384 107.0 ns/op 0 B/op 0 allocs/op
170+
BenchmarkLessThanOrEqualThan-8 6474268 182.1 ns/op 48 B/op 1 allocs/op
171+
BenchmarkLessThanOrEqualThanPrealloc-8 10892846 107.9 ns/op 0 B/op 0 allocs/op
172+
PASS
173+
ok github.com/FabienMht/go-struct-enum 14.543s
174+
```
175+
176+
## Contributing
177+
178+
Contributions are welcome ! Please open an issue or submit a pull request.
179+
180+
```bash
181+
# Install task
182+
$ go install github.com/go-task/task/v3/cmd/task@v3
183+
184+
# Install dev dependencies
185+
$ task dev
186+
187+
# Run linter
188+
$ task lint
189+
190+
# Run tests
191+
$ task test
192+
193+
# Run benchmarks
194+
$ task bench
195+
```

0 commit comments

Comments
 (0)