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  }