🚧 Scaffold stuff

This commit is contained in:
Dan Jones 2025-04-21 11:07:53 -05:00
commit a73435601c
6 changed files with 212 additions and 0 deletions

25
.gitignore vendored Normal file
View file

@ -0,0 +1,25 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Dependency directories
vendor/
# Go workspace file
go.work
go.work.sum
# env file
.env
build/
.task/

39
.golangci.yaml Normal file
View file

@ -0,0 +1,39 @@
linters:
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused
- copyloopvar
- dupl
- err113
- errname
- exptostd
- fatcontext
- funlen
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- gosec
- perfsprint
- testifylint
linters-settings:
testifylint:
enable-all: true
disable:
- require-error
gocognit:
min-complexity: 5
gocyclo:
min-complexity: 5
gocritic:
enable-all: true
settings:
hugeParam:
sizeThreshold: 255

62
Taskfile.yml Normal file
View file

@ -0,0 +1,62 @@
version: '3'
tasks:
default:
cmds:
- task: fmt
- task: test
- task: lint
fmt:
desc: Format go code
sources:
- '**/*.go'
cmds:
- go fmt ./...
- go mod tidy
gen:
desc: Generate files
sources:
- '**/*.go'
cmds:
- go generate ./...
lint:
desc: Do static analysis
sources:
- '**/*.go'
cmds:
- golangci-lint run
test:
desc: Run unit tests
deps: [fmt]
sources:
- '**/*.go'
generates:
- build/cover.out
cmds:
- go test -race -cover -coverprofile build/cover.out ./...
coverage-report:
desc: Build coverage report
deps: [test]
sources:
- build/cover.out
generates:
- build/cover.html
cmds:
- go tool cover -html=build/cover.out -o build/cover.html
serve-report:
desc: Serve the coverage report
deps: [coverage-report]
cmds:
- ip addr list | grep inet
- php -S 0.0.0.0:3434 -t build
serve-docs:
desc: Serve the current docs
cmds:
- godoc -http=0.0.0.0:3434 -play

31
cache.go Normal file
View file

@ -0,0 +1,31 @@
package ezcache
import (
"errors"
"time"
)
// ErrInvalidFetcher is returned by Cache.SetFetcher if the fetcher is invalid.
// This is probably only going to happen if it's nil.
var ErrInvalidFetcher = errors.New("invalid fetcher")
// ErrInvalidDuration is returned by Cache.SetExpiry if the duration is invalid.
// This is usually if it is <= 0.
var ErrInvalidDuration = errors.New("invalid duration")
type Fetcher[K comparable, V any] func(K) (V, error)
// Cache represents a Cache for values.
type Cache[K comparable, V any] interface {
// Get will fetch the value for key. If in the cache, it will fetch the cached value.
// If not in the cache, it will use the Fetcher.
// It may return [ErrInvalidFetcher], but if an error is returned, it's probably returned by the
// [Fetcher] itself.
Get(key K) (V, error)
// SetFetcher sets the fetcher for this [Cache].
SetFetcher(f Fetcher[K, V]) error
// SetExpiry sets the expiry for this [Cache].
SetExpiry(d time.Duration) error
}

52
ezcache.go Normal file
View file

@ -0,0 +1,52 @@
package ezcache
import (
"errors"
"time"
)
type ezc[K comparable, V any] struct {
fetch Fetcher[K, V]
exp time.Duration
cache map[K]V
setTime map[K]time.Time
}
func New[K comparable, V any](fetcher Fetcher[K, V], exp time.Duration) (Cache[K, V], error) {
c := &ezc[K, V]{}
err := c.SetFetcher(fetcher)
if err != nil {
return nil, err
}
err = c.SetExpiry(exp)
if err != nil {
return nil, err
}
c.cache = make(map[K]V)
c.setTime = make(map[K]time.Time)
return c, nil
}
var errUnimpl = errors.New("unimplemented")
func (c *ezc[K, V]) Get(key K) (V, error) {
var val V
return val, errUnimpl
}
func (c *ezc[K, V]) SetFetcher(f Fetcher[K, V]) error {
if f == nil {
return ErrInvalidFetcher
}
c.fetch = f
return nil
}
func (c *ezc[K, V]) SetExpiry(exp time.Duration) error {
if exp <= 0 {
return ErrInvalidDuration
}
c.exp = exp
return nil
}

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module codeberg.org/danjones000/ezcache
go 1.23.7