src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

arn.go (2113B)


      1 package awsrulesfn
      2 
      3 import (
      4 	"strings"
      5 )
      6 
      7 // ARN provides AWS ARN components broken out into a data structure.
      8 type ARN struct {
      9 	Partition  string
     10 	Service    string
     11 	Region     string
     12 	AccountId  string
     13 	ResourceId OptionalStringSlice
     14 }
     15 
     16 const (
     17 	arnDelimiters      = ":"
     18 	resourceDelimiters = "/:"
     19 	arnSections        = 6
     20 	arnPrefix          = "arn:"
     21 
     22 	// zero-indexed
     23 	sectionPartition = 1
     24 	sectionService   = 2
     25 	sectionRegion    = 3
     26 	sectionAccountID = 4
     27 	sectionResource  = 5
     28 )
     29 
     30 // ParseARN returns an [ARN] value parsed from the input string provided. If
     31 // the ARN cannot be parsed nil will be returned, and error added to
     32 // [ErrorCollector].
     33 func ParseARN(input string) *ARN {
     34 	if !strings.HasPrefix(input, arnPrefix) {
     35 		return nil
     36 	}
     37 
     38 	sections := strings.SplitN(input, arnDelimiters, arnSections)
     39 	if numSections := len(sections); numSections != arnSections {
     40 		return nil
     41 	}
     42 
     43 	if sections[sectionPartition] == "" {
     44 		return nil
     45 	}
     46 	if sections[sectionService] == "" {
     47 		return nil
     48 	}
     49 	if sections[sectionResource] == "" {
     50 		return nil
     51 	}
     52 
     53 	return &ARN{
     54 		Partition:  sections[sectionPartition],
     55 		Service:    sections[sectionService],
     56 		Region:     sections[sectionRegion],
     57 		AccountId:  sections[sectionAccountID],
     58 		ResourceId: splitResource(sections[sectionResource]),
     59 	}
     60 }
     61 
     62 // splitResource splits the resource components by the ARN resource delimiters.
     63 func splitResource(v string) []string {
     64 	var parts []string
     65 	var offset int
     66 
     67 	for offset <= len(v) {
     68 		idx := strings.IndexAny(v[offset:], "/:")
     69 		if idx < 0 {
     70 			parts = append(parts, v[offset:])
     71 			break
     72 		}
     73 		parts = append(parts, v[offset:idx+offset])
     74 		offset += idx + 1
     75 	}
     76 
     77 	return parts
     78 }
     79 
     80 // OptionalStringSlice provides a helper to safely get the index of a string
     81 // slice that may be out of bounds. Returns pointer to string if index is
     82 // valid. Otherwise returns nil.
     83 type OptionalStringSlice []string
     84 
     85 // Get returns a string pointer of the string at index i if the index is valid.
     86 // Otherwise returns nil.
     87 func (s OptionalStringSlice) Get(i int) *string {
     88 	if i < 0 || i >= len(s) {
     89 		return nil
     90 	}
     91 
     92 	v := s[i]
     93 	return &v
     94 }