<commit_before>/*
Copyright 2020 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package slos

import (
	"math"
	"time"

	"github.com/prometheus/common/model"
	"k8s.io/klog"
	"k8s.io/perf-tests/clusterloader2/pkg/measurement"
	"k8s.io/perf-tests/clusterloader2/pkg/measurement/common"
	measurementutil "k8s.io/perf-tests/clusterloader2/pkg/measurement/util"
	"k8s.io/perf-tests/clusterloader2/pkg/util"
)

const (
	windowsResourceUsagePrometheusMeasurementName = "WindowsResourceUsagePrometheus"
	// get top 10 non-system processes with highest cpu usage within 1min query window size
	cpuUsageQueryTop10 = `topk(10, sum by (process) (irate(wmi_process_cpu_time_total{process!~"Idle|Total|System"}[5m]) / on(job) group_left wmi_cs_logical_processors) * 100)`
	// cpu usage metrics file name prefix
	cpuUsageMetricsName = "WindowsCPUUsagePrometheus"
	// get top 10 non-system processes with highest memory usage
	memoryUsageQueryTop10 = `topk(10, sum(wmi_process_working_set{process!~"Idle|Total|System"}) by (process))`
	// memory usage metrics file name prefix
	memoryUsageMetricsName                    = "WindowsMemoryUsagePrometheus"
	currentWindowsResourceUsageMetricsVersion = "v1"
)

type convertFunc func([]*model.Sample) *measurementutil.PerfData
type windowsResourceUsageGatherer struct{}

func (w *windowsResourceUsageGatherer) Configure(config *measurement.Config) error {
	return nil
}

func (w *windowsResourceUsageGatherer) IsEnabled(config *measurement.Config) bool {
	return true
}

func (w *windowsResourceUsageGatherer) String() string {
	return windowsResourceUsagePrometheusMeasurementName
}

func init() {
	create := func() measurement.Measurement {
		return common.CreatePrometheusMeasurement(&windowsResourceUsageGatherer{})
	}
	if err := measurement.Register(windowsResourceUsagePrometheusMeasurementName, create); err != nil {
		klog.Fatalf("Cannot register %s: %v", windowsResourceUsagePrometheusMeasurementName, err)
	}
}

func convertToCPUPerfData(samples []*model.Sample) *measurementutil.PerfData {
	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
	for _, sample := range samples {
		item := measurementutil.DataItem{
			Data: map[string]float64{
				"CPU_Usage": math.Round(float64(sample.Value)*100) / 100,
			},
			Unit: "%",
			Labels: map[string]string{
				"Process": string(sample.Metric["process"]),
			},
		}
		perfData.DataItems = append(perfData.DataItems, item)
	}
	return perfData
}

func convertToMemoryPerfData(samples []*model.Sample) *measurementutil.PerfData {
	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
	for _, sample := range samples {
		item := measurementutil.DataItem{
			Data: map[string]float64{
				"Memory_Usage": math.Round(float64(sample.Value)*100/(1024*1024)) / 100,
			},
			Unit: "MB",
			Labels: map[string]string{
				"Process": string(sample.Metric["process"]),
			},
		}
		perfData.DataItems = append(perfData.DataItems, item)
	}
	return perfData
}

func getSummary(query string, converter convertFunc, metricsName string, measurementTime time.Time, executor common.QueryExecutor, config *measurement.Config) (measurement.Summary, error) {
	samples, err := executor.Query(query, measurementTime)
	if err != nil {
		return nil, err
	}
	content, err := util.PrettyPrintJSON(converter(samples))
	if err != nil {
		return nil, err
	}
	summaryName, err := util.GetStringOrDefault(config.Params, "summaryName", metricsName)
	if err != nil {
		return nil, err
	}
	return measurement.CreateSummary(summaryName, "json", content), nil
}

// Gather gathers the metrics and convert to json summary
func (w *windowsResourceUsageGatherer) Gather(executor common.QueryExecutor, startTime, endTime time.Time, config *measurement.Config) ([]measurement.Summary, error) {
	cpuSummary, err := getSummary(cpuUsageQueryTop10, convertToCPUPerfData, cpuUsageMetricsName, endTime, executor, config)
	if err != nil {
		return nil, err
	}
	memorySummary, err := getSummary(memoryUsageQueryTop10, convertToMemoryPerfData, memoryUsageMetricsName, endTime, executor, config)
	if err != nil {
		return nil, err
	}
	return []measurement.Summary{cpuSummary, memorySummary}, nil
}
<commit_msg>Use Windows Exporter metrics names<commit_after>/*
Copyright 2020 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package slos

import (
	"math"
	"time"

	"github.com/prometheus/common/model"
	"k8s.io/klog"
	"k8s.io/perf-tests/clusterloader2/pkg/measurement"
	"k8s.io/perf-tests/clusterloader2/pkg/measurement/common"
	measurementutil "k8s.io/perf-tests/clusterloader2/pkg/measurement/util"
	"k8s.io/perf-tests/clusterloader2/pkg/util"
)

const (
	windowsResourceUsagePrometheusMeasurementName = "WindowsResourceUsagePrometheus"
	// get top 10 non-system processes with highest cpu usage within 1min query window size
	cpuUsageQueryTop10 = `topk(10, sum by (process) (irate(windows_process_cpu_time_total{process!~"Idle|Total|System"}[5m]) / on(job) group_left windows_cs_logical_processors) * 100)`
	// cpu usage metrics file name prefix
	cpuUsageMetricsName = "WindowsCPUUsagePrometheus"
	// get top 10 non-system processes with highest memory usage
	memoryUsageQueryTop10 = `topk(10, sum(windows_process_working_set_bytes{process!~"Idle|Total|System"}) by (process))`
	// memory usage metrics file name prefix
	memoryUsageMetricsName                    = "WindowsMemoryUsagePrometheus"
	currentWindowsResourceUsageMetricsVersion = "v1"
)

type convertFunc func([]*model.Sample) *measurementutil.PerfData
type windowsResourceUsageGatherer struct{}

func (w *windowsResourceUsageGatherer) Configure(config *measurement.Config) error {
	return nil
}

func (w *windowsResourceUsageGatherer) IsEnabled(config *measurement.Config) bool {
	return true
}

func (w *windowsResourceUsageGatherer) String() string {
	return windowsResourceUsagePrometheusMeasurementName
}

func init() {
	create := func() measurement.Measurement {
		return common.CreatePrometheusMeasurement(&windowsResourceUsageGatherer{})
	}
	if err := measurement.Register(windowsResourceUsagePrometheusMeasurementName, create); err != nil {
		klog.Fatalf("Cannot register %s: %v", windowsResourceUsagePrometheusMeasurementName, err)
	}
}

func convertToCPUPerfData(samples []*model.Sample) *measurementutil.PerfData {
	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
	for _, sample := range samples {
		item := measurementutil.DataItem{
			Data: map[string]float64{
				"CPU_Usage": math.Round(float64(sample.Value)*100) / 100,
			},
			Unit: "%",
			Labels: map[string]string{
				"Process": string(sample.Metric["process"]),
			},
		}
		perfData.DataItems = append(perfData.DataItems, item)
	}
	return perfData
}

func convertToMemoryPerfData(samples []*model.Sample) *measurementutil.PerfData {
	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
	for _, sample := range samples {
		item := measurementutil.DataItem{
			Data: map[string]float64{
				"Memory_Usage": math.Round(float64(sample.Value)*100/(1024*1024)) / 100,
			},
			Unit: "MB",
			Labels: map[string]string{
				"Process": string(sample.Metric["process"]),
			},
		}
		perfData.DataItems = append(perfData.DataItems, item)
	}
	return perfData
}

func getSummary(query string, converter convertFunc, metricsName string, measurementTime time.Time, executor common.QueryExecutor, config *measurement.Config) (measurement.Summary, error) {
	samples, err := executor.Query(query, measurementTime)
	if err != nil {
		return nil, err
	}
	content, err := util.PrettyPrintJSON(converter(samples))
	if err != nil {
		return nil, err
	}
	summaryName, err := util.GetStringOrDefault(config.Params, "summaryName", metricsName)
	if err != nil {
		return nil, err
	}
	return measurement.CreateSummary(summaryName, "json", content), nil
}

// Gather gathers the metrics and convert to json summary
func (w *windowsResourceUsageGatherer) Gather(executor common.QueryExecutor, startTime, endTime time.Time, config *measurement.Config) ([]measurement.Summary, error) {
	cpuSummary, err := getSummary(cpuUsageQueryTop10, convertToCPUPerfData, cpuUsageMetricsName, endTime, executor, config)
	if err != nil {
		return nil, err
	}
	memorySummary, err := getSummary(memoryUsageQueryTop10, convertToMemoryPerfData, memoryUsageMetricsName, endTime, executor, config)
	if err != nil {
		return nil, err
	}
	return []measurement.Summary{cpuSummary, memorySummary}, nil
}
<|endoftext|>


<commit_before>package fullerene

import (
	"time"
)

type Fullerene struct {
	t time.Time
}

func Now() Fullerene {
	return Fullerene{
		t: time.Now(),
	}
}

func (fr Fullerene) Date() (year int, month time.Month, day int) {
	return fr.t.Date()
}

func (fr Fullerene) After(u Fullerene) bool {
	return fr.t.After(u.t)
}

func (fr Fullerene) Before(u Fullerene) bool {
	return fr.t.Before(u.t)
}

func (fr Fullerene) Equal(u Fullerene) bool {
	return fr.t.Equal(u.t)
}

func (fr Fullerene) IsZero() bool {
	return fr.t.IsZero()
}

func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) Fullerene {
	return Fullerene{t: time.Date(year, month, day, hour, min, sec, nsec, loc)}
}

func (fr Fullerene) IsLeapYear() bool {
	y, _, _ := fr.Date()
	if y%4 != 0 {
		return false
	}
	if y%100 == 0 && y%400 != 0 {
		return false
	}
	return true
}

func (fr Fullerene) IsLeapDay() bool {
	_, m, d := fr.Date()
	if m == 2 && d == 29 {
		return true
	}
	return false
}

func (fr Fullerene) IsBirthday(targetTime Fullerene, beforeDayIfLeap bool) bool {
	_, m, d := fr.Date()           // birthday
	_, mm, dd := targetTime.Date() // check if it is birthday.
	if m == mm && d == dd && !fr.IsLeapDay() {
		// consider leap year.
		return true
	}

	// there are countries which a person get old at the day before leap day, and the day after in a leap year.
	return fr.isBirthdayEx(targetTime, beforeDayIfLeap)
}

func (fr Fullerene) isBirthdayEx(targetTime Fullerene, beforeDayIfLeap bool) bool {
	_, m, d := targetTime.Date()
	if targetTime.IsLeapYear() {
		return false
	}
	if beforeDayIfLeap && m == 2 && d == 28 {
		return true
	}
	if !beforeDayIfLeap && m == 3 && d == 1 {
		return true
	}
	return false
}
<commit_msg>Add each method to get year, month, day.<commit_after>package fullerene

import (
	"time"
)

type Fullerene struct {
	t time.Time
}

func Now() Fullerene {
	return Fullerene{
		t: time.Now(),
	}
}

func (fr Fullerene) Date() (year int, month time.Month, day int) {
	return fr.t.Date()
}

func (fr Fullerene) After(u Fullerene) bool {
	return fr.t.After(u.t)
}

func (fr Fullerene) Before(u Fullerene) bool {
	return fr.t.Before(u.t)
}

func (fr Fullerene) Equal(u Fullerene) bool {
	return fr.t.Equal(u.t)
}

func (fr Fullerene) IsZero() bool {
	return fr.t.IsZero()
}

func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) Fullerene {
	return Fullerene{t: time.Date(year, month, day, hour, min, sec, nsec, loc)}
}

func (fr Fullerene) Year() int {
	return fr.t.Year()
}

func (fr Fullerene) Month() time.Month {
	return fr.t.Month()
}

func (fr Fullerene) Day() int {
	return fr.t.Day()
}

func (fr Fullerene) AddDate(years int, months int, days int) Fullerene {
	return Fullerene{t: fr.t.AddDate(years, months, days)}
}

func (fr Fullerene) IsLeapYear() bool {
	y, _, _ := fr.Date()
	if y%4 != 0 {
		return false
	}
	if y%100 == 0 && y%400 != 0 {
		return false
	}
	return true
}

func (fr Fullerene) IsLeapDay() bool {
	_, m, d := fr.Date()
	if m == 2 && d == 29 {
		return true
	}
	return false
}

func (fr Fullerene) IsBirthday(targetTime Fullerene, beforeDayIfLeap bool) bool {
	_, m, d := fr.Date()           // birthday
	_, mm, dd := targetTime.Date() // check if it is birthday.
	if m == mm && d == dd && !fr.IsLeapDay() {
		// consider leap year.
		return true
	}

	// there are countries which a person get old at the day before leap day, and the day after in a leap year.
	return fr.isBirthdayEx(targetTime, beforeDayIfLeap)
}

func (fr Fullerene) isBirthdayEx(targetTime Fullerene, beforeDayIfLeap bool) bool {
	_, m, d := targetTime.Date()
	if targetTime.IsLeapYear() {
		return false
	}
	if beforeDayIfLeap && m == 2 && d == 28 {
		return true
	}
	if !beforeDayIfLeap && m == 3 && d == 1 {
		return true
	}
	return false
}
<|endoftext|>


<commit_before>package eureka

import (
	"io/ioutil"
	"strconv"
	"strings"
	"text/template"
	"time"

	"github.com/ArthurHlt/go-eureka-client/eureka"
	"github.com/cenk/backoff"
	"github.com/containous/traefik/job"
	"github.com/containous/traefik/log"
	"github.com/containous/traefik/provider"
	"github.com/containous/traefik/safe"
	"github.com/containous/traefik/types"
)

// Provider holds configuration of the Provider provider.
type Provider struct {
	provider.BaseProvider `mapstructure:",squash" export:"true"`
	Endpoint              string `description:"Eureka server endpoint"`
	Delay                 string `description:"Override default configuration time between refresh" export:"true"`
}

// Provide allows the eureka provider to provide configurations to traefik
// using the given configuration channel.
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, _ types.Constraints) error {

	operation := func() error {
		configuration, err := p.buildConfiguration()
		if err != nil {
			log.Errorf("Failed to build configuration for Provider, error: %s", err)
			return err
		}

		configurationChan <- types.ConfigMessage{
			ProviderName:  "eureka",
			Configuration: configuration,
		}

		var delay time.Duration
		if len(p.Delay) > 0 {
			var err error
			delay, err = time.ParseDuration(p.Delay)
			if err != nil {
				log.Errorf("Failed to parse delay for Provider, error: %s", err)
				return err
			}
		} else {
			delay = time.Second * 30
		}

		ticker := time.NewTicker(delay)
		safe.Go(func() {
			for t := range ticker.C {

				log.Debug("Refreshing Provider " + t.String())

				configuration, err := p.buildConfiguration()
				if err != nil {
					log.Errorf("Failed to refresh Provider configuration, error: %s", err)
					return
				}

				configurationChan <- types.ConfigMessage{
					ProviderName:  "eureka",
					Configuration: configuration,
				}
			}
		})
		return nil
	}

	notify := func(err error, time time.Duration) {
		log.Errorf("Provider connection error %+v, retrying in %s", err, time)
	}
	err := backoff.RetryNotify(operation, job.NewBackOff(backoff.NewExponentialBackOff()), notify)
	if err != nil {
		log.Errorf("Cannot connect to Provider server %+v", err)
		return err
	}
	return nil
}

// Build the configuration from Provider server
func (p *Provider) buildConfiguration() (*types.Configuration, error) {
	var EurekaFuncMap = template.FuncMap{
		"getPort":       p.getPort,
		"getProtocol":   p.getProtocol,
		"getWeight":     p.getWeight,
		"getInstanceID": p.getInstanceID,
	}

	eureka.GetLogger().SetOutput(ioutil.Discard)

	client := eureka.NewClient([]string{
		p.Endpoint,
	})

	applications, err := client.GetApplications()
	if err != nil {
		return nil, err
	}

	templateObjects := struct {
		Applications []eureka.Application
	}{
		applications.Applications,
	}

	configuration, err := p.GetConfiguration("templates/eureka.tmpl", EurekaFuncMap, templateObjects)
	if err != nil {
		log.Error(err)
	}
	return configuration, nil
}

func (p *Provider) getPort(instance eureka.InstanceInfo) string {
	if instance.SecurePort.Enabled {
		return strconv.Itoa(instance.SecurePort.Port)
	}
	return strconv.Itoa(instance.Port.Port)
}

func (p *Provider) getProtocol(instance eureka.InstanceInfo) string {
	if instance.SecurePort.Enabled {
		return "https"
	}
	return "http"
}

func (p *Provider) getWeight(instance eureka.InstanceInfo) string {
	if val, ok := instance.Metadata.Map[types.LabelWeight]; ok {
		return val
	}
	return "0"
}

func (p *Provider) getInstanceID(instance eureka.InstanceInfo) string {
	if val, ok := instance.Metadata.Map[types.LabelBackendID]; ok {
		return val
	}
	return strings.Replace(instance.IpAddr, ".", "-", -1) + "-" + p.getPort(instance)
}
<commit_msg>Continue refresh the configuration after a failure.<commit_after>package eureka

import (
	"io/ioutil"
	"strconv"
	"strings"
	"text/template"
	"time"

	"github.com/ArthurHlt/go-eureka-client/eureka"
	"github.com/cenk/backoff"
	"github.com/containous/traefik/job"
	"github.com/containous/traefik/log"
	"github.com/containous/traefik/provider"
	"github.com/containous/traefik/safe"
	"github.com/containous/traefik/types"
)

// Provider holds configuration of the Provider provider.
type Provider struct {
	provider.BaseProvider `mapstructure:",squash" export:"true"`
	Endpoint              string `description:"Eureka server endpoint"`
	Delay                 string `description:"Override default configuration time between refresh" export:"true"`
}

// Provide allows the eureka provider to provide configurations to traefik
// using the given configuration channel.
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, _ types.Constraints) error {

	operation := func() error {
		configuration, err := p.buildConfiguration()
		if err != nil {
			log.Errorf("Failed to build configuration for Provider, error: %s", err)
			return err
		}

		configurationChan <- types.ConfigMessage{
			ProviderName:  "eureka",
			Configuration: configuration,
		}

		var delay time.Duration
		if len(p.Delay) > 0 {
			var err error
			delay, err = time.ParseDuration(p.Delay)
			if err != nil {
				log.Errorf("Failed to parse delay for Provider, error: %s", err)
				return err
			}
		} else {
			delay = time.Second * 30
		}

		ticker := time.NewTicker(delay)
		safe.Go(func() {
			for t := range ticker.C {

				log.Debugf("Refreshing Provider %s", t.String())

				configuration, err := p.buildConfiguration()
				if err != nil {
					log.Errorf("Failed to refresh Provider configuration, error: %s", err)
					continue
				}

				configurationChan <- types.ConfigMessage{
					ProviderName:  "eureka",
					Configuration: configuration,
				}
			}
		})
		return nil
	}

	notify := func(err error, time time.Duration) {
		log.Errorf("Provider connection error %+v, retrying in %s", err, time)
	}
	err := backoff.RetryNotify(operation, job.NewBackOff(backoff.NewExponentialBackOff()), notify)
	if err != nil {
		log.Errorf("Cannot connect to Provider server %+v", err)
		return err
	}
	return nil
}

// Build the configuration from Provider server
func (p *Provider) buildConfiguration() (*types.Configuration, error) {
	var EurekaFuncMap = template.FuncMap{
		"getPort":       p.getPort,
		"getProtocol":   p.getProtocol,
		"getWeight":     p.getWeight,
		"getInstanceID": p.getInstanceID,
	}

	eureka.GetLogger().SetOutput(ioutil.Discard)

	client := eureka.NewClient([]string{
		p.Endpoint,
	})

	applications, err := client.GetApplications()
	if err != nil {
		return nil, err
	}

	templateObjects := struct {
		Applications []eureka.Application
	}{
		applications.Applications,
	}

	configuration, err := p.GetConfiguration("templates/eureka.tmpl", EurekaFuncMap, templateObjects)
	if err != nil {
		log.Error(err)
	}
	return configuration, nil
}

func (p *Provider) getPort(instance eureka.InstanceInfo) string {
	if instance.SecurePort.Enabled {
		return strconv.Itoa(instance.SecurePort.Port)
	}
	return strconv.Itoa(instance.Port.Port)
}

func (p *Provider) getProtocol(instance eureka.InstanceInfo) string {
	if instance.SecurePort.Enabled {
		return "https"
	}
	return "http"
}

func (p *Provider) getWeight(instance eureka.InstanceInfo) string {
	if val, ok := instance.Metadata.Map[types.LabelWeight]; ok {
		return val
	}
	return "0"
}

func (p *Provider) getInstanceID(instance eureka.InstanceInfo) string {
	if val, ok := instance.Metadata.Map[types.LabelBackendID]; ok {
		return val
	}
	return strings.Replace(instance.IpAddr, ".", "-", -1) + "-" + p.getPort(instance)
}
<|endoftext|>


<commit_before>package ringo

import (
	"fmt"
	"log"
	"net/http"
	"path"
	"regexp"

	"github.com/julienschmidt/httprouter"
)

func (r *Router) GET(path string, handler HandlerFunc) {
	r.AddRoute(path, "GET", handler)
}
func (r *Router) POST(path string, handler HandlerFunc) {
	r.AddRoute(path, "POST", handler)
}
func (r *Router) PUT(path string, handler HandlerFunc) {
	r.AddRoute(path, "PUT", handler)
}
func (r *Router) DELETE(path string, handler HandlerFunc) {
	r.AddRoute(path, "DELETE", handler)
}
func (r *Router) HEAD(path string, handler HandlerFunc) {
	r.AddRoute(path, "HEAD", handler)
}
func (r *Router) OPTIONS(path string, handler HandlerFunc) {
	r.AddRoute(path, "OPTIONS", handler)
}
func (r *Router) PATCH(path string, handler HandlerFunc) {
	r.AddRoute(path, "PATCH", handler)
}

func (router *Router) Mount(mountPath string, mountedRouter *Router) {
	for _, r := range mountedRouter.routes {
		router.AddRoute(path.Join(mountPath, r.path), r.method, r.handler)
	}
}

func (r *Router) AddController(controller Controllerable) {
	registerToRouter(r, controller)
}

type routeHandler struct {
	method  string
	path    string
	handler HandlerFunc
}

type routeRegisterMap map[string]bool

type Router struct {
	routes []routeHandler
	httprouter.Router
}

var pathParamRegexp *regexp.Regexp

func init() {
	pathParamRegexp = regexp.MustCompile("\\:(\\w+)(/|\\z)")
}

func compilePathExp(path string) (*regexp.Regexp, error) {
	escaped := regexp.QuoteMeta(path)
	log.Printf("escaped route path: %s", escaped)
	replaced := pathParamRegexp.ReplaceAllString(escaped, "(?P<$1>\\w+)$2")
	log.Printf("replaced route path: %s", replaced)
	return regexp.Compile(fmt.Sprintf("\\A%s\\z", replaced))
}

func (r *Router) AddRoute(path string, method string, handler HandlerFunc) {
	r.Router.Handle(method, path, func(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
		var c Context
		c.ResponseWriter = w
		c.Request = r
		c.Params = Params(params)
		handler(&c)
	})

	route := routeHandler{path: path, method: method, handler: handler}
	r.routes = append(r.routes, route)
}

func (r *Router) MatchRoute(path string, method string) (handler HandlerFunc, params Params) {
	rawHandler, rawParams, _ := r.Lookup(method, path)
	params = Params(rawParams)

	if rawHandler != nil {
		handler = func(c *Context) {
			rawHandler(c.ResponseWriter, c.Request, rawParams)
		}
	}

	return
}

// NewRouter new router
func NewRouter() *Router {
	r := Router{}
	return &r
}
<commit_msg>remove unused code<commit_after>package ringo

import (
	"net/http"
	"path"

	"github.com/julienschmidt/httprouter"
)

func (r *Router) GET(path string, handler HandlerFunc) {
	r.AddRoute(path, "GET", handler)
}
func (r *Router) POST(path string, handler HandlerFunc) {
	r.AddRoute(path, "POST", handler)
}
func (r *Router) PUT(path string, handler HandlerFunc) {
	r.AddRoute(path, "PUT", handler)
}
func (r *Router) DELETE(path string, handler HandlerFunc) {
	r.AddRoute(path, "DELETE", handler)
}
func (r *Router) HEAD(path string, handler HandlerFunc) {
	r.AddRoute(path, "HEAD", handler)
}
func (r *Router) OPTIONS(path string, handler HandlerFunc) {
	r.AddRoute(path, "OPTIONS", handler)
}
func (r *Router) PATCH(path string, handler HandlerFunc) {
	r.AddRoute(path, "PATCH", handler)
}

func (router *Router) Mount(mountPath string, mountedRouter *Router) {
	for _, r := range mountedRouter.routes {
		router.AddRoute(path.Join(mountPath, r.path), r.method, r.handler)
	}
}

func (r *Router) AddController(controller Controllerable) {
	registerToRouter(r, controller)
}

type routeHandler struct {
	method  string
	path    string
	handler HandlerFunc
}

type routeRegisterMap map[string]bool

type Router struct {
	routes []routeHandler
	httprouter.Router
}

func (r *Router) AddRoute(path string, method string, handler HandlerFunc) {
	r.Router.Handle(method, path, func(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
		var c Context
		c.ResponseWriter = w
		c.Request = r
		c.Params = Params(params)
		handler(&c)
	})

	route := routeHandler{path: path, method: method, handler: handler}
	r.routes = append(r.routes, route)
}

func (r *Router) MatchRoute(path string, method string) (handler HandlerFunc, params Params) {
	rawHandler, rawParams, _ := r.Lookup(method, path)
	params = Params(rawParams)

	if rawHandler != nil {
		handler = func(c *Context) {
			rawHandler(c.ResponseWriter, c.Request, rawParams)
		}
	}

	return
}

// NewRouter new router
func NewRouter() *Router {
	r := Router{}
	return &r
}
<|endoftext|>


<commit_before>package skl

import "github.com/eliquious/lexer"

func init() {
	lexer.LoadTokenMap(testKeywords)
}

// Token enums
// Built-in Types
const (
	startTypes lexer.Token = iota + 1000
	STRING
	UINT8
	INT8
	UINT16
	INT16
	UINT32
	INT32
	UINT64
	INT64
	FLOAT32
	FLOAT64
	TIMESTAMP
	BOOLEAN
	endTypes

	// Keywords

	startKeywords
	ADD
	BY
	CLUSTERED
	CREATE
	DESCRIBE
	FOR
	FROM
	INSERT
	LIMIT
	LOG
	NAMESPACE
	OFFSET
	ON
	OPTIONAL
	OPTIONS
	PASSWORD
	PERMISSION
	REMOVE
	REQUIRED
	ROLE
	SELECT
	SET
	SHOW
	SUBSCRIBE
	TO
	TYPE
	UNSUBSCRIBE
	UPDATE
	USE
	USER
	USING
	VIEW
	WHERE
	WITH
	endKeywords
)

var testKeywords = map[lexer.Token]string{

	STRING:    "string",
	UINT8:     "uint8",
	INT8:      "int8",
	UINT16:    "uint16",
	INT16:     "int16",
	UINT32:    "uint32",
	INT32:     "int32",
	UINT64:    "uint64",
	INT64:     "int64",
	FLOAT32:   "float32",
	FLOAT64:   "float64",
	TIMESTAMP: "timestamp",
	BOOLEAN:   "boolean",

	ADD:         "ADD",
	BY:          "BY",
	CLUSTERED:   "CLUSTERED",
	CREATE:      "CREATE",
	DESCRIBE:    "DESCRIBE",
	FOR:         "FOR",
	FROM:        "FROM",
	INSERT:      "INSERT",
	LIMIT:       "LIMIT",
	LOG:         "LOG",
	NAMESPACE:   "NAMESPACE",
	OFFSET:      "OFFSET",
	ON:          "ON",
	OPTIONAL:    "OPTIONAL",
	OPTIONS:     "OPTIONS",
	PASSWORD:    "PASSWORD",
	PERMISSION:  "PERMISSION",
	REMOVE:      "REMOVE",
	REQUIRED:    "REQUIRED",
	ROLE:        "ROLE",
	SELECT:      "SELECT",
	SET:         "SET",
	SHOW:        "SHOW",
	SUBSCRIBE:   "SUBSCRIBE",
	TO:          "TO",
	TYPE:        "TYPE",
	UNSUBSCRIBE: "UNSUBSCRIBE",
	UPDATE:      "UPDATE",
	USE:         "USE",
	USER:        "USER",
	USING:       "USING",
	VIEW:        "VIEW",
	WHERE:       "WHERE",
	WITH:        "WITH",
}

// tokstr returns a literal if provided, otherwise returns the token string.
func tokstr(tok lexer.Token, lit string) string {
	if lit != "" && tok != lexer.WS {
		return lit
	}
	return tok.String()
}
<commit_msg>Add plural tokens<commit_after>package skl

import "github.com/eliquious/lexer"

func init() {
	lexer.LoadTokenMap(testKeywords)
}

// Token enums
// Built-in Types
const (
	startTypes lexer.Token = iota + 1000
	STRING
	UINT8
	INT8
	UINT16
	INT16
	UINT32
	INT32
	UINT64
	INT64
	FLOAT32
	FLOAT64
	TIMESTAMP
	BOOLEAN
	endTypes

	// Keywords

	startKeywords
	ADD
	BY
	CLUSTERED
	CREATE
	DESCRIBE
	FOR
	FROM
	INSERT
	LIMIT
	LOG
	LOGS
	NAMESPACE
	NAMESPACES
	OFFSET
	ON
	OPTIONAL
	OPTIONS
	PASSWORD
	PERMISSION
	PERMISSIONS
	REMOVE
	REQUIRED
	ROLE
	ROLES
	SELECT
	SET
	SHOW
	SUBSCRIBE
	TO
	TYPE
	TYPES
	UNSUBSCRIBE
	UPDATE
	USE
	USER
	USERS
	USING
	VIEW
	VIEWS
	WHERE
	WITH
	endKeywords
)

var testKeywords = map[lexer.Token]string{

	STRING:    "string",
	UINT8:     "uint8",
	INT8:      "int8",
	UINT16:    "uint16",
	INT16:     "int16",
	UINT32:    "uint32",
	INT32:     "int32",
	UINT64:    "uint64",
	INT64:     "int64",
	FLOAT32:   "float32",
	FLOAT64:   "float64",
	TIMESTAMP: "timestamp",
	BOOLEAN:   "boolean",

	ADD:         "ADD",
	BY:          "BY",
	CLUSTERED:   "CLUSTERED",
	CREATE:      "CREATE",
	DESCRIBE:    "DESCRIBE",
	FOR:         "FOR",
	FROM:        "FROM",
	INSERT:      "INSERT",
	LIMIT:       "LIMIT",
	LOG:         "LOG",
	LOGS:        "LOGS",
	NAMESPACE:   "NAMESPACE",
	NAMESPACES:  "NAMESPACES",
	OFFSET:      "OFFSET",
	ON:          "ON",
	OPTIONAL:    "OPTIONAL",
	OPTIONS:     "OPTIONS",
	PASSWORD:    "PASSWORD",
	PERMISSION:  "PERMISSION",
	PERMISSIONS: "PERMISSIONS",
	REMOVE:      "REMOVE",
	REQUIRED:    "REQUIRED",
	ROLE:        "ROLE",
	ROLES:       "ROLES",
	SELECT:      "SELECT",
	SET:         "SET",
	SHOW:        "SHOW",
	SUBSCRIBE:   "SUBSCRIBE",
	TO:          "TO",
	TYPE:        "TYPE",
	TYPES:       "TYPES",
	UNSUBSCRIBE: "UNSUBSCRIBE",
	UPDATE:      "UPDATE",
	USE:         "USE",
	USER:        "USER",
	USERS:       "USERS",
	USING:       "USING",
	VIEW:        "VIEW",
	VIEWS:       "VIEWS",
	WHERE:       "WHERE",
	WITH:        "WITH",
}

// tokstr returns a literal if provided, otherwise returns the token string.
func tokstr(tok lexer.Token, lit string) string {
	if lit != "" && tok != lexer.WS {
		return lit
	}
	return tok.String()
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"reflect"
	"strings"
	"testing"

	"k8s.io/test-infra/prow/config"
)

func expectEqual(t *testing.T, msg string, have interface{}, want interface{}) {
	if !reflect.DeepEqual(have, want) {
		t.Errorf("bad %s: got %v, wanted %v",
			msg, have, want)
	}
}

func makeStore(t *testing.T) *store {
	tmp, err := ioutil.TempFile("", "tot_test_")
	if err != nil {
		t.Fatal(err)
	}
	os.Remove(tmp.Name()) // json decoding an empty file throws an error

	store, err := newStore(tmp.Name())
	if err != nil {
		t.Fatal(err)
	}

	return store
}

func TestVend(t *testing.T) {
	store := makeStore(t)
	defer os.Remove(store.storagePath)

	expectEqual(t, "empty vend", store.vend("a"), 1)
	expectEqual(t, "second vend", store.vend("a"), 2)
	expectEqual(t, "third vend", store.vend("a"), 3)
	expectEqual(t, "second empty", store.vend("b"), 1)

	store2, err := newStore(store.storagePath)
	if err != nil {
		t.Fatal(err)
	}
	expectEqual(t, "fourth vend, different instance", store2.vend("a"), 4)
}

func TestSet(t *testing.T) {
	store := makeStore(t)
	defer os.Remove(store.storagePath)

	store.set("foo", 300)
	expectEqual(t, "peek", store.peek("foo"), 300)
	store.set("foo2", 300)
	expectEqual(t, "vend", store.vend("foo2"), 301)
	expectEqual(t, "vend", store.vend("foo2"), 302)
}

func expectResponse(t *testing.T, handler http.Handler, req *http.Request, msg, value string) {
	rr := httptest.NewRecorder()

	handler.ServeHTTP(rr, req)

	expectEqual(t, "http status OK", rr.Code, 200)

	expectEqual(t, msg, rr.Body.String(), value)
}

func TestHandler(t *testing.T) {
	store := makeStore(t)
	defer os.Remove(store.storagePath)

	handler := http.HandlerFunc(store.handle)

	req, err := http.NewRequest("GET", "/vend/foo", nil)
	if err != nil {
		t.Fatal(err)
	}

	expectResponse(t, handler, req, "http vend", "1")
	expectResponse(t, handler, req, "http vend", "2")

	req, err = http.NewRequest("HEAD", "/vend/foo", nil)
	if err != nil {
		t.Fatal(err)
	}

	expectResponse(t, handler, req, "http peek", "2")

	req, err = http.NewRequest("POST", "/vend/bar", strings.NewReader("40"))
	if err != nil {
		t.Fatal(err)
	}

	expectResponse(t, handler, req, "http post", "")

	req, err = http.NewRequest("HEAD", "/vend/bar", nil)
	if err != nil {
		t.Fatal(err)
	}

	expectResponse(t, handler, req, "http vend", "40")
}

type mapHandler map[string]string

func (h mapHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "%s", h[r.URL.Path])
}

func TestFallback(t *testing.T) {
	serv := httptest.NewServer(mapHandler(map[string]string{
		"/logs/foo/latest-build.txt": "200",
		"/logs/bar/latest-build.txt": "\t300 \n",
		"/logs/baz/latest-build.txt": "asdf",
	}))
	defer serv.Close()

	store := makeStore(t)
	defer os.Remove(store.storagePath)
	store.fallbackFunc = fallbackHandler{template: serv.URL + "/logs/%s/latest-build.txt"}.get

	expectEqual(t, "vend foo 1", store.vend("foo"), 201)
	expectEqual(t, "vend foo 2", store.vend("foo"), 202)

	expectEqual(t, "vend bar", store.vend("bar"), 301)
	expectEqual(t, "vend baz", store.vend("baz"), 1)
	expectEqual(t, "vend quux", store.vend("quux"), 1)
}

var c *config.Config

func TestMain(m *testing.M) {
	conf, err := config.Load("../../config.yaml", "../../../config/jobs")
	if err != nil {
		fmt.Printf("Could not load config: %v", err)
		os.Exit(1)
	}
	c = conf
	os.Exit(m.Run())
}

func TestGetURL(t *testing.T) {
	tests := []struct {
		name string

		jobName  string
		template string
		c        *config.Config
		bucket   string

		expected string
	}{
		{
			name: "fallback template",

			jobName:  "pull-community-verify",
			template: "https://storage.googleapis.com/kubernetes-jenkins/logs/%s/latest-build.txt",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/logs/pull-community-verify/latest-build.txt",
		},
		{
			name: "fallback bucket - presubmit",

			jobName: "pull-community-verify",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/pr-logs/directory/pull-community-verify/latest-build.txt",
		},
		{
			name: "fallback bucket - postsubmit",

			jobName: "ci-federation-release",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/logs/ci-federation-release/latest-build.txt",
		},
		{
			name: "fallback bucket - periodic",

			jobName: "ci-kubernetes-cross-build",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/logs/ci-kubernetes-cross-build/latest-build.txt",
		},
		{
			name: "fallback bucket - unknown",

			jobName: "a-name-that-is-what-it-is",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins",

			expected: "",
		},
		{
			name: "fallback bucket with trailing slash",

			jobName: "pull-community-verify",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins/",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/pr-logs/directory/pull-community-verify/latest-build.txt",
		},
	}

	for _, test := range tests {
		t.Logf("running scenario %q", test.name)

		var configAgent *config.Agent
		if test.c != nil {
			configAgent = new(config.Agent)
			configAgent.Set(test.c)
		}
		f := fallbackHandler{
			template:    test.template,
			configAgent: configAgent,
			bucket:      test.bucket,
		}

		if got := f.getURL(test.jobName); got != test.expected {
			t.Errorf("unexpected URL:\n%s\nexpected:\n%s", got, test.expected)
		}
	}
}
<commit_msg>use another job for tot test... for now<commit_after>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"reflect"
	"strings"
	"testing"

	"k8s.io/test-infra/prow/config"
)

func expectEqual(t *testing.T, msg string, have interface{}, want interface{}) {
	if !reflect.DeepEqual(have, want) {
		t.Errorf("bad %s: got %v, wanted %v",
			msg, have, want)
	}
}

func makeStore(t *testing.T) *store {
	tmp, err := ioutil.TempFile("", "tot_test_")
	if err != nil {
		t.Fatal(err)
	}
	os.Remove(tmp.Name()) // json decoding an empty file throws an error

	store, err := newStore(tmp.Name())
	if err != nil {
		t.Fatal(err)
	}

	return store
}

func TestVend(t *testing.T) {
	store := makeStore(t)
	defer os.Remove(store.storagePath)

	expectEqual(t, "empty vend", store.vend("a"), 1)
	expectEqual(t, "second vend", store.vend("a"), 2)
	expectEqual(t, "third vend", store.vend("a"), 3)
	expectEqual(t, "second empty", store.vend("b"), 1)

	store2, err := newStore(store.storagePath)
	if err != nil {
		t.Fatal(err)
	}
	expectEqual(t, "fourth vend, different instance", store2.vend("a"), 4)
}

func TestSet(t *testing.T) {
	store := makeStore(t)
	defer os.Remove(store.storagePath)

	store.set("foo", 300)
	expectEqual(t, "peek", store.peek("foo"), 300)
	store.set("foo2", 300)
	expectEqual(t, "vend", store.vend("foo2"), 301)
	expectEqual(t, "vend", store.vend("foo2"), 302)
}

func expectResponse(t *testing.T, handler http.Handler, req *http.Request, msg, value string) {
	rr := httptest.NewRecorder()

	handler.ServeHTTP(rr, req)

	expectEqual(t, "http status OK", rr.Code, 200)

	expectEqual(t, msg, rr.Body.String(), value)
}

func TestHandler(t *testing.T) {
	store := makeStore(t)
	defer os.Remove(store.storagePath)

	handler := http.HandlerFunc(store.handle)

	req, err := http.NewRequest("GET", "/vend/foo", nil)
	if err != nil {
		t.Fatal(err)
	}

	expectResponse(t, handler, req, "http vend", "1")
	expectResponse(t, handler, req, "http vend", "2")

	req, err = http.NewRequest("HEAD", "/vend/foo", nil)
	if err != nil {
		t.Fatal(err)
	}

	expectResponse(t, handler, req, "http peek", "2")

	req, err = http.NewRequest("POST", "/vend/bar", strings.NewReader("40"))
	if err != nil {
		t.Fatal(err)
	}

	expectResponse(t, handler, req, "http post", "")

	req, err = http.NewRequest("HEAD", "/vend/bar", nil)
	if err != nil {
		t.Fatal(err)
	}

	expectResponse(t, handler, req, "http vend", "40")
}

type mapHandler map[string]string

func (h mapHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "%s", h[r.URL.Path])
}

func TestFallback(t *testing.T) {
	serv := httptest.NewServer(mapHandler(map[string]string{
		"/logs/foo/latest-build.txt": "200",
		"/logs/bar/latest-build.txt": "\t300 \n",
		"/logs/baz/latest-build.txt": "asdf",
	}))
	defer serv.Close()

	store := makeStore(t)
	defer os.Remove(store.storagePath)
	store.fallbackFunc = fallbackHandler{template: serv.URL + "/logs/%s/latest-build.txt"}.get

	expectEqual(t, "vend foo 1", store.vend("foo"), 201)
	expectEqual(t, "vend foo 2", store.vend("foo"), 202)

	expectEqual(t, "vend bar", store.vend("bar"), 301)
	expectEqual(t, "vend baz", store.vend("baz"), 1)
	expectEqual(t, "vend quux", store.vend("quux"), 1)
}

var c *config.Config

func TestMain(m *testing.M) {
	conf, err := config.Load("../../config.yaml", "../../../config/jobs")
	if err != nil {
		fmt.Printf("Could not load config: %v", err)
		os.Exit(1)
	}
	c = conf
	os.Exit(m.Run())
}

func TestGetURL(t *testing.T) {
	tests := []struct {
		name string

		jobName  string
		template string
		c        *config.Config
		bucket   string

		expected string
	}{
		{
			name: "fallback template",

			jobName:  "pull-community-verify",
			template: "https://storage.googleapis.com/kubernetes-jenkins/logs/%s/latest-build.txt",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/logs/pull-community-verify/latest-build.txt",
		},
		{
			name: "fallback bucket - presubmit",

			jobName: "pull-community-verify",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/pr-logs/directory/pull-community-verify/latest-build.txt",
		},
		{
			name: "fallback bucket - postsubmit",

			jobName: "ci-test-infra-bazel",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/logs/ci-test-infra-bazel/latest-build.txt",
		},
		{
			name: "fallback bucket - periodic",

			jobName: "ci-kubernetes-cross-build",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/logs/ci-kubernetes-cross-build/latest-build.txt",
		},
		{
			name: "fallback bucket - unknown",

			jobName: "a-name-that-is-what-it-is",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins",

			expected: "",
		},
		{
			name: "fallback bucket with trailing slash",

			jobName: "pull-community-verify",
			c:       c,
			bucket:  "https://storage.googleapis.com/kubernetes-jenkins/",

			expected: "https://storage.googleapis.com/kubernetes-jenkins/pr-logs/directory/pull-community-verify/latest-build.txt",
		},
	}

	for _, test := range tests {
		t.Logf("running scenario %q", test.name)

		var configAgent *config.Agent
		if test.c != nil {
			configAgent = new(config.Agent)
			configAgent.Set(test.c)
		}
		f := fallbackHandler{
			template:    test.template,
			configAgent: configAgent,
			bucket:      test.bucket,
		}

		if got := f.getURL(test.jobName); got != test.expected {
			t.Errorf("unexpected URL:\n%s\nexpected:\n%s", got, test.expected)
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) Liam Stanley <me@liamstanley.io>. All rights reserved. Use
// of this source code is governed by the MIT license that can be found in
// the LICENSE file.

package girc

import (
	"strings"
	"testing"
)

func BenchmarkFormat(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Format("{red}test{c}")
	}

	return
}

func BenchmarkFormatLong(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Format("{red}test {blue}2 {red}3 {brown} {italic}test{c}")
	}

	return
}

func BenchmarkStripFormat(b *testing.B) {
	for i := 0; i < b.N; i++ {
		StripFormat("{red}test{c}")
	}

	return
}

func BenchmarkStripFormatLong(b *testing.B) {
	for i := 0; i < b.N; i++ {
		StripFormat("{red}test {blue}2 {red}3 {brown} {italic}test{c}")
	}

	return
}

func BenchmarkStripRaw(b *testing.B) {
	text := Format("{red}test{c}")
	for i := 0; i < b.N; i++ {
		StripRaw(text)
	}

	return
}

func BenchmarkStripRawLong(b *testing.B) {
	text := Format("{red}test {blue}2 {red}3 {brown} {italic}test{c}")
	for i := 0; i < b.N; i++ {
		StripRaw(text)
	}

	return
}

func TestFormat(t *testing.T) {
	type args struct {
		text string
	}

	tests := []struct {
		name string
		args args
		want string
	}{
		{name: "start, end", args: args{text: "{red}test{c}"}, want: "\x0304test\x03"},
		{name: "start, middle, end", args: args{text: "{red}te{red}st{c}"}, want: "\x0304te\x0304st\x03"},
		{name: "partial", args: args{text: "{redtest{c}"}, want: "{redtest\x03"},
		{name: "inside", args: args{text: "{re{c}d}test{c}"}, want: "{re\x03d}test\x03"},
		{name: "nothing", args: args{text: "this is a test."}, want: "this is a test."},
	}

	for _, tt := range tests {
		if got := Format(tt.args.text); got != tt.want {
			t.Errorf("%s: Format() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestStripFormat(t *testing.T) {
	type args struct {
		text string
	}

	tests := []struct {
		name string
		args args
		want string
	}{
		{name: "start, end", args: args{text: "{red}test{c}"}, want: "test"},
		{name: "start, middle, end", args: args{text: "{red}te{red}st{c}"}, want: "test"},
		{name: "partial", args: args{text: "{redtest{c}"}, want: "{redtest"},
		{name: "inside", args: args{text: "{re{c}d}test{c}"}, want: "{red}test"},
		{name: "nothing", args: args{text: "this is a test."}, want: "this is a test."},
	}

	for _, tt := range tests {
		if got := StripFormat(tt.args.text); got != tt.want {
			t.Errorf("%s: StripFormat() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestStripRaw(t *testing.T) {
	type args struct {
		text string
	}

	tests := []struct {
		name string
		args args // gets passed to Format() before sent
		want string
	}{
		{name: "start, end", args: args{text: "{red}test{c}"}, want: "test"},
		{name: "start, middle, end", args: args{text: "{red}te{red}st{c}"}, want: "test"},
		{name: "partial", args: args{text: "{redtest{c}"}, want: "{redtest"},
		{name: "inside", args: args{text: "{re{c}d}test{c}"}, want: "{red}test"},
		{name: "nothing", args: args{text: "this is a test."}, want: "this is a test."},
	}

	for _, tt := range tests {
		if got := StripRaw(Format(tt.args.text)); got != tt.want {
			t.Errorf("%s: StripRaw() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestIsValidNick(t *testing.T) {
	type args struct {
		nick string
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "normal", args: args{nick: "test"}, want: true},
		{name: "empty", args: args{nick: ""}, want: false},
		{name: "hyphen and special", args: args{nick: "test[-]"}, want: true},
		{name: "invalid middle", args: args{nick: "test!test"}, want: false},
		{name: "invalid dot middle", args: args{nick: "test.test"}, want: false},
		{name: "end", args: args{nick: "test!"}, want: false},
		{name: "invalid start", args: args{nick: "!test"}, want: false},
		{name: "backslash and numeric", args: args{nick: "test[\\0"}, want: true},
		{name: "long", args: args{nick: "test123456789AZBKASDLASMDLKM"}, want: true},
		{name: "index 0 dash", args: args{nick: "-test"}, want: false},
		{name: "index 0 numeric", args: args{nick: "0test"}, want: false},
	}
	for _, tt := range tests {
		if got := IsValidNick(tt.args.nick); got != tt.want {
			t.Errorf("%s: IsValidNick() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestIsValidChannel(t *testing.T) {
	type args struct {
		channel string
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "valid channel", args: args{channel: "#valid"}, want: true},
		{name: "invalid channel comma", args: args{channel: "#invalid,"}, want: false},
		{name: "invalid channel space", args: args{channel: "#inva lid"}, want: false},
		{name: "valid channel with numerics", args: args{channel: "#1valid0"}, want: true},
		{name: "valid channel with special", args: args{channel: "#valid[]test"}, want: true},
		{name: "valid channel with special", args: args{channel: "#[]valid[]test[]"}, want: true},
		{name: "just hash", args: args{channel: "#"}, want: false},
		{name: "empty", args: args{channel: ""}, want: false},
		{name: "invalid prefix", args: args{channel: "$invalid"}, want: false},
		{name: "too long", args: args{channel: "#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, want: false},
		{name: "valid id prefix", args: args{channel: "!12345test"}, want: true},
		{name: "invalid id length", args: args{channel: "!1234"}, want: false},
		{name: "invalid id length", args: args{channel: "!12345"}, want: false},
		{name: "invalid id prefix", args: args{channel: "!test1invalid"}, want: false},
	}
	for _, tt := range tests {
		if got := IsValidChannel(tt.args.channel); got != tt.want {
			t.Errorf("%s: IsValidChannel() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestIsValidUser(t *testing.T) {
	type args struct {
		name string
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "user without ident server", args: args{name: "~test"}, want: true},
		{name: "user with ident server", args: args{name: "test"}, want: true},
		{name: "non-alphanumeric first index", args: args{name: "-test"}, want: false},
		{name: "non-alphanumeric first index", args: args{name: "[test]"}, want: false},
		{name: "numeric first index", args: args{name: "0test"}, want: true},
		{name: "blank", args: args{name: ""}, want: false},
		{name: "just tilde", args: args{name: "~"}, want: false},
		{name: "special chars", args: args{name: "test-----"}, want: true},
		{name: "special chars", args: args{name: "test-[]-"}, want: true},
		{name: "special chars", args: args{name: "test-----"}, want: true},
	}
	for _, tt := range tests {
		if got := IsValidUser(tt.args.name); got != tt.want {
			t.Errorf("%s: IsValidUser() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestToRFC1459(t *testing.T) {
	cases := []struct {
		in   string
		want string
	}{
		{"", ""},
		{"a", "a"},
		{"abcd", "abcd"},
		{"AbcD", "abcd"},
		{"!@#$%^&*()_+-=", "!@#$%~&*()_+-="},
		{"Abcd[]", "abcd{}"},
	}

	for _, tt := range cases {
		if got := ToRFC1459(tt.in); got != tt.want {
			t.Errorf("ToRFC1459() = %q, want %q", got, tt.want)
		}
	}

	return
}

func BenchmarkGlob(b *testing.B) {
	for i := 0; i < b.N; i++ {
		if !Glob("*quick*fox*dog", "The quick brown fox jumped over the lazy dog") {
			b.Fatalf("should match")
		}
	}

	return
}

func testGlobMatch(t *testing.T, subj, pattern string) {
	if !Glob(subj, pattern) {
		t.Fatalf("'%s' should match '%s'", pattern, subj)
	}

	return
}

func testGlobNoMatch(t *testing.T, subj, pattern string) {
	if Glob(subj, pattern) {
		t.Fatalf("'%s' should not match '%s'", pattern, subj)
	}

	return
}

func TestEmptyPattern(t *testing.T) {
	testGlobMatch(t, "", "")
	testGlobNoMatch(t, "test", "")

	return
}

func TestEmptySubject(t *testing.T) {
	cases := []string{
		"",
		"*",
		"**",
		"***",
		"****************",
		strings.Repeat("*", 1000000),
	}

	for _, pattern := range cases {
		testGlobMatch(t, "", pattern)
	}

	cases = []string{
		// No globs/non-glob characters.
		"test",
		"*test*",

		// Trailing characters.
		"*x",
		"*****************x",
		strings.Repeat("*", 1000000) + "x",

		// Leading characters.
		"x*",
		"x*****************",
		"x" + strings.Repeat("*", 1000000),

		// Mixed leading/trailing characters.
		"x*x",
		"x****************x",
		"x" + strings.Repeat("*", 1000000) + "x",
	}

	for _, pattern := range cases {
		testGlobNoMatch(t, pattern, "")
	}

	return
}

func TestPatternWithoutGlobs(t *testing.T) {
	testGlobMatch(t, "test", "test")

	return
}

func TestGlob(t *testing.T) {
	cases := []string{
		"*test",           // Leading.
		"this*",           // Trailing.
		"this*test",       // Middle.
		"*is *",           // String in between two.
		"*is*a*",          // Lots.
		"**test**",        // Double glob characters.
		"**is**a***test*", // Varying number.
		"* *",             // White space between.
		"*",               // Lone.
		"**********",      // Nothing but globs.
		"*Ѿ*",             // Unicode.
		"*is a ϗѾ *",      // Mixed ASCII/unicode.
	}

	for _, pattern := range cases {
		testGlobMatch(t, "this is a ϗѾ test", pattern)
	}

	cases = []string{
		"test*", // Implicit substring match.
		"*is",   // Partial match.
		"*no*",  // Globs without a match between them.
		" ",     // Plain white space.
		"* ",    // Trailing white space.
		" *",    // Leading white space.
		"*ʤ*",   // Non-matching unicode.
	}

	// Non-matches
	for _, pattern := range cases {
		testGlobNoMatch(t, "this is a test", pattern)
	}

	return
}
<commit_msg>add additional test to validate users<commit_after>// Copyright (c) Liam Stanley <me@liamstanley.io>. All rights reserved. Use
// of this source code is governed by the MIT license that can be found in
// the LICENSE file.

package girc

import (
	"strings"
	"testing"
)

func BenchmarkFormat(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Format("{red}test{c}")
	}

	return
}

func BenchmarkFormatLong(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Format("{red}test {blue}2 {red}3 {brown} {italic}test{c}")
	}

	return
}

func BenchmarkStripFormat(b *testing.B) {
	for i := 0; i < b.N; i++ {
		StripFormat("{red}test{c}")
	}

	return
}

func BenchmarkStripFormatLong(b *testing.B) {
	for i := 0; i < b.N; i++ {
		StripFormat("{red}test {blue}2 {red}3 {brown} {italic}test{c}")
	}

	return
}

func BenchmarkStripRaw(b *testing.B) {
	text := Format("{red}test{c}")
	for i := 0; i < b.N; i++ {
		StripRaw(text)
	}

	return
}

func BenchmarkStripRawLong(b *testing.B) {
	text := Format("{red}test {blue}2 {red}3 {brown} {italic}test{c}")
	for i := 0; i < b.N; i++ {
		StripRaw(text)
	}

	return
}

func TestFormat(t *testing.T) {
	type args struct {
		text string
	}

	tests := []struct {
		name string
		args args
		want string
	}{
		{name: "start, end", args: args{text: "{red}test{c}"}, want: "\x0304test\x03"},
		{name: "start, middle, end", args: args{text: "{red}te{red}st{c}"}, want: "\x0304te\x0304st\x03"},
		{name: "partial", args: args{text: "{redtest{c}"}, want: "{redtest\x03"},
		{name: "inside", args: args{text: "{re{c}d}test{c}"}, want: "{re\x03d}test\x03"},
		{name: "nothing", args: args{text: "this is a test."}, want: "this is a test."},
	}

	for _, tt := range tests {
		if got := Format(tt.args.text); got != tt.want {
			t.Errorf("%s: Format() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestStripFormat(t *testing.T) {
	type args struct {
		text string
	}

	tests := []struct {
		name string
		args args
		want string
	}{
		{name: "start, end", args: args{text: "{red}test{c}"}, want: "test"},
		{name: "start, middle, end", args: args{text: "{red}te{red}st{c}"}, want: "test"},
		{name: "partial", args: args{text: "{redtest{c}"}, want: "{redtest"},
		{name: "inside", args: args{text: "{re{c}d}test{c}"}, want: "{red}test"},
		{name: "nothing", args: args{text: "this is a test."}, want: "this is a test."},
	}

	for _, tt := range tests {
		if got := StripFormat(tt.args.text); got != tt.want {
			t.Errorf("%s: StripFormat() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestStripRaw(t *testing.T) {
	type args struct {
		text string
	}

	tests := []struct {
		name string
		args args // gets passed to Format() before sent
		want string
	}{
		{name: "start, end", args: args{text: "{red}test{c}"}, want: "test"},
		{name: "start, middle, end", args: args{text: "{red}te{red}st{c}"}, want: "test"},
		{name: "partial", args: args{text: "{redtest{c}"}, want: "{redtest"},
		{name: "inside", args: args{text: "{re{c}d}test{c}"}, want: "{red}test"},
		{name: "nothing", args: args{text: "this is a test."}, want: "this is a test."},
	}

	for _, tt := range tests {
		if got := StripRaw(Format(tt.args.text)); got != tt.want {
			t.Errorf("%s: StripRaw() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestIsValidNick(t *testing.T) {
	type args struct {
		nick string
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "normal", args: args{nick: "test"}, want: true},
		{name: "empty", args: args{nick: ""}, want: false},
		{name: "hyphen and special", args: args{nick: "test[-]"}, want: true},
		{name: "invalid middle", args: args{nick: "test!test"}, want: false},
		{name: "invalid dot middle", args: args{nick: "test.test"}, want: false},
		{name: "end", args: args{nick: "test!"}, want: false},
		{name: "invalid start", args: args{nick: "!test"}, want: false},
		{name: "backslash and numeric", args: args{nick: "test[\\0"}, want: true},
		{name: "long", args: args{nick: "test123456789AZBKASDLASMDLKM"}, want: true},
		{name: "index 0 dash", args: args{nick: "-test"}, want: false},
		{name: "index 0 numeric", args: args{nick: "0test"}, want: false},
	}
	for _, tt := range tests {
		if got := IsValidNick(tt.args.nick); got != tt.want {
			t.Errorf("%s: IsValidNick() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestIsValidChannel(t *testing.T) {
	type args struct {
		channel string
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "valid channel", args: args{channel: "#valid"}, want: true},
		{name: "invalid channel comma", args: args{channel: "#invalid,"}, want: false},
		{name: "invalid channel space", args: args{channel: "#inva lid"}, want: false},
		{name: "valid channel with numerics", args: args{channel: "#1valid0"}, want: true},
		{name: "valid channel with special", args: args{channel: "#valid[]test"}, want: true},
		{name: "valid channel with special", args: args{channel: "#[]valid[]test[]"}, want: true},
		{name: "just hash", args: args{channel: "#"}, want: false},
		{name: "empty", args: args{channel: ""}, want: false},
		{name: "invalid prefix", args: args{channel: "$invalid"}, want: false},
		{name: "too long", args: args{channel: "#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, want: false},
		{name: "valid id prefix", args: args{channel: "!12345test"}, want: true},
		{name: "invalid id length", args: args{channel: "!1234"}, want: false},
		{name: "invalid id length", args: args{channel: "!12345"}, want: false},
		{name: "invalid id prefix", args: args{channel: "!test1invalid"}, want: false},
	}
	for _, tt := range tests {
		if got := IsValidChannel(tt.args.channel); got != tt.want {
			t.Errorf("%s: IsValidChannel() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestIsValidUser(t *testing.T) {
	type args struct {
		name string
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "user without ident server", args: args{name: "~test"}, want: true},
		{name: "user with ident server", args: args{name: "test"}, want: true},
		{name: "non-alphanumeric first index", args: args{name: "-test"}, want: false},
		{name: "non-alphanumeric first index", args: args{name: "[test]"}, want: false},
		{name: "numeric first index", args: args{name: "0test"}, want: true},
		{name: "blank", args: args{name: ""}, want: false},
		{name: "just tilde", args: args{name: "~"}, want: false},
		{name: "special chars", args: args{name: "test-----"}, want: true},
		{name: "special chars", args: args{name: "test-[]-"}, want: true},
		{name: "special chars, invalid after first index", args: args{name: "t!--"}, want: false},
	}
	for _, tt := range tests {
		if got := IsValidUser(tt.args.name); got != tt.want {
			t.Errorf("%s: IsValidUser() = %v, want %v", tt.name, got, tt.want)
		}
	}
}

func TestToRFC1459(t *testing.T) {
	cases := []struct {
		in   string
		want string
	}{
		{"", ""},
		{"a", "a"},
		{"abcd", "abcd"},
		{"AbcD", "abcd"},
		{"!@#$%^&*()_+-=", "!@#$%~&*()_+-="},
		{"Abcd[]", "abcd{}"},
	}

	for _, tt := range cases {
		if got := ToRFC1459(tt.in); got != tt.want {
			t.Errorf("ToRFC1459() = %q, want %q", got, tt.want)
		}
	}

	return
}

func BenchmarkGlob(b *testing.B) {
	for i := 0; i < b.N; i++ {
		if !Glob("*quick*fox*dog", "The quick brown fox jumped over the lazy dog") {
			b.Fatalf("should match")
		}
	}

	return
}

func testGlobMatch(t *testing.T, subj, pattern string) {
	if !Glob(subj, pattern) {
		t.Fatalf("'%s' should match '%s'", pattern, subj)
	}

	return
}

func testGlobNoMatch(t *testing.T, subj, pattern string) {
	if Glob(subj, pattern) {
		t.Fatalf("'%s' should not match '%s'", pattern, subj)
	}

	return
}

func TestEmptyPattern(t *testing.T) {
	testGlobMatch(t, "", "")
	testGlobNoMatch(t, "test", "")

	return
}

func TestEmptySubject(t *testing.T) {
	cases := []string{
		"",
		"*",
		"**",
		"***",
		"****************",
		strings.Repeat("*", 1000000),
	}

	for _, pattern := range cases {
		testGlobMatch(t, "", pattern)
	}

	cases = []string{
		// No globs/non-glob characters.
		"test",
		"*test*",

		// Trailing characters.
		"*x",
		"*****************x",
		strings.Repeat("*", 1000000) + "x",

		// Leading characters.
		"x*",
		"x*****************",
		"x" + strings.Repeat("*", 1000000),

		// Mixed leading/trailing characters.
		"x*x",
		"x****************x",
		"x" + strings.Repeat("*", 1000000) + "x",
	}

	for _, pattern := range cases {
		testGlobNoMatch(t, pattern, "")
	}

	return
}

func TestPatternWithoutGlobs(t *testing.T) {
	testGlobMatch(t, "test", "test")

	return
}

func TestGlob(t *testing.T) {
	cases := []string{
		"*test",           // Leading.
		"this*",           // Trailing.
		"this*test",       // Middle.
		"*is *",           // String in between two.
		"*is*a*",          // Lots.
		"**test**",        // Double glob characters.
		"**is**a***test*", // Varying number.
		"* *",             // White space between.
		"*",               // Lone.
		"**********",      // Nothing but globs.
		"*Ѿ*",             // Unicode.
		"*is a ϗѾ *",      // Mixed ASCII/unicode.
	}

	for _, pattern := range cases {
		testGlobMatch(t, "this is a ϗѾ test", pattern)
	}

	cases = []string{
		"test*", // Implicit substring match.
		"*is",   // Partial match.
		"*no*",  // Globs without a match between them.
		" ",     // Plain white space.
		"* ",    // Trailing white space.
		" *",    // Leading white space.
		"*ʤ*",   // Non-matching unicode.
	}

	// Non-matches
	for _, pattern := range cases {
		testGlobNoMatch(t, "this is a test", pattern)
	}

	return
}
<|endoftext|>


<commit_before>package runtime

import (
	"encoding/base64"
	"fmt"
	"strconv"
	"strings"

	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/durationpb"
	"google.golang.org/protobuf/types/known/timestamppb"
	"google.golang.org/protobuf/types/known/wrapperspb"
)

// String just returns the given string.
// It is just for compatibility to other types.
func String(val string) (string, error) {
	return val, nil
}

// StringSlice converts 'val' where individual strings are separated by
// 'sep' into a string slice.
func StringSlice(val, sep string) ([]string, error) {
	return strings.Split(val, sep), nil
}

// Bool converts the given string representation of a boolean value into bool.
func Bool(val string) (bool, error) {
	return strconv.ParseBool(val)
}

// BoolSlice converts 'val' where individual booleans are separated by
// 'sep' into a bool slice.
func BoolSlice(val, sep string) ([]bool, error) {
	s := strings.Split(val, sep)
	values := make([]bool, len(s))
	for i, v := range s {
		value, err := Bool(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Float64 converts the given string representation into representation of a floating point number into float64.
func Float64(val string) (float64, error) {
	return strconv.ParseFloat(val, 64)
}

// Float64Slice converts 'val' where individual floating point numbers are separated by
// 'sep' into a float64 slice.
func Float64Slice(val, sep string) ([]float64, error) {
	s := strings.Split(val, sep)
	values := make([]float64, len(s))
	for i, v := range s {
		value, err := Float64(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Float32 converts the given string representation of a floating point number into float32.
func Float32(val string) (float32, error) {
	f, err := strconv.ParseFloat(val, 32)
	if err != nil {
		return 0, err
	}
	return float32(f), nil
}

// Float32Slice converts 'val' where individual floating point numbers are separated by
// 'sep' into a float32 slice.
func Float32Slice(val, sep string) ([]float32, error) {
	s := strings.Split(val, sep)
	values := make([]float32, len(s))
	for i, v := range s {
		value, err := Float32(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Int64 converts the given string representation of an integer into int64.
func Int64(val string) (int64, error) {
	return strconv.ParseInt(val, 0, 64)
}

// Int64Slice converts 'val' where individual integers are separated by
// 'sep' into a int64 slice.
func Int64Slice(val, sep string) ([]int64, error) {
	s := strings.Split(val, sep)
	values := make([]int64, len(s))
	for i, v := range s {
		value, err := Int64(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Int32 converts the given string representation of an integer into int32.
func Int32(val string) (int32, error) {
	i, err := strconv.ParseInt(val, 0, 32)
	if err != nil {
		return 0, err
	}
	return int32(i), nil
}

// Int32Slice converts 'val' where individual integers are separated by
// 'sep' into a int32 slice.
func Int32Slice(val, sep string) ([]int32, error) {
	s := strings.Split(val, sep)
	values := make([]int32, len(s))
	for i, v := range s {
		value, err := Int32(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Uint64 converts the given string representation of an integer into uint64.
func Uint64(val string) (uint64, error) {
	return strconv.ParseUint(val, 0, 64)
}

// Uint64Slice converts 'val' where individual integers are separated by
// 'sep' into a uint64 slice.
func Uint64Slice(val, sep string) ([]uint64, error) {
	s := strings.Split(val, sep)
	values := make([]uint64, len(s))
	for i, v := range s {
		value, err := Uint64(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Uint32 converts the given string representation of an integer into uint32.
func Uint32(val string) (uint32, error) {
	i, err := strconv.ParseUint(val, 0, 32)
	if err != nil {
		return 0, err
	}
	return uint32(i), nil
}

// Uint32Slice converts 'val' where individual integers are separated by
// 'sep' into a uint32 slice.
func Uint32Slice(val, sep string) ([]uint32, error) {
	s := strings.Split(val, sep)
	values := make([]uint32, len(s))
	for i, v := range s {
		value, err := Uint32(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Bytes converts the given string representation of a byte sequence into a slice of bytes
// A bytes sequence is encoded in URL-safe base64 without padding
func Bytes(val string) ([]byte, error) {
	b, err := base64.StdEncoding.DecodeString(val)
	if err != nil {
		b, err = base64.URLEncoding.DecodeString(val)
		if err != nil {
			return nil, err
		}
	}
	return b, nil
}

// BytesSlice converts 'val' where individual bytes sequences, encoded in URL-safe
// base64 without padding, are separated by 'sep' into a slice of bytes slices slice.
func BytesSlice(val, sep string) ([][]byte, error) {
	s := strings.Split(val, sep)
	values := make([][]byte, len(s))
	for i, v := range s {
		value, err := Bytes(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp.
func Timestamp(val string) (*timestamppb.Timestamp, error) {
	var r timestamppb.Timestamp
	val = strconv.Quote(strings.Trim(val, `"`))
	unmarshaler := &protojson.UnmarshalOptions{}
	err := unmarshaler.Unmarshal([]byte(val), &r)
	if err != nil {
		return nil, err
	}
	return &r, nil
}

// Duration converts the given string into a timestamp.Duration.
func Duration(val string) (*durationpb.Duration, error) {
	var r durationpb.Duration
	val = strconv.Quote(strings.Trim(val, `"`))
	unmarshaler := &protojson.UnmarshalOptions{}
	err := unmarshaler.Unmarshal([]byte(val), &r)
	if err != nil {
		return nil, err
	}
	return &r, nil
}

// Enum converts the given string into an int32 that should be type casted into the
// correct enum proto type.
func Enum(val string, enumValMap map[string]int32) (int32, error) {
	e, ok := enumValMap[val]
	if ok {
		return e, nil
	}

	i, err := Int32(val)
	if err != nil {
		return 0, fmt.Errorf("%s is not valid", val)
	}
	for _, v := range enumValMap {
		if v == i {
			return i, nil
		}
	}
	return 0, fmt.Errorf("%s is not valid", val)
}

// EnumSlice converts 'val' where individual enums are separated by 'sep'
// into a int32 slice. Each individual int32 should be type casted into the
// correct enum proto type.
func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) {
	s := strings.Split(val, sep)
	values := make([]int32, len(s))
	for i, v := range s {
		value, err := Enum(v, enumValMap)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

/*
	Support fot google.protobuf.wrappers on top of primitive types
*/

