1package identity
2
3import (
4 "encoding/json"
5 "errors"
6 "fmt"
7 "strings"
8)
9
10var ErrIdentityNotExist = errors.New("identity doesn't exist")
11
12type ErrMultipleMatch struct {
13 Matching []string
14}
15
16func (e ErrMultipleMatch) Error() string {
17 return fmt.Sprintf("Multiple matching identities found:\n%s", strings.Join(e.Matching, "\n"))
18}
19
20// Custom unmarshaling function to allow package user to delegate
21// the decoding of an Identity and distinguish between an Identity
22// and a Bare.
23//
24// If the given message has a "id" field, it's considered being a proper Identity.
25func UnmarshalJSON(raw json.RawMessage) (Interface, error) {
26 aux := &IdentityStub{}
27
28 // First try to decode and load as a normal Identity
29 err := json.Unmarshal(raw, &aux)
30 if err == nil && aux.Id() != "" {
31 return aux, nil
32 }
33
34 // abort if we have an error other than the wrong type
35 if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok {
36 return nil, err
37 }
38
39 // Fallback on a legacy Bare identity
40 b := &Bare{}
41
42 err = json.Unmarshal(raw, b)
43 if err == nil && (b.name != "" || b.login != "") {
44 return b, nil
45 }
46
47 // abort if we have an error other than the wrong type
48 if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok {
49 return nil, err
50 }
51
52 return nil, fmt.Errorf("unknown identity type")
53}