github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/types/id.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 "strconv" 6 "strings" 7 8 "golang.org/x/xerrors" 9 ) 10 11 var idEncoder func(ID) string = func(i ID) string { return strconv.FormatInt(int64(i), 10) } 12 var idDecoder func(string) (ID, error) = func(s string) (ID, error) { 13 i, err := strconv.ParseInt(s, 10, 64) 14 if err != nil { 15 return 0, err 16 } 17 return ID(i), err 18 } 19 20 func Init(encode func(ID) string, decode func(string) (ID, error)) { 21 idEncoder = encode 22 idDecoder = decode 23 } 24 25 // ID is int64, useful for some convenient transform case. 26 // Example: 27 // json api, to protect real id, developer can embed this 28 // ID into a struct to do automatically transform int64 to 29 // string with encrypt. 30 type ID int64 31 32 func (i ID) MarshalText() (text []byte, err error) { 33 if i < 0 { 34 return nil, xerrors.Errorf("err: ID(%d) must greater than 0", i) 35 } 36 str := idEncoder(i) 37 return []byte(str), nil 38 } 39 40 func (i *ID) UnmarshalText(text []byte) error { 41 id, err := idDecoder(string(text)) 42 if err != nil { 43 return xerrors.Errorf("unmarshal id failed, %w", err) 44 } 45 46 *i = ID(id) 47 return nil 48 } 49 50 func (i ID) MarshalJSON() ([]byte, error) { 51 text, err := i.MarshalText() 52 if err != nil { 53 return nil, err 54 } 55 return json.Marshal(string(text)) 56 } 57 58 func (i *ID) UnmarshalJSON(data []byte) error { 59 var text string 60 err := json.Unmarshal(data, &text) 61 if err != nil { 62 return err 63 } 64 return i.UnmarshalText([]byte(text)) 65 } 66 67 func ParseIDList(str string) ([]ID, error) { 68 items := strings.Split(str, ",") 69 ids := make([]ID, 0, len(items)) 70 for _, item := range items { 71 id := new(ID) 72 err := id.UnmarshalText([]byte(item)) 73 if err != nil { 74 continue 75 } 76 ids = append(ids, *id) 77 } 78 return ids, nil 79 } 80 81 func ParseInt64List(str string) ([]int64, error) { 82 ids, err := ParseIDList(str) 83 if err != nil { 84 return nil, err 85 } 86 int64s := make([]int64, 0, len(ids)) 87 for _, id := range ids { 88 int64s = append(int64s, int64(id)) 89 } 90 return int64s, nil 91 } 92 93 func FormatIDList(ids []ID) (string, error) { 94 items := make([]string, 0, len(ids)) 95 for _, id := range ids { 96 item, err := id.MarshalJSON() 97 if err != nil { 98 continue 99 } 100 items = append(items, string(item)) 101 } 102 return strings.Join(items, ","), nil 103 }