opentofu/svchost/label_iter.go
Martin Atkins db08ee4ac5 svchost: new package for wrangling service hostnames
We're starting to expose a number of so-called "Terraform-native services"
that can be offered under a friendly hostname. The first of these will
be module registry services, as they expand from the public
Terraform Registry to private registry services within Terraform
Enterprise and elsewhere.

This package is for wrangling these "friendly hostnames", which start
their lives as user-specified unicode strings, can be converted to
Punycode for storage and comparison, and can in turn be converted back
into normalized unicode for display to the user.
2017-10-19 11:18:43 -07:00

70 lines
1.4 KiB
Go

package svchost
import (
"strings"
)
// A labelIter allows iterating over domain name labels.
//
// This type is copied from golang.org/x/net/idna, where it is used
// to segment hostnames into their separate labels for analysis. We use
// it for the same purpose here, in ForComparison.
type labelIter struct {
orig string
slice []string
curStart int
curEnd int
i int
}
func (l *labelIter) reset() {
l.curStart = 0
l.curEnd = 0
l.i = 0
}
func (l *labelIter) done() bool {
return l.curStart >= len(l.orig)
}
func (l *labelIter) result() string {
if l.slice != nil {
return strings.Join(l.slice, ".")
}
return l.orig
}
func (l *labelIter) label() string {
if l.slice != nil {
return l.slice[l.i]
}
p := strings.IndexByte(l.orig[l.curStart:], '.')
l.curEnd = l.curStart + p
if p == -1 {
l.curEnd = len(l.orig)
}
return l.orig[l.curStart:l.curEnd]
}
// next sets the value to the next label. It skips the last label if it is empty.
func (l *labelIter) next() {
l.i++
if l.slice != nil {
if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" {
l.curStart = len(l.orig)
}
} else {
l.curStart = l.curEnd + 1
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
l.curStart = len(l.orig)
}
}
}
func (l *labelIter) set(s string) {
if l.slice == nil {
l.slice = strings.Split(l.orig, ".")
}
l.slice[l.i] = s
}