// StringValue well-known type support as wrapper around string type
func StringValue(val string) (*wrapperspb.StringValue, error) {
	return &wrapperspb.StringValue{Value: val}, nil
}

// FloatValue well-known type support as wrapper around float32 type
func FloatValue(val string) (*wrapperspb.FloatValue, error) {
	parsedVal, err := Float32(val)
	return &wrapperspb.FloatValue{Value: parsedVal}, err
}

// DoubleValue well-known type support as wrapper around float64 type
func DoubleValue(val string) (*wrapperspb.DoubleValue, error) {
	parsedVal, err := Float64(val)
	return &wrapperspb.DoubleValue{Value: parsedVal}, err
}

// BoolValue well-known type support as wrapper around bool type
func BoolValue(val string) (*wrapperspb.BoolValue, error) {
	parsedVal, err := Bool(val)
	return &wrapperspb.BoolValue{Value: parsedVal}, err
}

// Int32Value well-known type support as wrapper around int32 type
func Int32Value(val string) (*wrapperspb.Int32Value, error) {
	parsedVal, err := Int32(val)
	return &wrapperspb.Int32Value{Value: parsedVal}, err
}

// UInt32Value well-known type support as wrapper around uint32 type
func UInt32Value(val string) (*wrapperspb.UInt32Value, error) {
	parsedVal, err := Uint32(val)
	return &wrapperspb.UInt32Value{Value: parsedVal}, err
}

