...

Source file src/go.einride.tech/aip/resourcename/scanner.go

Documentation: go.einride.tech/aip/resourcename

     1  package resourcename
     2  
     3  import (
     4  	"strings"
     5  )
     6  
     7  // Scanner scans a resource name.
     8  type Scanner struct {
     9  	name                     string
    10  	start, end               int
    11  	serviceStart, serviceEnd int
    12  	full                     bool
    13  }
    14  
    15  // Init initializes the scanner.
    16  func (s *Scanner) Init(name string) {
    17  	s.name = name
    18  	s.start, s.end = 0, 0
    19  	s.full = false
    20  }
    21  
    22  // Scan to the next segment.
    23  func (s *Scanner) Scan() bool {
    24  	switch s.end {
    25  	case len(s.name):
    26  		return false
    27  	case 0:
    28  		// Special case for full resource names.
    29  		if strings.HasPrefix(s.name, "//") {
    30  			s.full = true
    31  			s.start, s.end = 2, 2
    32  			nextSlash := strings.IndexByte(s.name[s.start:], '/')
    33  			if nextSlash == -1 {
    34  				s.serviceStart, s.serviceEnd = s.start, len(s.name)
    35  				s.start, s.end = len(s.name), len(s.name)
    36  				return false
    37  			}
    38  			s.serviceStart, s.serviceEnd = s.start, s.start+nextSlash
    39  			s.start, s.end = s.start+nextSlash+1, s.start+nextSlash+1
    40  		} else if strings.HasPrefix(s.name, "/") {
    41  			s.start = s.end + 1 // start past beginning slash
    42  		}
    43  	default:
    44  		s.start = s.end + 1 // start past latest slash
    45  	}
    46  	if nextSlash := strings.IndexByte(s.name[s.start:], '/'); nextSlash == -1 {
    47  		s.end = len(s.name)
    48  	} else {
    49  		s.end = s.start + nextSlash
    50  	}
    51  	return true
    52  }
    53  
    54  // Start returns the start index (inclusive) of the current segment.
    55  func (s *Scanner) Start() int {
    56  	return s.start
    57  }
    58  
    59  // End returns the end index (exclusive) of the current segment.
    60  func (s *Scanner) End() int {
    61  	return s.end
    62  }
    63  
    64  // Segment returns the current segment.
    65  func (s *Scanner) Segment() Segment {
    66  	return Segment(s.name[s.start:s.end])
    67  }
    68  
    69  // Full returns true if the scanner has detected a full resource name.
    70  func (s *Scanner) Full() bool {
    71  	return s.full
    72  }
    73  
    74  // ServiceName returns the service name, when the scanner has detected a full resource name.
    75  func (s *Scanner) ServiceName() string {
    76  	return s.name[s.serviceStart:s.serviceEnd]
    77  }
    78  

View as plain text