From 67a3752e176790e82a48706236f889cab4f8913d Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 11 Aug 2019 14:08:03 +0200 Subject: bug,entity: use a dedicated type to store IDs --- entity/err.go | 1 + entity/id.go | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ entity/interface.go | 4 +--- 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 entity/err.go create mode 100644 entity/id.go (limited to 'entity') diff --git a/entity/err.go b/entity/err.go new file mode 100644 index 00000000..9356433d --- /dev/null +++ b/entity/err.go @@ -0,0 +1 @@ +package entity diff --git a/entity/id.go b/entity/id.go new file mode 100644 index 00000000..7fa1785a --- /dev/null +++ b/entity/id.go @@ -0,0 +1,65 @@ +package entity + +import ( + "fmt" + "io" + "strings" + + "github.com/pkg/errors" +) + +const IdLengthSHA1 = 40 +const IdLengthSHA256 = 64 +const humanIdLength = 7 + +const UnsetId = Id("unset") + +// Id is an identifier for an entity or part of an entity +type Id string + +func (i Id) String() string { + return string(i) +} + +func (i Id) Human() string { + format := fmt.Sprintf("%%.%ds", humanIdLength) + return fmt.Sprintf(format, i) +} + +func (i Id) HasPrefix(prefix string) bool { + return strings.HasPrefix(string(i), prefix) +} + +// UnmarshalGQL implement the Unmarshaler interface for gqlgen +func (i *Id) UnmarshalGQL(v interface{}) error { + _, ok := v.(string) + if !ok { + return fmt.Errorf("IDs must be strings") + } + + *i = v.(Id) + + if err := i.Validate(); err != nil { + return errors.Wrap(err, "invalid ID") + } + + return nil +} + +// MarshalGQL implement the Marshaler interface for gqlgen +func (i Id) MarshalGQL(w io.Writer) { + _, _ = w.Write([]byte(`"` + i.String() + `"`)) +} + +// IsValid tell if the Id is valid +func (i Id) Validate() error { + if len(i) != IdLengthSHA1 && len(i) != IdLengthSHA256 { + return fmt.Errorf("invalid length") + } + for _, r := range i { + if (r < 'a' || r > 'z') && (r < '0' || r > '9') { + return fmt.Errorf("invalid character") + } + } + return nil +} diff --git a/entity/interface.go b/entity/interface.go index 62b92a58..dd5d69b1 100644 --- a/entity/interface.go +++ b/entity/interface.go @@ -2,7 +2,5 @@ package entity type Interface interface { // Id return the Entity identifier - Id() string - // HumanId return the Entity identifier truncated for human consumption - HumanId() string + Id() Id } -- cgit