github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/graveler/ref/parse_ref.go (about)

     1  package ref
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strconv"
     7  
     8  	"github.com/treeverse/lakefs/pkg/graveler"
     9  )
    10  
    11  var modifiersRegexp = regexp.MustCompile("(^|[~^@$])[^^~@$]*")
    12  
    13  func parseRefModifier(buf string) (graveler.RefModifier, error) {
    14  	amount := 1
    15  	var err error
    16  	var typ graveler.RefModType
    17  	switch buf[0] {
    18  	case '~':
    19  		typ = graveler.RefModTypeTilde
    20  	case '^':
    21  		typ = graveler.RefModTypeCaret
    22  	case '$':
    23  		typ = graveler.RefModTypeDollar
    24  		if len(buf) > 1 {
    25  			return graveler.RefModifier{}, graveler.ErrInvalidRef
    26  		}
    27  	case '@':
    28  		typ = graveler.RefModTypeAt
    29  		if len(buf) > 1 {
    30  			return graveler.RefModifier{}, graveler.ErrInvalidRef
    31  		}
    32  	default:
    33  		return graveler.RefModifier{}, graveler.ErrInvalidRef
    34  	}
    35  
    36  	if len(buf) > 1 {
    37  		amount, err = strconv.Atoi(buf[1:])
    38  		if err != nil {
    39  			return graveler.RefModifier{}, fmt.Errorf("could not parse modifier %s: %w", buf, graveler.ErrInvalidRef)
    40  		}
    41  	}
    42  
    43  	return graveler.RefModifier{
    44  		Type:  typ,
    45  		Value: amount,
    46  	}, nil
    47  }
    48  
    49  func ParseRef(r graveler.Ref) (graveler.RawRef, error) {
    50  	ref := string(r)
    51  	parts := modifiersRegexp.FindAllString(ref, -1)
    52  	if len(parts) == 0 || len(parts[0]) == 0 {
    53  		return graveler.RawRef{}, graveler.ErrInvalidRef
    54  	}
    55  	baseRef := parts[0]
    56  	mods := make([]graveler.RefModifier, 0, len(parts)-1)
    57  	for _, part := range parts[1:] {
    58  		mod, err := parseRefModifier(part)
    59  		if err != nil {
    60  			return graveler.RawRef{}, err
    61  		}
    62  		mods = append(mods, mod)
    63  	}
    64  	return graveler.RawRef{
    65  		BaseRef:   baseRef,
    66  		Modifiers: mods,
    67  	}, nil
    68  }