auth/internal/domain/action/action.go

89 lines
1.9 KiB
Go

package action
import (
"errors"
"fmt"
"strconv"
"strings"
"source.toby3d.me/toby3d/auth/internal/common"
)
// Action represent action for token endpoint supported by IndieAuth.
//
// 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 {
action string
}
//nolint:gochecknoglobals // structs cannot be constants
var (
Und = Action{} // "und"
// Revoke represent action for revoke token.
Revoke = Action{"revoke"} // "revoke"
// Ticket represent action for TicketAuth extension.
Ticket = Action{"ticket"} // "ticket"
)
var ErrActionSyntax error = errors.New("unknown action method")
//nolint:gochecknoglobals
var uidsActions = map[string]Action{
Revoke.action: Revoke,
Ticket.action: Ticket,
}
// Parse parse string identifier of action into struct enum.
func Parse(uid string) (Action, error) {
if action, ok := uidsActions[uid]; ok {
return action, nil
}
return Und, fmt.Errorf("%w: %s", ErrActionSyntax, uid)
}
// UnmarshalForm implements custom unmarshler for form values.
func (a *Action) UnmarshalForm(v []byte) error {
parsed, err := Parse(strings.ToLower(string(v)))
if err != nil {
return fmt.Errorf("Action: UnmarshalForm: %w", err)
}
*a = parsed
return nil
}
// UnmarshalJSON implements custom unmarshler for JSON.
func (a *Action) UnmarshalJSON(v []byte) error {
unquoted, err := strconv.Unquote(string(v))
if err != nil {
return fmt.Errorf("Action: UnmarshalJSON: %w", err)
}
parsed, err := Parse(strings.ToLower(unquoted))
if err != nil {
return fmt.Errorf("Action: UnmarshalJSON: %w", err)
}
*a = parsed
return nil
}
// String returns string representation of action.
func (a Action) String() string {
if a == Und {
return common.Und
}
return a.action
}
func (a Action) GoString() string {
return "action.Action(" + a.String() + ")"
}