github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/kit/httptransport/transformer/util_path_pattern.go (about)

     1  package transformer
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/julienschmidt/httprouter"
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  func ParamsFromMap(m map[string]string) httprouter.Params {
    11  	params := httprouter.Params{}
    12  	for k, v := range m {
    13  		params = append(params, httprouter.Param{
    14  			Key:   k,
    15  			Value: v,
    16  		})
    17  	}
    18  	return params
    19  }
    20  
    21  func NewPathnamePattern(pattern string) *PathnamePattern {
    22  	parts := ToPathParts(pattern)
    23  
    24  	idxKeys := map[int]string{}
    25  
    26  	for i, p := range parts {
    27  		if p[0] == ':' {
    28  			idxKeys[i] = p[1:]
    29  		}
    30  	}
    31  
    32  	return &PathnamePattern{
    33  		parts,
    34  		idxKeys,
    35  	}
    36  }
    37  
    38  type PathnamePattern struct {
    39  	parts   []string
    40  	idxKeys map[int]string
    41  }
    42  
    43  func (pp *PathnamePattern) String() string { return "/" + strings.Join(pp.parts, "/") }
    44  
    45  func (pp *PathnamePattern) Stringify(params httprouter.Params) string {
    46  	if len(pp.idxKeys) == 0 {
    47  		return pp.String()
    48  	}
    49  
    50  	parts := append([]string{}, pp.parts...)
    51  
    52  	for idx, key := range pp.idxKeys {
    53  		v := params.ByName(key)
    54  		if v == "" {
    55  			v = "-"
    56  		}
    57  		parts[idx] = v
    58  	}
    59  
    60  	return (&PathnamePattern{parts: parts}).String()
    61  }
    62  
    63  func (pp *PathnamePattern) Parse(pathname string) (params httprouter.Params, err error) {
    64  	parts := ToPathParts(pathname)
    65  
    66  	if len(parts) != len(pp.parts) {
    67  		return nil, errors.Errorf("pathname %s is not match %s", pathname, pp)
    68  	}
    69  
    70  	for idx, part := range pp.parts {
    71  		if key, ok := pp.idxKeys[idx]; ok {
    72  			params = append(params, httprouter.Param{
    73  				Key:   key,
    74  				Value: parts[idx],
    75  			})
    76  		} else if part != parts[idx] {
    77  			return nil, errors.Errorf("pathname %s is not match %s", pathname, pp)
    78  		}
    79  	}
    80  
    81  	return
    82  }
    83  
    84  func ToPathParts(p string) []string {
    85  	p = httprouter.CleanPath(p)
    86  	if p[0] == '/' {
    87  		p = p[1:]
    88  	}
    89  	if p == "" {
    90  		return make([]string, 0)
    91  	}
    92  	return strings.Split(p, "/")
    93  }