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 }