From bfbb15ea57eea90dd25e7f1e78607e5bcab73979 Mon Sep 17 00:00:00 2001 From: Maxim Lebedev Date: Thu, 30 Dec 2021 05:42:54 +0500 Subject: [PATCH] :label: Added Action domain --- internal/domain/action.go | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 internal/domain/action.go diff --git a/internal/domain/action.go b/internal/domain/action.go new file mode 100644 index 0000000..9b68e65 --- /dev/null +++ b/internal/domain/action.go @@ -0,0 +1,68 @@ +package domain + +import ( + "errors" + "fmt" + "strconv" + "strings" +) + +// NOTE(toby3d): Encapsulate enums in structs for extra compile-time safety: +// https://threedots.tech/post/safer-enums-in-go/#struct-based-enums +type Action struct { + slug string +} + +//nolint: gochecknoglobals // NOTE(toby3d): structs cannot be constants +var ( + ActionUndefined = Action{slug: ""} + ActionRevoke = Action{slug: "revoke"} + ActionTicket = Action{slug: "ticket"} +) + +var ErrActionUnknown = errors.New("unknown action method") + +// ParseAction parse string identifier of action into struct enum. +func ParseAction(slug string) (Action, error) { + switch strings.ToLower(slug) { + case ActionRevoke.slug: + return ActionRevoke, nil + case ActionTicket.slug: + return ActionTicket, nil + } + + return ActionUndefined, fmt.Errorf("%w: %s", ErrActionUnknown, slug) +} + +// UnmarshalForm implements custom unmarshler for form values. +func (a *Action) UnmarshalForm(v []byte) error { + action, err := ParseAction(string(v)) + if err != nil { + return fmt.Errorf("action: %w", err) + } + + *a = action + + return nil +} + +func (a *Action) UnmarshalJSON(v []byte) error { + src, err := strconv.Unquote(string(v)) + if err != nil { + return err + } + + action, err := ParseAction(src) + if err != nil { + return fmt.Errorf("action: %w", err) + } + + *a = action + + return nil +} + +// String returns string representation of action. +func (a Action) String() string { + return a.slug +}