package resourcename import ( "strings" ) // Scanner scans a resource name. type Scanner struct { name string start, end int serviceStart, serviceEnd int full bool } // Init initializes the scanner. func (s *Scanner) Init(name string) { s.name = name s.start, s.end = 0, 0 s.full = false } // Scan to the next segment. func (s *Scanner) Scan() bool { switch s.end { case len(s.name): return false case 0: // Special case for full resource names. if strings.HasPrefix(s.name, "//") { s.full = true s.start, s.end = 2, 2 nextSlash := strings.IndexByte(s.name[s.start:], '/') if nextSlash == -1 { s.serviceStart, s.serviceEnd = s.start, len(s.name) s.start, s.end = len(s.name), len(s.name) return false } s.serviceStart, s.serviceEnd = s.start, s.start+nextSlash s.start, s.end = s.start+nextSlash+1, s.start+nextSlash+1 } else if strings.HasPrefix(s.name, "/") { s.start = s.end + 1 // start past beginning slash } default: s.start = s.end + 1 // start past latest slash } if nextSlash := strings.IndexByte(s.name[s.start:], '/'); nextSlash == -1 { s.end = len(s.name) } else { s.end = s.start + nextSlash } return true } // Start returns the start index (inclusive) of the current segment. func (s *Scanner) Start() int { return s.start } // End returns the end index (exclusive) of the current segment. func (s *Scanner) End() int { return s.end } // Segment returns the current segment. func (s *Scanner) Segment() Segment { return Segment(s.name[s.start:s.end]) } // Full returns true if the scanner has detected a full resource name. func (s *Scanner) Full() bool { return s.full } // ServiceName returns the service name, when the scanner has detected a full resource name. func (s *Scanner) ServiceName() string { return s.name[s.serviceStart:s.serviceEnd] }