// Int64Value well-known type support as wrapper around int64 type
func Int64Value(val string) (*wrapperspb.Int64Value, error) {
	parsedVal, err := Int64(val)
	return &wrapperspb.Int64Value{Value: parsedVal}, err
}

// UInt64Value well-known type support as wrapper around uint64 type
func UInt64Value(val string) (*wrapperspb.UInt64Value, error) {
	parsedVal, err := Uint64(val)
	return &wrapperspb.UInt64Value{Value: parsedVal}, err
}

// BytesValue well-known type support as wrapper around bytes[] type
func BytesValue(val string) (*wrapperspb.BytesValue, error) {
	parsedVal, err := Bytes(val)
	return &wrapperspb.BytesValue{Value: parsedVal}, err
}
<commit_msg>fix typos (#2474)<commit_after>package runtime

import (
	"encoding/base64"
	"fmt"
	"strconv"
	"strings"

	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/durationpb"
	"google.golang.org/protobuf/types/known/timestamppb"
	"google.golang.org/protobuf/types/known/wrapperspb"
)

// String just returns the given string.
// It is just for compatibility to other types.
func String(val string) (string, error) {
	return val, nil
}

// StringSlice converts 'val' where individual strings are separated by
// 'sep' into a string slice.
func StringSlice(val, sep string) ([]string, error) {
	return strings.Split(val, sep), nil
}

// Bool converts the given string representation of a boolean value into bool.
func Bool(val string) (bool, error) {
	return strconv.ParseBool(val)
}

// BoolSlice converts 'val' where individual booleans are separated by
// 'sep' into a bool slice.
func BoolSlice(val, sep string) ([]bool, error) {
	s := strings.Split(val, sep)
	values := make([]bool, len(s))
	for i, v := range s {
		value, err := Bool(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Float64 converts the given string representation into representation of a floating point number into float64.
func Float64(val string) (float64, error) {
	return strconv.ParseFloat(val, 64)
}

// Float64Slice converts 'val' where individual floating point numbers are separated by
// 'sep' into a float64 slice.
func Float64Slice(val, sep string) ([]float64, error) {
	s := strings.Split(val, sep)
	values := make([]float64, len(s))
	for i, v := range s {
		value, err := Float64(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Float32 converts the given string representation of a floating point number into float32.
func Float32(val string) (float32, error) {
	f, err := strconv.ParseFloat(val, 32)
	if err != nil {
		return 0, err
	}
	return float32(f), nil
}

// Float32Slice converts 'val' where individual floating point numbers are separated by
// 'sep' into a float32 slice.
func Float32Slice(val, sep string) ([]float32, error) {
	s := strings.Split(val, sep)
	values := make([]float32, len(s))
	for i, v := range s {
		value, err := Float32(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Int64 converts the given string representation of an integer into int64.
func Int64(val string) (int64, error) {
	return strconv.ParseInt(val, 0, 64)
}

// Int64Slice converts 'val' where individual integers are separated by
// 'sep' into a int64 slice.
func Int64Slice(val, sep string) ([]int64, error) {
	s := strings.Split(val, sep)
	values := make([]int64, len(s))
	for i, v := range s {
		value, err := Int64(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Int32 converts the given string representation of an integer into int32.
func Int32(val string) (int32, error) {
	i, err := strconv.ParseInt(val, 0, 32)
	if err != nil {
		return 0, err
	}
	return int32(i), nil
}

// Int32Slice converts 'val' where individual integers are separated by
// 'sep' into a int32 slice.
func Int32Slice(val, sep string) ([]int32, error) {
	s := strings.Split(val, sep)
	values := make([]int32, len(s))
	for i, v := range s {
		value, err := Int32(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Uint64 converts the given string representation of an integer into uint64.
func Uint64(val string) (uint64, error) {
	return strconv.ParseUint(val, 0, 64)
}

// Uint64Slice converts 'val' where individual integers are separated by
// 'sep' into a uint64 slice.
func Uint64Slice(val, sep string) ([]uint64, error) {
	s := strings.Split(val, sep)
	values := make([]uint64, len(s))
	for i, v := range s {
		value, err := Uint64(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Uint32 converts the given string representation of an integer into uint32.
func Uint32(val string) (uint32, error) {
	i, err := strconv.ParseUint(val, 0, 32)
	if err != nil {
		return 0, err
	}
	return uint32(i), nil
}

// Uint32Slice converts 'val' where individual integers are separated by
// 'sep' into a uint32 slice.
func Uint32Slice(val, sep string) ([]uint32, error) {
	s := strings.Split(val, sep)
	values := make([]uint32, len(s))
	for i, v := range s {
		value, err := Uint32(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Bytes converts the given string representation of a byte sequence into a slice of bytes
// A bytes sequence is encoded in URL-safe base64 without padding
func Bytes(val string) ([]byte, error) {
	b, err := base64.StdEncoding.DecodeString(val)
	if err != nil {
		b, err = base64.URLEncoding.DecodeString(val)
		if err != nil {
			return nil, err
		}
	}
	return b, nil
}

// BytesSlice converts 'val' where individual bytes sequences, encoded in URL-safe
// base64 without padding, are separated by 'sep' into a slice of bytes slices slice.
func BytesSlice(val, sep string) ([][]byte, error) {
	s := strings.Split(val, sep)
	values := make([][]byte, len(s))
	for i, v := range s {
		value, err := Bytes(v)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

// Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp.
func Timestamp(val string) (*timestamppb.Timestamp, error) {
	var r timestamppb.Timestamp
	val = strconv.Quote(strings.Trim(val, `"`))
	unmarshaler := &protojson.UnmarshalOptions{}
	err := unmarshaler.Unmarshal([]byte(val), &r)
	if err != nil {
		return nil, err
	}
	return &r, nil
}

// Duration converts the given string into a timestamp.Duration.
func Duration(val string) (*durationpb.Duration, error) {
	var r durationpb.Duration
	val = strconv.Quote(strings.Trim(val, `"`))
	unmarshaler := &protojson.UnmarshalOptions{}
	err := unmarshaler.Unmarshal([]byte(val), &r)
	if err != nil {
		return nil, err
	}
	return &r, nil
}

// Enum converts the given string into an int32 that should be type casted into the
// correct enum proto type.
func Enum(val string, enumValMap map[string]int32) (int32, error) {
	e, ok := enumValMap[val]
	if ok {
		return e, nil
	}

	i, err := Int32(val)
	if err != nil {
		return 0, fmt.Errorf("%s is not valid", val)
	}
	for _, v := range enumValMap {
		if v == i {
			return i, nil
		}
	}
	return 0, fmt.Errorf("%s is not valid", val)
}

// EnumSlice converts 'val' where individual enums are separated by 'sep'
// into a int32 slice. Each individual int32 should be type casted into the
// correct enum proto type.
func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) {
	s := strings.Split(val, sep)
	values := make([]int32, len(s))
	for i, v := range s {
		value, err := Enum(v, enumValMap)
		if err != nil {
			return values, err
		}
		values[i] = value
	}
	return values, nil
}

/*
	Support for google.protobuf.wrappers on top of primitive types
*/

// StringValue well-known type support as wrapper around string type
func StringValue(val string) (*wrapperspb.StringValue, error) {
	return &wrapperspb.StringValue{Value: val}, nil
}

// FloatValue well-known type support as wrapper around float32 type
func FloatValue(val string) (*wrapperspb.FloatValue, error) {
	parsedVal, err := Float32(val)
	return &wrapperspb.FloatValue{Value: parsedVal}, err
}

// DoubleValue well-known type support as wrapper around float64 type
func DoubleValue(val string) (*wrapperspb.DoubleValue, error) {
	parsedVal, err := Float64(val)
	return &wrapperspb.DoubleValue{Value: parsedVal}, err
}

// BoolValue well-known type support as wrapper around bool type
func BoolValue(val string) (*wrapperspb.BoolValue, error) {
	parsedVal, err := Bool(val)
	return &wrapperspb.BoolValue{Value: parsedVal}, err
}

// Int32Value well-known type support as wrapper around int32 type
func Int32Value(val string) (*wrapperspb.Int32Value, error) {
	parsedVal, err := Int32(val)
	return &wrapperspb.Int32Value{Value: parsedVal}, err
}

// UInt32Value well-known type support as wrapper around uint32 type
func UInt32Value(val string) (*wrapperspb.UInt32Value, error) {
	parsedVal, err := Uint32(val)
	return &wrapperspb.UInt32Value{Value: parsedVal}, err
}

// Int64Value well-known type support as wrapper around int64 type
func Int64Value(val string) (*wrapperspb.Int64Value, error) {
	parsedVal, err := Int64(val)
	return &wrapperspb.Int64Value{Value: parsedVal}, err
}

// UInt64Value well-known type support as wrapper around uint64 type
func UInt64Value(val string) (*wrapperspb.UInt64Value, error) {
	parsedVal, err := Uint64(val)
	return &wrapperspb.UInt64Value{Value: parsedVal}, err
}

// BytesValue well-known type support as wrapper around bytes[] type
func BytesValue(val string) (*wrapperspb.BytesValue, error) {
	parsedVal, err := Bytes(val)
	return &wrapperspb.BytesValue{Value: parsedVal}, err
}
<|endoftext|>


<commit_before>package traffic

import (
  "os"
  "fmt"
  "log"
  "net/http"
  "github.com/pilu/config"
)

type HttpMethod string

type BeforeFilterFunc func(ResponseWriter, *http.Request) bool

type NextMiddlewareFunc func() Middleware

type Middleware interface {
  ServeHTTP(ResponseWriter, *http.Request, NextMiddlewareFunc) (ResponseWriter, *http.Request)
}

type Router struct {
  routes map[HttpMethod][]*Route
  NotFoundHandler HttpHandleFunc
  beforeFilters []BeforeFilterFunc
  middlewares []Middleware
  env map[string]interface{}
}

func (router Router) MiddlewareEnumerator() func() Middleware {
  index := 0
  next := func() Middleware {
    if len(router.middlewares) > index {
      nextMiddleware := router.middlewares[index]
      index++
      return nextMiddleware
    }

    return nil
  }

  return next
}

func (router *Router) Add(method HttpMethod, path string, handler HttpHandleFunc) *Route {
  route := NewRoute(path, handler)
  router.addRoute(method, route)

  return route
}

func (router *Router) addRoute(method HttpMethod, route *Route) {
  router.routes[method] = append(router.routes[method], route)
}

func (router *Router) Get(path string, handler HttpHandleFunc) *Route {
  route := router.Add(HttpMethod("GET"), path, handler)
  router.addRoute(HttpMethod("HEAD"), route)

  return route
}

func (router *Router) Post(path string, handler HttpHandleFunc) *Route {
  return router.Add(HttpMethod("POST"), path, handler)
}

func (router *Router) Delete(path string, handler HttpHandleFunc) *Route {
  return router.Add(HttpMethod("DELETE"), path, handler)
}

func (router *Router) Put(path string, handler HttpHandleFunc) *Route {
  return router.Add(HttpMethod("PUT"), path, handler)
}

func (router *Router) Patch(path string, handler HttpHandleFunc) *Route {
  return router.Add(HttpMethod("PATCH"), path, handler)
}

func (router *Router) AddBeforeFilter(beforeFilter BeforeFilterFunc) *Router {
  router.beforeFilters = append(router.beforeFilters, beforeFilter)

  return router
}

func (router *Router) handleNotFound (w ResponseWriter, r *http.Request) {
  if router.NotFoundHandler != nil {
    router.NotFoundHandler(w, r)
  } else {
    fmt.Fprint(w, "404 page not found")
  }
}

func (router *Router) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
  w := newAppResponseWriter(rw, &router.env)
  w.Header().Set("Content-Type", "text/html")

  nextMiddlewareFunc := router.MiddlewareEnumerator()
  if nextMiddleware := nextMiddlewareFunc(); nextMiddleware != nil {
    nextMiddleware.ServeHTTP(w, r, nextMiddlewareFunc)
  }

  if w.StatusCode() == http.StatusNotFound {
    router.handleNotFound(w, r)
  }
}

func (router *Router) AddMiddleware(middleware Middleware) {
  router.middlewares = append([]Middleware{middleware}, router.middlewares...)
}

func (router *Router) SetVar(key string, value interface{}) {
  router.env[key] = value
}

func (router *Router) GetVar(key string) interface{} {
  value := router.env[key]
  if value != nil {
    return value
  }

  return GetVar(key)
}

func (router *Router) loadConfigurationsFromFile(path, env string) {
  mainSectionName := "main"
  sections, err := config.ParseFile(path, mainSectionName)
  if err != nil {
    panic(err)
  }

  for section, options := range sections {
    if section == mainSectionName || section == env {
      for key, value := range options {
        router.SetVar(key, value)
      }
    }
  }
}

func addDevelopmentMiddlewares(router *Router) {
  // Static middleware
  router.AddMiddleware(NewStaticMiddleware(PublicPath()))

  // Logger middleware
  loggerMiddleware := &LoggerMiddleware{
    router: router,
  }
  router.AddMiddleware(loggerMiddleware)

  // ShowErrors middleware
  router.AddMiddleware(&ShowErrorsMiddleware{})
}

func (router *Router) Run() {
  address := fmt.Sprintf("%s:%d", Host(), Port())
  Logger().Printf("Starting in %s on %s", Env(), address)
  err := http.ListenAndServe(address, router)
  if err != nil {
    log.Fatal(err)
  }
}

func New() *Router {
  router := &Router{}
  router.routes = make(map[HttpMethod][]*Route)
  router.beforeFilters = make([]BeforeFilterFunc, 0)
  router.middlewares = make([]Middleware, 0)
  router.env = make(map[string]interface{})

  routerMiddleware := &RouterMiddleware{ router }
  router.AddMiddleware(routerMiddleware)

  // Environment
  env := Env()

  // Add useful middlewares for development
  if env == EnvDevelopment {
    addDevelopmentMiddlewares(router)
  }

  // configuration
  configFile := ConfigFilePath()
  if _, err := os.Stat(configFile); err == nil {
    router.loadConfigurationsFromFile(configFile, env)
  }

  initTemplateManager()

  return router
}

<commit_msg>refactoring<commit_after>package traffic

import (
  "os"
  "fmt"
  "log"
  "net/http"
  "github.com/pilu/config"
)

type HttpMethod string

type BeforeFilterFunc func(ResponseWriter, *http.Request) bool

type NextMiddlewareFunc func() Middleware

type Middleware interface {
  ServeHTTP(ResponseWriter, *http.Request, NextMiddlewareFunc) (ResponseWriter, *http.Request)
}

type Router struct {
  NotFoundHandler HttpHandleFunc
  routes          map[HttpMethod][]*Route
  beforeFilters   []BeforeFilterFunc
  middlewares     []Middleware
  env             map[string]interface{}
}

func (router Router) MiddlewareEnumerator() func() Middleware {
  index := 0
  next := func() Middleware {
    if len(router.middlewares) > index {
      nextMiddleware := router.middlewares[index]
      index++
      return nextMiddleware
    }

    return nil
  }

  return next
}

func (router *Router) Add(method HttpMethod, path string, handler HttpHandleFunc) *Route {
  route := NewRoute(path, handler)
  router.addRoute(method, route)

  return route
}

func (router *Router) addRoute(method HttpMethod, route *Route) {
  router.routes[method] = append(router.routes[method], route)
}

func (router *Router) Get(path string, handler HttpHandleFunc) *Route {
  route := router.Add(HttpMethod("GET"), path, handler)
  router.addRoute(HttpMethod("HEAD"), route)

  return route
}

func (router *Router) Post(path string, handler HttpHandleFunc) *Route {
  return router.Add(HttpMethod("POST"), path, handler)
}

func (router *Router) Delete(path string, handler HttpHandleFunc) *Route {
  return router.Add(HttpMethod("DELETE"), path, handler)
}

func (router *Router) Put(path string, handler HttpHandleFunc) *Route {
  return router.Add(HttpMethod("PUT"), path, handler)
}

func (router *Router) Patch(path string, handler HttpHandleFunc) *Route {
  return router.Add(HttpMethod("PATCH"), path, handler)
}

func (router *Router) AddBeforeFilter(beforeFilter BeforeFilterFunc) *Router {
  router.beforeFilters = append(router.beforeFilters, beforeFilter)

  return router
}

func (router *Router) handleNotFound (w ResponseWriter, r *http.Request) {
  if router.NotFoundHandler != nil {
    router.NotFoundHandler(w, r)
  } else {
    fmt.Fprint(w, "404 page not found")
  }
}

func (router *Router) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
  w := newAppResponseWriter(rw, &router.env)
  w.Header().Set("Content-Type", "text/html")

  nextMiddlewareFunc := router.MiddlewareEnumerator()
  if nextMiddleware := nextMiddlewareFunc(); nextMiddleware != nil {
    nextMiddleware.ServeHTTP(w, r, nextMiddlewareFunc)
  }

  if w.StatusCode() == http.StatusNotFound {
    router.handleNotFound(w, r)
  }
}

func (router *Router) AddMiddleware(middleware Middleware) {
  router.middlewares = append([]Middleware{middleware}, router.middlewares...)
}

func (router *Router) SetVar(key string, value interface{}) {
  router.env[key] = value
}

func (router *Router) GetVar(key string) interface{} {
  value := router.env[key]
  if value != nil {
    return value
  }

  return GetVar(key)
}

func (router *Router) loadConfigurationsFromFile(path, env string) {
  mainSectionName := "main"
  sections, err := config.ParseFile(path, mainSectionName)
  if err != nil {
    panic(err)
  }

  for section, options := range sections {
    if section == mainSectionName || section == env {
      for key, value := range options {
        router.SetVar(key, value)
      }
    }
  }
}

func addDevelopmentMiddlewares(router *Router) {
  // Static middleware
  router.AddMiddleware(NewStaticMiddleware(PublicPath()))

  // Logger middleware
  loggerMiddleware := &LoggerMiddleware{
    router: router,
  }
  router.AddMiddleware(loggerMiddleware)

  // ShowErrors middleware
  router.AddMiddleware(&ShowErrorsMiddleware{})
}

func (router *Router) Run() {
  address := fmt.Sprintf("%s:%d", Host(), Port())
  Logger().Printf("Starting in %s on %s", Env(), address)
  err := http.ListenAndServe(address, router)
  if err != nil {
    log.Fatal(err)
  }
}

func New() *Router {
  router := &Router{
    routes:         make(map[HttpMethod][]*Route),
    beforeFilters:  make([]BeforeFilterFunc, 0),
    middlewares:    make([]Middleware, 0),
    env:            make(map[string]interface{}),
  }

  routerMiddleware := &RouterMiddleware{ router }
  router.AddMiddleware(routerMiddleware)

  // Environment
  env := Env()

  // Add useful middlewares for development
  if env == EnvDevelopment {
    addDevelopmentMiddlewares(router)
  }

  // configuration
  configFile := ConfigFilePath()
  if _, err := os.Stat(configFile); err == nil {
    router.loadConfigurationsFromFile(configFile, env)
  }

  initTemplateManager()

  return router
}

<|endoftext|>


<commit_before>package nom

import (
	"bytes"
	"encoding/gob"
	"encoding/json"
	"fmt"
)

// Port is either a physical or a virtual port of a node.
type Port struct {
	ID    PortID
	Node  UID
	Links []UID
}

// PortID is the ID of a port and is unique among the ports of a node.
type PortID string

// UID returns the unique ID of the port in the form of
// net_id$$node_id$$port_id.
func (p Port) UID() UID {
	return UIDJoin(string(p.Node), string(p.ID))
}

// ParsePortUID parses a UID of a port and returns the respective network, node,
// and port IDs.
func ParsePortUID(id UID) (NetworkID, NodeID, PortID) {
	s := UIDSplit(id)
	return NetworkID(s[0]), NodeID(s[1]), PortID(s[2])
}

// AddLink adds an outgoing link to the port. Return an error if the link does
// not belong to this port.
func (p *Port) AddLink(l Link) error {
	if l.From != p.UID() {
		return fmt.Errorf("Link is outgoing from %s not from %s", l.From, p.UID())
	}

	p.Links = append(p.Links, l.UID())
	return nil
}

// GOBDecode decodes the port from b using GOB.
func (p *Port) GOBDecode(b []byte) error {
	buf := bytes.NewBuffer(b)
	dec := gob.NewDecoder(buf)
	return dec.Decode(p)
}

// GOBEncode encodes the port into a byte array using GOB.
func (p *Port) GOBEncode() ([]byte, error) {
	var buf bytes.Buffer
	enc := gob.NewEncoder(&buf)
	err := enc.Encode(p)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// JSONDecode decodes the port from a byte array using JSON.
func (p *Port) JSONDecode(b []byte) error {
	return json.Unmarshal(b, p)
}

// JSONEncode encodes the port into a byte array using JSON.
func (p *Port) JSONEncode() ([]byte, error) {
	return json.Marshal(p)
}
<commit_msg>Use generic encoding/decoding impl for nom.Port<commit_after>package nom

import (
	"bytes"
	"encoding/gob"
	"encoding/json"
	"fmt"
)

// Port is either a physical or a virtual port of a node.
type Port struct {
	ID    PortID
	Node  UID
	Links []UID
}

// PortID is the ID of a port and is unique among the ports of a node.
type PortID string

// UID returns the unique ID of the port in the form of
// net_id$$node_id$$port_id.
func (p Port) UID() UID {
	return UIDJoin(string(p.Node), string(p.ID))
}

// ParsePortUID parses a UID of a port and returns the respective node and port
// IDs.
func ParsePortUID(id UID) (NodeID, PortID) {
	s := UIDSplit(id)
	return NodeID(s[0]), PortID(s[1])
}

// GobDecode decodes the port from b using Gob.
func (p *Port) GobDecode(b []byte) error {
	return ObjGobDecode(p, b)
}

// GobEncode encodes the port into a byte array using Gob.
func (p *Port) GobEncode() ([]byte, error) {
	return ObjGobEncode(p)
}

// JSONDecode decodes the port from a byte array using JSON.
func (p *Port) JSONDecode(b []byte) error {
	return json.Unmarshal(b, p)
}

// JSONEncode encodes the port into a byte array using JSON.
func (p *Port) JSONEncode() ([]byte, error) {
	return json.Marshal(p)
}
<|endoftext|>


<commit_before>package main

import "fmt"
//import "github.com/lucasb-eyer/go-colorful"
import "go-colorful"
import "image"
import "image/draw"
//import "image/color"
import "image/png"
import "os"

func main() {
    blocks := 10
    blockw := 40
    img := image.NewRGBA(image.Rect(0,0,blocks*blockw,200))

    c1, _ := colorful.Hex("#fdffcc")
    c2, _ := colorful.Hex("#242a42")

    // Use these colors to get invalid RGB in the gradient.
    //c1, _ := colorful.Hex("#EEEF61")
    //c2, _ := colorful.Hex("#1E3140")

    for i := 0 ; i < blocks ; i++ {
        draw.Draw(img, image.Rect(i*blockw,  0,(i+1)*blockw, 40), &image.Uniform{c1.BlendHsv(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)
        draw.Draw(img, image.Rect(i*blockw, 40,(i+1)*blockw, 80), &image.Uniform{c1.BlendLuv(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)
        draw.Draw(img, image.Rect(i*blockw, 80,(i+1)*blockw,120), &image.Uniform{c1.BlendRgb(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)
        draw.Draw(img, image.Rect(i*blockw,120,(i+1)*blockw,160), &image.Uniform{c1.BlendLab(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)
        draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)

        // This can be used to "fix" invalid colors in the gradient.
        //draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1)).Clamped()}, image.ZP, draw.Src)
    }

    toimg, err := os.Create("colorblend.png")
    if err != nil {
        fmt.Printf("Error: %v", err)
        return
    }
    defer toimg.Close()

    png.Encode(toimg, img)
}
<commit_msg>Removed unnecessary import. Why didn't go complain?<commit_after>package main

import "fmt"
//import "github.com/lucasb-eyer/go-colorful"
import "go-colorful"
import "image"
import "image/draw"
import "image/png"
import "os"

func main() {
    blocks := 10
    blockw := 40
    img := image.NewRGBA(image.Rect(0,0,blocks*blockw,200))

    c1, _ := colorful.Hex("#fdffcc")
    c2, _ := colorful.Hex("#242a42")

    // Use these colors to get invalid RGB in the gradient.
    //c1, _ := colorful.Hex("#EEEF61")
    //c2, _ := colorful.Hex("#1E3140")

    for i := 0 ; i < blocks ; i++ {
        draw.Draw(img, image.Rect(i*blockw,  0,(i+1)*blockw, 40), &image.Uniform{c1.BlendHsv(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)
        draw.Draw(img, image.Rect(i*blockw, 40,(i+1)*blockw, 80), &image.Uniform{c1.BlendLuv(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)
        draw.Draw(img, image.Rect(i*blockw, 80,(i+1)*blockw,120), &image.Uniform{c1.BlendRgb(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)
        draw.Draw(img, image.Rect(i*blockw,120,(i+1)*blockw,160), &image.Uniform{c1.BlendLab(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)
        draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src)

        // This can be used to "fix" invalid colors in the gradient.
        //draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1)).Clamped()}, image.ZP, draw.Src)
    }

    toimg, err := os.Create("colorblend.png")
    if err != nil {
        fmt.Printf("Error: %v", err)
        return
    }
    defer toimg.Close()

    png.Encode(toimg, img)
}
<|endoftext|>