<commit_before>package meter

import (
	"net/url"
	"time"
)

type QueryMode uint8

const (
	ModeScan QueryMode = iota
	ModeExact
	ModeValues
)

func (m QueryMode) String() string {
	switch m {
	case ModeExact:
		return "exact"
	case ModeScan:
		return "scan"
	case ModeValues:
		return "values"
	}
	return "querymodeinvalid"
}

type QueryBuilder struct {
	Mode       QueryMode
	Events     []string
	Start, End time.Time
	Group      []string
	Query      url.Values
	Resolution string
}

type Query struct {
	Mode       QueryMode
	Event      Descriptor
	Start, End time.Time
	Group      []string
	Values     []map[string]string
	Resolution Resolution
	err        error
}

func (q *Query) Error() error {
	return q.err
}

func NewQueryBuilder() QueryBuilder {
	return QueryBuilder{Query: url.Values{}}
}
func (q QueryBuilder) Exact() QueryBuilder {
	q.Mode = ModeExact
	return q
}
func (q QueryBuilder) Values() QueryBuilder {
	q.Mode = ModeValues
	return q
}
func (q QueryBuilder) Scan() QueryBuilder {
	q.Mode = ModeScan
	return q
}
func (q QueryBuilder) Between(start, end time.Time) QueryBuilder {
	q.Start, q.End = start, end
	return q
}
func (q QueryBuilder) At(res Resolution) QueryBuilder {
	q.Resolution = res.Name()
	return q
}
func (q QueryBuilder) Where(label string, value ...string) QueryBuilder {
	if q.Query == nil {
		q.Query = url.Values{}
	}
	q.Query[label] = value
	return q
}
func (q QueryBuilder) GroupBy(label ...string) QueryBuilder {
	q.Group = label
	return q
}
func (q QueryBuilder) From(event ...string) QueryBuilder {
	q.Events = event
	return q
}

func (q QueryBuilder) QueryValues(d *Desc) []map[string]string {
	if d == nil || q.Query == nil {
		return nil
	}
	queries := d.MatchingQueries(q.Query)
	if len(q.Group) != 0 {
		for _, g := range q.Group {
			if !d.HasLabel(g) {
				return nil
			}
			delete(queries, g)
		}
	}
	return QueryPermutations(queries)
}

func QueryPermutations(input url.Values) []map[string]string {
	vcount := []int{}
	keys := []string{}
	combinations := [][]int{}
	for k, v := range input {
		if c := len(v); c > 0 {
			keys = append(keys, k)
			vcount = append(vcount, c)
		}
	}
	var generate func([]int)
	generate = func(comb []int) {
		if i := len(comb); i == len(vcount) {
			combinations = append(combinations, comb)
			return
		} else {
			for j := 0; j < vcount[i]; j++ {
				next := make([]int, i+1)
				if i > 0 {
					copy(next[:i], comb)
				}
				next[i] = j
				generate(next)
			}
		}
	}
	generate([]int{})
	results := make([]map[string]string, 0, len(combinations))
	for _, comb := range combinations {
		result := make(map[string]string, len(comb))
		for i, j := range comb {
			key := keys[i]
			result[key] = input[key][j]
		}
		if len(result) > 0 {
			results = append(results, result)
		}
	}
	return results
}

func (qb QueryBuilder) Queries(events Resolver) (queries []Query) {
	q := Query{
		Mode:  qb.Mode,
		Start: qb.Start,
		End:   qb.End,
	}
	if events == nil {
		events = defaultRegistry
	}
eloop:
	for i := 0; i < len(qb.Events); i++ {
		eventName := qb.Events[i]
		event := events.Get(eventName)
		if event == nil {
			q.err = ErrUnregisteredEvent
			queries = append(queries, q)
			continue
		}

		desc := event.Describe()
		if desc == nil {
			q.err = ErrNilDesc
			queries = append(queries, q)
			continue
		}
		if q.err = desc.Error(); q.err != nil {
			queries = append(queries, q)
			continue
		}
		q.Event = event
		res, hasResolution := desc.Resolution(qb.Resolution)
		if !hasResolution {
			q.err = ErrInvalidResolution
			queries = append(queries, q)
			continue
		}
		q.Resolution = res
		if qb.Mode == ModeScan && len(qb.Group) != 0 {
			for _, g := range qb.Group {
				if !desc.HasLabel(g) {
					q.err = ErrInvalidGroupLabel
					queries = append(queries, q)
					continue eloop
				}
			}
		}
		q.Group = qb.Group
		qvs := desc.MatchingQueries(qb.Query)
		if len(q.Group) != 0 {
			for _, g := range q.Group {
				delete(qvs, g)
			}
		}
		if len(qvs) == 0 {
			q.Values = []map[string]string{LabelValues{}}
		} else {
			q.Values = QueryPermutations(qvs)
		}
		queries = append(queries, q)
	}

	return

}

type Queryer interface {
	Query(queries ...Query) (Results, error)
}
<commit_msg>Fix var scope issue with QueryBuider.Queries<commit_after>package meter

import (
	"net/url"
	"time"
)

type QueryMode uint8

const (
	ModeScan QueryMode = iota
	ModeExact
	ModeValues
)

func (m QueryMode) String() string {
	switch m {
	case ModeExact:
		return "exact"
	case ModeScan:
		return "scan"
	case ModeValues:
		return "values"
	}
	return "querymodeinvalid"
}

type QueryBuilder struct {
	Mode       QueryMode
	Events     []string
	Start, End time.Time
	Group      []string
	Query      url.Values
	Resolution string
}

type Query struct {
	Mode       QueryMode
	Event      Descriptor
	Start, End time.Time
	Group      []string
	Values     []map[string]string
	Resolution Resolution
	err        error
}

func (q *Query) Error() error {
	return q.err
}

func NewQueryBuilder() QueryBuilder {
	return QueryBuilder{Query: url.Values{}}
}
func (q QueryBuilder) Exact() QueryBuilder {
	q.Mode = ModeExact
	return q
}
func (q QueryBuilder) Values() QueryBuilder {
	q.Mode = ModeValues
	return q
}
func (q QueryBuilder) Scan() QueryBuilder {
	q.Mode = ModeScan
	return q
}
func (q QueryBuilder) Between(start, end time.Time) QueryBuilder {
	q.Start, q.End = start, end
	return q
}
func (q QueryBuilder) At(res Resolution) QueryBuilder {
	q.Resolution = res.Name()
	return q
}
func (q QueryBuilder) Where(label string, value ...string) QueryBuilder {
	if q.Query == nil {
		q.Query = url.Values{}
	}
	q.Query[label] = value
	return q
}
func (q QueryBuilder) GroupBy(label ...string) QueryBuilder {
	q.Group = label
	return q
}
func (q QueryBuilder) From(event ...string) QueryBuilder {
	q.Events = event
	return q
}

func (q QueryBuilder) QueryValues(d *Desc) []map[string]string {
	if d == nil || q.Query == nil {
		return nil
	}
	queries := d.MatchingQueries(q.Query)
	if len(q.Group) != 0 {
		for _, g := range q.Group {
			if !d.HasLabel(g) {
				return nil
			}
			delete(queries, g)
		}
	}
	return QueryPermutations(queries)
}

func QueryPermutations(input url.Values) []map[string]string {
	vcount := []int{}
	keys := []string{}
	combinations := [][]int{}
	for k, v := range input {
		if c := len(v); c > 0 {
			keys = append(keys, k)
			vcount = append(vcount, c)
		}
	}
	var generate func([]int)
	generate = func(comb []int) {
		if i := len(comb); i == len(vcount) {
			combinations = append(combinations, comb)
			return
		} else {
			for j := 0; j < vcount[i]; j++ {
				next := make([]int, i+1)
				if i > 0 {
					copy(next[:i], comb)
				}
				next[i] = j
				generate(next)
			}
		}
	}
	generate([]int{})
	results := make([]map[string]string, 0, len(combinations))
	for _, comb := range combinations {
		result := make(map[string]string, len(comb))
		for i, j := range comb {
			key := keys[i]
			result[key] = input[key][j]
		}
		if len(result) > 0 {
			results = append(results, result)
		}
	}
	return results
}

func (qb QueryBuilder) Queries(events Resolver) (queries []Query) {
	if events == nil {
		events = defaultRegistry
	}
eloop:
	for i := 0; i < len(qb.Events); i++ {
		q := Query{
			Mode:  qb.Mode,
			Start: qb.Start,
			End:   qb.End,
		}
		eventName := qb.Events[i]
		event := events.Get(eventName)
		if event == nil {
			q.err = ErrUnregisteredEvent
			queries = append(queries, q)
			continue
		}

		desc := event.Describe()
		if desc == nil {
			q.err = ErrNilDesc
			queries = append(queries, q)
			continue
		}
		if q.err = desc.Error(); q.err != nil {
			queries = append(queries, q)
			continue
		}
		q.Event = event
		res, hasResolution := desc.Resolution(qb.Resolution)
		if !hasResolution {
			q.err = ErrInvalidResolution
			queries = append(queries, q)
			continue
		}
		q.Resolution = res
		if qb.Mode == ModeScan && len(qb.Group) != 0 {
			for _, g := range qb.Group {
				if !desc.HasLabel(g) {
					q.err = ErrInvalidGroupLabel
					queries = append(queries, q)
					continue eloop
				}
			}
		}
		q.Group = qb.Group
		qvs := desc.MatchingQueries(qb.Query)
		if len(q.Group) != 0 {
			for _, g := range q.Group {
				delete(qvs, g)
			}
		}
		if len(qvs) == 0 {
			q.Values = []map[string]string{LabelValues{}}
		} else {
			q.Values = QueryPermutations(qvs)
		}
		queries = append(queries, q)
	}

	return

}

type Queryer interface {
	Query(queries ...Query) (Results, error)
}
<|endoftext|>


<commit_before>// Package force provides access to Salesforce various APIs
package force

import (
	"encoding/json"
	"fmt"
	"io"
	"net/url"
)

// Query is used for retrieving query performance feedback without executing
// the query
func (c *Client) Query(query string, v interface{}) (err error) {

	endpoint := fmt.Sprintf("/query/?q=%v", url.QueryEscape(query))
	req, err := c.NewRequest("GET", endpoint, nil)

	if err != nil {
		return
	}

	resp, err := c.client.Do(req)

	if err != nil {
		return
	}

	if v != nil {
		if w, ok := v.(io.Writer); ok {
			io.Copy(w, resp.Body)
		} else {
			err = json.NewDecoder(resp.Body).Decode(v)
		}
	}

	return
}
<commit_msg>adding support for query explain<commit_after>// Package force provides access to Salesforce various APIs
package force

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/url"
)

// Query is used for retrieving query performance feedback without executing
// the query
func (c *Client) Query(query string, v interface{}) (err error) {

	endpoint := fmt.Sprintf("/query/?q=%v", url.QueryEscape(query))
	req, err := c.NewRequest("GET", endpoint, nil)

	if err != nil {
		return
	}

	resp, err := c.client.Do(req)

	if err != nil {
		return
	}

	if v != nil {
		if w, ok := v.(io.Writer); ok {
			io.Copy(w, resp.Body)
		} else {
			err = json.NewDecoder(resp.Body).Decode(v)
		}
	}

	return
}

// QueryExplain is used for retrieving query performance feedback without
// executing the query
func (c *Client) QueryExplain(query string) (explain QueryExplainResponse, err error) {

	endpoint := fmt.Sprintf("/query/?explain=%v", url.QueryEscape(query))
	req, err := c.NewRequest("GET", endpoint, nil)

	if err != nil {
		return
	}

	resp, err := c.client.Do(req)

	if err != nil {
		return
	}

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return
	}

	err = json.Unmarshal(body, &explain)

	if err != nil {
		return
	}

	return
}

// QueryExplainResponse is returned by QueryExplain
type QueryExplainResponse struct {
	Plans []struct {
		Cardinality          int      `json:"cardinality"`
		Fields               []string `json:"fields"`
		LeadingOperationType string   `json:"leadingOperationType"`
		RelativeCost         float64  `json:"relativeCost"`
		SobjectCardinality   int      `json:"sobjectCardinality"`
		SobjectType          string   `json:"sobjectType"`
		Notes                []struct {
			Description   string   `json:"description"`
			Fields        []string `json:"fields"`
			TableEnumOrID string   `json:"tableEnumOrId"`
		} `json:"notes"`
	} `json:"plans"`
}
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package time

import (
	"testing";
	"time";
)

export func TestTick(t *testing.T) {
	const (
		Delta uint64 = 10*1e6;
		Count uint64 = 10;
	);
	c := Tick(Delta);
	t0 := Nanoseconds();
	for i := 0; i < Count; i++ {
		<-c;
	}
	t1 := Nanoseconds();
	ns := t1 - t0;
	target := int64(Delta*Count);
	slop := target*2/10;
	if ns < target - slop || ns > target + slop {
		t.Fatalf("%d ticks of %d ns took %d ns, expected %d", Count, Delta, ns, target);
	}
}
<commit_msg>change time.Tick test to use 100ms intervals. now passes even under loaded conditions on r45.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package time

import (
	"testing";
	"time";
)

export func TestTick(t *testing.T) {
	const (
		Delta uint64 = 100*1e6;
		Count uint64 = 10;
	);
	c := Tick(Delta);
	t0 := Nanoseconds();
	for i := 0; i < Count; i++ {
		<-c;
	}
	t1 := Nanoseconds();
	ns := t1 - t0;
	target := int64(Delta*Count);
	slop := target*2/10;
	if ns < target - slop || ns > target + slop {
		t.Fatalf("%d ticks of %g ns took %g ns, expected %g", Count, float64(Delta), float64(ns), float64(target));
	}
}
<|endoftext|>


<commit_before>// Copyright The OpenTelemetry 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 grpctrace

// gRPC tracing middleware
// https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/rpc.md
import (
	"context"
	"io"
	"net"
	"regexp"

	"github.com/golang/protobuf/proto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/peer"
	"google.golang.org/grpc/status"

	"go.opentelemetry.io/otel/api/core"
	"go.opentelemetry.io/otel/api/correlation"
	"go.opentelemetry.io/otel/api/key"
	"go.opentelemetry.io/otel/api/trace"
)

var (
	rpcServiceKey  = key.New("rpc.service")
	netPeerIPKey   = key.New("net.peer.ip")
	netPeerPortKey = key.New("net.peer.port")

	messageTypeKey             = key.New("message.type")
	messageIDKey               = key.New("message.id")
	messageUncompressedSizeKey = key.New("message.uncompressed_size")
)

const (
	messageTypeSent     = "SENT"
	messageTypeReceived = "RECEIVED"
)

// UnaryClientInterceptor returns a grpc.UnaryClientInterceptor suitable
// for use in a grpc.Dial call.
//
// For example:
//     tracer := global.Tracer("client-tracer")
//     s := grpc.NewServer(
//         grpc.WithUnaryInterceptor(grpctrace.UnaryClientInterceptor(tracer)),
//         ...,  // (existing DialOptions))
func UnaryClientInterceptor(tracer trace.Tracer) grpc.UnaryClientInterceptor {
	return func(
		ctx context.Context,
		method string,
		req, reply interface{},
		cc *grpc.ClientConn,
		invoker grpc.UnaryInvoker,
		opts ...grpc.CallOption,
	) error {
		requestMetadata, _ := metadata.FromOutgoingContext(ctx)
		metadataCopy := requestMetadata.Copy()

		var span trace.Span
		ctx, span = tracer.Start(
			ctx, method,
			trace.WithSpanKind(trace.SpanKindClient),
			trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
			trace.WithAttributes(rpcServiceKey.String(serviceFromFullMethod(method))),
		)
		defer span.End()

		Inject(ctx, &metadataCopy)
		ctx = metadata.NewOutgoingContext(ctx, metadataCopy)

		addEventForMessageSent(ctx, 1, req)

		err := invoker(ctx, method, req, reply, cc, opts...)

		addEventForMessageReceived(ctx, 1, reply)

		if err != nil {
			s, _ := status.FromError(err)
			span.SetStatus(s.Code(), s.Message())
		}

		return err
	}
}

type streamEventType int

type streamEvent struct {
	Type streamEventType
	Err  error
}

const (
	closeEvent streamEventType = iota
	receiveEndEvent
	errorEvent
)

// clientStream  wraps around the embedded grpc.ClientStream, and intercepts the RecvMsg and
// SendMsg method call.
type clientStream struct {
	grpc.ClientStream

	desc     *grpc.StreamDesc
	events   chan streamEvent
	finished chan error

	receivedMessageID int
	sentMessageID     int
}

var _ = proto.Marshal

func (w *clientStream) RecvMsg(m interface{}) error {
	err := w.ClientStream.RecvMsg(m)

	if err == nil && !w.desc.ServerStreams {
		w.events <- streamEvent{receiveEndEvent, nil}
	} else if err == io.EOF {
		w.events <- streamEvent{receiveEndEvent, nil}
	} else if err != nil {
		w.events <- streamEvent{errorEvent, err}
	} else {
		w.receivedMessageID++
		addEventForMessageReceived(w.Context(), w.receivedMessageID, m)
	}

	return err
}

func (w *clientStream) SendMsg(m interface{}) error {
	err := w.ClientStream.SendMsg(m)

	w.sentMessageID++
	addEventForMessageSent(w.Context(), w.sentMessageID, m)

	if err != nil {
		w.events <- streamEvent{errorEvent, err}
	}

	return err
}

func (w *clientStream) Header() (metadata.MD, error) {
	md, err := w.ClientStream.Header()

	if err != nil {
		w.events <- streamEvent{errorEvent, err}
	}

	return md, err
}

func (w *clientStream) CloseSend() error {
	err := w.ClientStream.CloseSend()

	if err != nil {
		w.events <- streamEvent{errorEvent, err}
	} else {
		w.events <- streamEvent{closeEvent, nil}
	}

	return err
}

const (
	clientClosedState byte = 1 << iota
	receiveEndedState
)

func wrapClientStream(s grpc.ClientStream, desc *grpc.StreamDesc) *clientStream {
	events := make(chan streamEvent, 1)
	finished := make(chan error)

	go func() {
		// Both streams have to be closed
		state := byte(0)

		for event := range events {
			switch event.Type {
			case closeEvent:
				state |= clientClosedState
			case receiveEndEvent:
				state |= receiveEndedState
			case errorEvent:
				finished <- event.Err
				close(events)
			}

			if state == clientClosedState|receiveEndedState {
				finished <- nil
				close(events)
			}
		}
	}()

	return &clientStream{
		ClientStream: s,
		desc:         desc,
		events:       events,
		finished:     finished,
	}
}

// StreamClientInterceptor returns a grpc.StreamClientInterceptor suitable
// for use in a grpc.Dial call.
//
// For example:
//     tracer := global.Tracer("client-tracer")
//     s := grpc.Dial(
//         grpc.WithStreamInterceptor(grpctrace.StreamClientInterceptor(tracer)),
//         ...,  // (existing DialOptions))
func StreamClientInterceptor(tracer trace.Tracer) grpc.StreamClientInterceptor {
	return func(
		ctx context.Context,
		desc *grpc.StreamDesc,
		cc *grpc.ClientConn,
		method string,
		streamer grpc.Streamer,
		opts ...grpc.CallOption,
	) (grpc.ClientStream, error) {
		requestMetadata, _ := metadata.FromOutgoingContext(ctx)
		metadataCopy := requestMetadata.Copy()

		var span trace.Span
		ctx, span = tracer.Start(
			ctx, method,
			trace.WithSpanKind(trace.SpanKindClient),
			trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
			trace.WithAttributes(rpcServiceKey.String(serviceFromFullMethod(method))),
		)

		Inject(ctx, &metadataCopy)
		ctx = metadata.NewOutgoingContext(ctx, metadataCopy)

		s, err := streamer(ctx, desc, cc, method, opts...)
		stream := wrapClientStream(s, desc)

		go func() {
			if err == nil {
				err = <-stream.finished
			}

			if err != nil {
				s, _ := status.FromError(err)
				span.SetStatus(s.Code(), s.Message())
			}

			span.End()
		}()

		return stream, err
	}
}

// UnaryServerInterceptor returns a grpc.UnaryServerInterceptor suitable
// for use in a grpc.NewServer call.
//
// For example:
//     tracer := global.Tracer("client-tracer")
//     s := grpc.Dial(
//         grpc.UnaryInterceptor(grpctrace.UnaryServerInterceptor(tracer)),
//         ...,  // (existing ServerOptions))
func UnaryServerInterceptor(tracer trace.Tracer) grpc.UnaryServerInterceptor {
	return func(
		ctx context.Context,
		req interface{},
		info *grpc.UnaryServerInfo,
		handler grpc.UnaryHandler,
	) (interface{}, error) {
		requestMetadata, _ := metadata.FromIncomingContext(ctx)
		metadataCopy := requestMetadata.Copy()

		entries, spanCtx := Extract(ctx, &metadataCopy)
		ctx = correlation.ContextWithMap(ctx, correlation.NewMap(correlation.MapUpdate{
			MultiKV: entries,
		}))

		ctx, span := tracer.Start(
			trace.ContextWithRemoteSpanContext(ctx, spanCtx),
			info.FullMethod,
			trace.WithSpanKind(trace.SpanKindServer),
			trace.WithAttributes(peerInfoFromContext(ctx)...),
			trace.WithAttributes(rpcServiceKey.String(serviceFromFullMethod(info.FullMethod))),
		)
		defer span.End()

		addEventForMessageReceived(ctx, 1, req)

		resp, err := handler(ctx, req)

		addEventForMessageSent(ctx, 1, resp)

		if err != nil {
			s, _ := status.FromError(err)
			span.SetStatus(s.Code(), s.Message())
		}

		return resp, err
	}
}

// clientStream wraps around the embedded grpc.ServerStream, and intercepts the RecvMsg and
// SendMsg method call.
type serverStream struct {
	grpc.ServerStream
	ctx context.Context

	receivedMessageID int
	sentMessageID     int
}

func (w *serverStream) Context() context.Context {
	return w.ctx
}

func (w *serverStream) RecvMsg(m interface{}) error {
	err := w.ServerStream.RecvMsg(m)

	if err == nil {
		w.receivedMessageID++
		addEventForMessageReceived(w.Context(), w.receivedMessageID, m)
	}

	return err
}

func (w *serverStream) SendMsg(m interface{}) error {
	err := w.ServerStream.SendMsg(m)

	w.sentMessageID++
	addEventForMessageSent(w.Context(), w.sentMessageID, m)

	return err
}

func wrapServerStream(ctx context.Context, ss grpc.ServerStream) *serverStream {
	return &serverStream{
		ServerStream: ss,
		ctx:          ctx,
	}
}

// StreamServerInterceptor returns a grpc.StreamServerInterceptor suitable
// for use in a grpc.NewServer call.
//
// For example:
//     tracer := global.Tracer("client-tracer")
//     s := grpc.Dial(
//         grpc.StreamInterceptor(grpctrace.StreamServerInterceptor(tracer)),
//         ...,  // (existing ServerOptions))
func StreamServerInterceptor(tracer trace.Tracer) grpc.StreamServerInterceptor {
	return func(
		srv interface{},
		ss grpc.ServerStream,
		info *grpc.StreamServerInfo,
		handler grpc.StreamHandler,
	) error {
		ctx := ss.Context()

		requestMetadata, _ := metadata.FromIncomingContext(ctx)
		metadataCopy := requestMetadata.Copy()

		entries, spanCtx := Extract(ctx, &metadataCopy)
		ctx = correlation.ContextWithMap(ctx, correlation.NewMap(correlation.MapUpdate{
			MultiKV: entries,
		}))

		ctx, span := tracer.Start(
			trace.ContextWithRemoteSpanContext(ctx, spanCtx),
			info.FullMethod,
			trace.WithSpanKind(trace.SpanKindServer),
			trace.WithAttributes(peerInfoFromContext(ctx)...),
			trace.WithAttributes(rpcServiceKey.String(serviceFromFullMethod(info.FullMethod))),
		)
		defer span.End()

		err := handler(srv, wrapServerStream(ctx, ss))

		if err != nil {
			s, _ := status.FromError(err)
			span.SetStatus(s.Code(), s.Message())
		}

		return err
	}
}

func peerInfoFromTarget(target string) []core.KeyValue {
	host, port, err := net.SplitHostPort(target)

	if err != nil {
		return []core.KeyValue{}
	}

	if host == "" {
		host = "127.0.0.1"
	}

	return []core.KeyValue{
		netPeerIPKey.String(host),
		netPeerPortKey.String(port),
	}
}

func peerInfoFromContext(ctx context.Context) []core.KeyValue {
	p, ok := peer.FromContext(ctx)

	if !ok {
		return []core.KeyValue{}
	}

	return peerInfoFromTarget(p.Addr.String())
}

var fullMethodRegexp = regexp.MustCompile(`^/\S*\.(\S*)/\S*$`)

func serviceFromFullMethod(method string) string {
	match := fullMethodRegexp.FindAllStringSubmatch(method, 1)

	if len(match) != 1 && len(match[1]) != 2 {
		return ""
	}

	return match[0][1]
}

func addEventForMessageReceived(ctx context.Context, id int, m interface{}) {
	size := proto.Size(m.(proto.Message))

	span := trace.SpanFromContext(ctx)
	span.AddEvent(ctx, "message",
		messageTypeKey.String(messageTypeReceived),
		messageIDKey.Int(id),
		messageUncompressedSizeKey.Int(size),
	)
}

func addEventForMessageSent(ctx context.Context, id int, m interface{}) {
	size := proto.Size(m.(proto.Message))

	span := trace.SpanFromContext(ctx)
	span.AddEvent(ctx, "message",
		messageTypeKey.String(messageTypeSent),
		messageIDKey.Int(id),
		messageUncompressedSizeKey.Int(size),
	)
}
<commit_msg>fix interceptor regexp<commit_after>// Copyright The OpenTelemetry 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 grpctrace

// gRPC tracing middleware
// https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/rpc.md
import (
	"context"
	"io"
	"net"
	"regexp"

	"github.com/golang/protobuf/proto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/peer"
	"google.golang.org/grpc/status"

	"go.opentelemetry.io/otel/api/core"
	"go.opentelemetry.io/otel/api/correlation"
	"go.opentelemetry.io/otel/api/key"
	"go.opentelemetry.io/otel/api/trace"
)

var (
	rpcServiceKey  = key.New("rpc.service")
	netPeerIPKey   = key.New("net.peer.ip")
	netPeerPortKey = key.New("net.peer.port")

	messageTypeKey             = key.New("message.type")
	messageIDKey               = key.New("message.id")
	messageUncompressedSizeKey = key.New("message.uncompressed_size")
)

const (
	messageTypeSent     = "SENT"
	messageTypeReceived = "RECEIVED"
)

// UnaryClientInterceptor returns a grpc.UnaryClientInterceptor suitable
// for use in a grpc.Dial call.
//
// For example:
//     tracer := global.Tracer("client-tracer")
//     s := grpc.NewServer(
//         grpc.WithUnaryInterceptor(grpctrace.UnaryClientInterceptor(tracer)),
//         ...,  // (existing DialOptions))
func UnaryClientInterceptor(tracer trace.Tracer) grpc.UnaryClientInterceptor {
	return func(
		ctx context.Context,
		method string,
		req, reply interface{},
		cc *grpc.ClientConn,
		invoker grpc.UnaryInvoker,
		opts ...grpc.CallOption,
	) error {
		requestMetadata, _ := metadata.FromOutgoingContext(ctx)
		metadataCopy := requestMetadata.Copy()

		var span trace.Span
		ctx, span = tracer.Start(
			ctx, method,
			trace.WithSpanKind(trace.SpanKindClient),
			trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
			trace.WithAttributes(rpcServiceKey.String(serviceFromFullMethod(method))),
		)
		defer span.End()

		Inject(ctx, &metadataCopy)
		ctx = metadata.NewOutgoingContext(ctx, metadataCopy)

		addEventForMessageSent(ctx, 1, req)

		err := invoker(ctx, method, req, reply, cc, opts...)

		addEventForMessageReceived(ctx, 1, reply)

		if err != nil {
			s, _ := status.FromError(err)
			span.SetStatus(s.Code(), s.Message())
		}

		return err
	}
}

type streamEventType int

type streamEvent struct {
	Type streamEventType
	Err  error
}

const (
	closeEvent streamEventType = iota
	receiveEndEvent
	errorEvent
)

// clientStream  wraps around the embedded grpc.ClientStream, and intercepts the RecvMsg and
// SendMsg method call.
type clientStream struct {
	grpc.ClientStream

	desc     *grpc.StreamDesc
	events   chan streamEvent
	finished chan error

	receivedMessageID int
	sentMessageID     int
}

var _ = proto.Marshal

func (w *clientStream) RecvMsg(m interface{}) error {
	err := w.ClientStream.RecvMsg(m)

	if err == nil && !w.desc.ServerStreams {
		w.events <- streamEvent{receiveEndEvent, nil}
	} else if err == io.EOF {
		w.events <- streamEvent{receiveEndEvent, nil}
	} else if err != nil {
		w.events <- streamEvent{errorEvent, err}
	} else {
		w.receivedMessageID++
		addEventForMessageReceived(w.Context(), w.receivedMessageID, m)
	}

	return err
}

func (w *clientStream) SendMsg(m interface{}) error {
	err := w.ClientStream.SendMsg(m)

	w.sentMessageID++
	addEventForMessageSent(w.Context(), w.sentMessageID, m)

	if err != nil {
		w.events <- streamEvent{errorEvent, err}
	}

	return err
}

func (w *clientStream) Header() (metadata.MD, error) {
	md, err := w.ClientStream.Header()

	if err != nil {
		w.events <- streamEvent{errorEvent, err}
	}

	return md, err
}

func (w *clientStream) CloseSend() error {
	err := w.ClientStream.CloseSend()

	if err != nil {
		w.events <- streamEvent{errorEvent, err}
	} else {
		w.events <- streamEvent{closeEvent, nil}
	}

	return err
}

const (
	clientClosedState byte = 1 << iota
	receiveEndedState
)

func wrapClientStream(s grpc.ClientStream, desc *grpc.StreamDesc) *clientStream {
	events := make(chan streamEvent, 1)
	finished := make(chan error)

	go func() {
		// Both streams have to be closed
		state := byte(0)

		for event := range events {
			switch event.Type {
			case closeEvent:
				state |= clientClosedState
			case receiveEndEvent:
				state |= receiveEndedState
			case errorEvent:
				finished <- event.Err
				close(events)
			}

			if state == clientClosedState|receiveEndedState {
				finished <- nil
				close(events)
			}
		}
	}()

	return &clientStream{
		ClientStream: s,
		desc:         desc,
		events:       events,
		finished:     finished,
	}
}

// StreamClientInterceptor returns a grpc.StreamClientInterceptor suitable
// for use in a grpc.Dial call.
//
// For example:
//     tracer := global.Tracer("client-tracer")
//     s := grpc.Dial(
//         grpc.WithStreamInterceptor(grpctrace.StreamClientInterceptor(tracer)),
//         ...,  // (existing DialOptions))
func StreamClientInterceptor(tracer trace.Tracer) grpc.StreamClientInterceptor {
	return func(
		ctx context.Context,
		desc *grpc.StreamDesc,
		cc *grpc.ClientConn,
		method string,
		streamer grpc.Streamer,
		opts ...grpc.CallOption,
	) (grpc.ClientStream, error) {
		requestMetadata, _ := metadata.FromOutgoingContext(ctx)
		metadataCopy := requestMetadata.Copy()

		var span trace.Span
		ctx, span = tracer.Start(
			ctx, method,
			trace.WithSpanKind(trace.SpanKindClient),
			trace.WithAttributes(peerInfoFromTarget(cc.Target())...),
			trace.WithAttributes(rpcServiceKey.String(serviceFromFullMethod(method))),
		)

		Inject(ctx, &metadataCopy)
		ctx = metadata.NewOutgoingContext(ctx, metadataCopy)

		s, err := streamer(ctx, desc, cc, method, opts...)
		stream := wrapClientStream(s, desc)

		go func() {
			if err == nil {
				err = <-stream.finished
			}

			if err != nil {
				s, _ := status.FromError(err)
				span.SetStatus(s.Code(), s.Message())
			}

			span.End()
		}()

		return stream, err
	}
}

// UnaryServerInterceptor returns a grpc.UnaryServerInterceptor suitable
// for use in a grpc.NewServer call.
//
// For example:
//     tracer := global.Tracer("client-tracer")
//     s := grpc.Dial(
//         grpc.UnaryInterceptor(grpctrace.UnaryServerInterceptor(tracer)),
//         ...,  // (existing ServerOptions))
func UnaryServerInterceptor(tracer trace.Tracer) grpc.UnaryServerInterceptor {
	return func(
		ctx context.Context,
		req interface{},
		info *grpc.UnaryServerInfo,
		handler grpc.UnaryHandler,
	) (interface{}, error) {
		requestMetadata, _ := metadata.FromIncomingContext(ctx)
		metadataCopy := requestMetadata.Copy()

		entries, spanCtx := Extract(ctx, &metadataCopy)
		ctx = correlation.ContextWithMap(ctx, correlation.NewMap(correlation.MapUpdate{
			MultiKV: entries,
		}))

		ctx, span := tracer.Start(
			trace.ContextWithRemoteSpanContext(ctx, spanCtx),
			info.FullMethod,
			trace.WithSpanKind(trace.SpanKindServer),
			trace.WithAttributes(peerInfoFromContext(ctx)...),
			trace.WithAttributes(rpcServiceKey.String(serviceFromFullMethod(info.FullMethod))),
		)
		defer span.End()

		addEventForMessageReceived(ctx, 1, req)

		resp, err := handler(ctx, req)

		addEventForMessageSent(ctx, 1, resp)

		if err != nil {
			s, _ := status.FromError(err)
			span.SetStatus(s.Code(), s.Message())
		}

		return resp, err
	}
}

// clientStream wraps around the embedded grpc.ServerStream, and intercepts the RecvMsg and
// SendMsg method call.
type serverStream struct {
	grpc.ServerStream
	ctx context.Context

	receivedMessageID int
	sentMessageID     int
}

func (w *serverStream) Context() context.Context {
	return w.ctx
}

func (w *serverStream) RecvMsg(m interface{}) error {
	err := w.ServerStream.RecvMsg(m)

	if err == nil {
		w.receivedMessageID++
		addEventForMessageReceived(w.Context(), w.receivedMessageID, m)
	}

	return err
}

func (w *serverStream) SendMsg(m interface{}) error {
	err := w.ServerStream.SendMsg(m)

	w.sentMessageID++
	addEventForMessageSent(w.Context(), w.sentMessageID, m)

	return err
}

func wrapServerStream(ctx context.Context, ss grpc.ServerStream) *serverStream {
	return &serverStream{
		ServerStream: ss,
		ctx:          ctx,
	}
}

// StreamServerInterceptor returns a grpc.StreamServerInterceptor suitable
// for use in a grpc.NewServer call.
//
// For example:
//     tracer := global.Tracer("client-tracer")
//     s := grpc.Dial(
//         grpc.StreamInterceptor(grpctrace.StreamServerInterceptor(tracer)),
//         ...,  // (existing ServerOptions))
func StreamServerInterceptor(tracer trace.Tracer) grpc.StreamServerInterceptor {
	return func(
		srv interface{},
		ss grpc.ServerStream,
		info *grpc.StreamServerInfo,
		handler grpc.StreamHandler,
	) error {
		ctx := ss.Context()

		requestMetadata, _ := metadata.FromIncomingContext(ctx)
		metadataCopy := requestMetadata.Copy()

		entries, spanCtx := Extract(ctx, &metadataCopy)
		ctx = correlation.ContextWithMap(ctx, correlation.NewMap(correlation.MapUpdate{
			MultiKV: entries,
		}))

		ctx, span := tracer.Start(
			trace.ContextWithRemoteSpanContext(ctx, spanCtx),
			info.FullMethod,
			trace.WithSpanKind(trace.SpanKindServer),
			trace.WithAttributes(peerInfoFromContext(ctx)...),
			trace.WithAttributes(rpcServiceKey.String(serviceFromFullMethod(info.FullMethod))),
		)
		defer span.End()

		err := handler(srv, wrapServerStream(ctx, ss))

		if err != nil {
			s, _ := status.FromError(err)
			span.SetStatus(s.Code(), s.Message())
		}

		return err
	}
}

func peerInfoFromTarget(target string) []core.KeyValue {
	host, port, err := net.SplitHostPort(target)

	if err != nil {
		return []core.KeyValue{}
	}

	if host == "" {
		host = "127.0.0.1"
	}

	return []core.KeyValue{
		netPeerIPKey.String(host),
		netPeerPortKey.String(port),
	}
}

func peerInfoFromContext(ctx context.Context) []core.KeyValue {
	p, ok := peer.FromContext(ctx)

	if !ok {
		return []core.KeyValue{}
	}

	return peerInfoFromTarget(p.Addr.String())
}

var fullMethodRegexp = regexp.MustCompile(`^/(?:\S*\.)?(\S*)/\S*$`)

func serviceFromFullMethod(method string) string {
	match := fullMethodRegexp.FindAllStringSubmatch(method, 1)

	if len(match) != 1 && len(match[1]) != 2 {
		return ""
	}

	return match[0][1]
}

func addEventForMessageReceived(ctx context.Context, id int, m interface{}) {
	size := proto.Size(m.(proto.Message))

	span := trace.SpanFromContext(ctx)
	span.AddEvent(ctx, "message",
		messageTypeKey.String(messageTypeReceived),
		messageIDKey.Int(id),
		messageUncompressedSizeKey.Int(size),
	)
}

func addEventForMessageSent(ctx context.Context, id int, m interface{}) {
	size := proto.Size(m.(proto.Message))

	span := trace.SpanFromContext(ctx)
	span.AddEvent(ctx, "message",
		messageTypeKey.String(messageTypeSent),
		messageIDKey.Int(id),
		messageUncompressedSizeKey.Int(size),
	)
}
<|endoftext|>


<commit_before>package cc1101

import (
	"bytes"
	"log"
	"time"
)

const (
	verbose            = false
	maxPacketSize      = 110
	fifoSize           = 64
	readFifoUsingBurst = true

	// Approximate time for one byte to be transmitted, based on
	// the data rate.
	byteDuration = time.Millisecond
)

func init() {
	if verbose {
		log.SetFlags(log.Ltime | log.Lmicroseconds | log.LUTC)
	}
}

func (r *Radio) Send(data []byte) {
	if len(data) > maxPacketSize {
		log.Panicf("attempting to send %d-byte packet", len(data))
	}
	if r.Error() != nil {
		return
	}
	if verbose {
		log.Printf("sending %d-byte packet in %s state", len(data), r.State())
	}
	// Terminate packet with zero byte,
	// and pad with another to ensure final bytes
	// are transmitted before leaving TX state.
	packet := make([]byte, len(data), len(data)+2)
	copy(packet, data)
	packet = packet[:cap(packet)]
	defer r.changeState(SIDLE, STATE_IDLE)
	r.transmit(packet)
	if r.Error() == nil {
		r.stats.Packets.Sent++
		r.stats.Bytes.Sent += len(data)
	}
}

func (r *Radio) transmit(data []byte) {
	avail := fifoSize
	for r.Error() == nil {
		if avail > len(data) {
			avail = len(data)
		}
		r.hw.WriteBurst(TXFIFO, data[:avail])
		r.changeState(STX, STATE_TX)
		data = data[avail:]
		if len(data) == 0 {
			break
		}
		// Transmitting a packet that is larger than the TXFIFO size.
		// See TI Design Note DN500 (swra109c).
		// Err on the short side here to avoid TXFIFO underflow.
		time.Sleep(fifoSize / 4 * byteDuration)
		for r.Error() == nil {
			n := r.ReadNumTxBytes()
			if n < fifoSize {
				avail = fifoSize - int(n)
				if avail > len(data) {
					avail = len(data)
				}
				break
			}
		}
	}
	r.finishTx(avail)
}

func (r *Radio) finishTx(numBytes int) {
	time.Sleep(time.Duration(numBytes) * byteDuration)
	for r.Error() == nil {
		n := r.ReadNumTxBytes()
		if n == 0 || r.Error() == TxFifoUnderflow {
			break
		}
		s := r.ReadState()
		if s != STATE_TX && s != STATE_TXFIFO_UNDERFLOW {
			log.Panicf("unexpected %s state while finishing TX", StateName(s))
		}
		if verbose {
			log.Printf("waiting to transmit %d bytes in %s state", n, StateName(s))
		}
		time.Sleep(byteDuration)
	}
	if verbose {
		log.Printf("TX finished in %s state", r.State())
	}
}

func (r *Radio) Receive(timeout time.Duration) ([]byte, int) {
	if r.Error() != nil {
		return nil, 0
	}
	r.changeState(SRX, STATE_RX)
	defer r.changeState(SIDLE, STATE_IDLE)
	if verbose {
		log.Printf("waiting for interrupt in %s state", r.State())
	}
	r.hw.AwaitInterrupt(timeout)
	rssi := r.ReadRSSI()
	startedWaiting := time.Time{}
	for r.Error() == nil {
		numBytes := r.ReadNumRxBytes()
		if r.Error() == RxFifoOverflow {
			// Flush RX FIFO and change back to RX.
			r.changeState(SRX, STATE_RX)
			continue
		}
		// Don't read last byte of FIFO if packet is still
		// being received. See Section 20 of data sheet.
		if numBytes < 2 {
			if startedWaiting.IsZero() {
				startedWaiting = time.Now()
			} else if time.Since(startedWaiting) >= timeout {
				break
			}
			time.Sleep(byteDuration)
			continue
		}
		if readFifoUsingBurst {
			data := r.hw.ReadBurst(RXFIFO, int(numBytes))
			if r.Error() != nil {
				break
			}
			i := bytes.IndexByte(data, 0)
			if i == -1 {
				// No zero byte found; packet is still incoming.
				// Append all the data and continue to receive.
				_, r.err = r.receiveBuffer.Write(data)
				continue
			}
			// End of packet.
			_, r.err = r.receiveBuffer.Write(data[:i])
		} else {
			c := r.hw.ReadRegister(RXFIFO)
			if r.Error() != nil {
				break
			}
			if c != 0 {
				r.err = r.receiveBuffer.WriteByte(c)
				continue
			}
		}
		// End of packet.
		r.changeState(SIDLE, STATE_IDLE)
		r.Strobe(SFRX)
		size := r.receiveBuffer.Len()
		if size == 0 {
			break
		}
		r.stats.Packets.Received++
		r.stats.Bytes.Received += size
		p := make([]byte, size)
		_, err := r.receiveBuffer.Read(p)
		r.SetError(err)
		if r.Error() != nil {
			break
		}
		r.receiveBuffer.Reset()
		if verbose {
			log.Printf("received %d-byte packet in %s state; %d bytes remaining", size, r.State(), r.ReadNumRxBytes())
		}
		return p, rssi
	}
	return nil, rssi
}
<commit_msg>Simplify zero termination of outgoing packets<commit_after>package cc1101

import (
	"bytes"
	"log"
	"time"
)

const (
	verbose            = false
	maxPacketSize      = 110
	fifoSize           = 64
	readFifoUsingBurst = true

	// Approximate time for one byte to be transmitted, based on
	// the data rate.
	byteDuration = time.Millisecond
)

func init() {
	if verbose {
		log.SetFlags(log.Ltime | log.Lmicroseconds | log.LUTC)
	}
}

func (r *Radio) Send(data []byte) {
	if len(data) > maxPacketSize {
		log.Panicf("attempting to send %d-byte packet", len(data))
	}
	if r.Error() != nil {
		return
	}
	if verbose {
		log.Printf("sending %d-byte packet in %s state", len(data), r.State())
	}
	// Terminate packet with zero byte,
	// and pad with another to ensure final bytes
	// are transmitted before leaving TX state.
	packet := make([]byte, len(data)+2)
	copy(packet, data)
	defer r.changeState(SIDLE, STATE_IDLE)
	r.transmit(packet)
	if r.Error() == nil {
		r.stats.Packets.Sent++
		r.stats.Bytes.Sent += len(data)
	}
}

func (r *Radio) transmit(data []byte) {
	avail := fifoSize
	for r.Error() == nil {
		if avail > len(data) {
			avail = len(data)
		}
		r.hw.WriteBurst(TXFIFO, data[:avail])
		r.changeState(STX, STATE_TX)
		data = data[avail:]
		if len(data) == 0 {
			break
		}
		// Transmitting a packet that is larger than the TXFIFO size.
		// See TI Design Note DN500 (swra109c).
		// Err on the short side here to avoid TXFIFO underflow.
		time.Sleep(fifoSize / 4 * byteDuration)
		for r.Error() == nil {
			n := r.ReadNumTxBytes()
			if n < fifoSize {
				avail = fifoSize - int(n)
				if avail > len(data) {
					avail = len(data)
				}
				break
			}
		}
	}
	r.finishTx(avail)
}

func (r *Radio) finishTx(numBytes int) {
	time.Sleep(time.Duration(numBytes) * byteDuration)
	for r.Error() == nil {
		n := r.ReadNumTxBytes()
		if n == 0 || r.Error() == TxFifoUnderflow {
			break
		}
		s := r.ReadState()
		if s != STATE_TX && s != STATE_TXFIFO_UNDERFLOW {
			log.Panicf("unexpected %s state while finishing TX", StateName(s))
		}
		if verbose {
			log.Printf("waiting to transmit %d bytes in %s state", n, StateName(s))
		}
		time.Sleep(byteDuration)
	}
	if verbose {
		log.Printf("TX finished in %s state", r.State())
	}
}

func (r *Radio) Receive(timeout time.Duration) ([]byte, int) {
	if r.Error() != nil {
		return nil, 0
	}
	r.changeState(SRX, STATE_RX)
	defer r.changeState(SIDLE, STATE_IDLE)
	if verbose {
		log.Printf("waiting for interrupt in %s state", r.State())
	}
	r.hw.AwaitInterrupt(timeout)
	rssi := r.ReadRSSI()
	startedWaiting := time.Time{}
	for r.Error() == nil {
		numBytes := r.ReadNumRxBytes()
		if r.Error() == RxFifoOverflow {
			// Flush RX FIFO and change back to RX.
			r.changeState(SRX, STATE_RX)
			continue
		}
		// Don't read last byte of FIFO if packet is still
		// being received. See Section 20 of data sheet.
		if numBytes < 2 {
			if startedWaiting.IsZero() {
				startedWaiting = time.Now()
			} else if time.Since(startedWaiting) >= timeout {
				break
			}
			time.Sleep(byteDuration)
			continue
		}
		if readFifoUsingBurst {
			data := r.hw.ReadBurst(RXFIFO, int(numBytes))
			if r.Error() != nil {
				break
			}
			i := bytes.IndexByte(data, 0)
			if i == -1 {
				// No zero byte found; packet is still incoming.
				// Append all the data and continue to receive.
				_, r.err = r.receiveBuffer.Write(data)
				continue
			}
			// End of packet.
			_, r.err = r.receiveBuffer.Write(data[:i])
		} else {
			c := r.hw.ReadRegister(RXFIFO)
			if r.Error() != nil {
				break
			}
			if c != 0 {
				r.err = r.receiveBuffer.WriteByte(c)
				continue
			}
		}
		// End of packet.
		r.changeState(SIDLE, STATE_IDLE)
		r.Strobe(SFRX)
		size := r.receiveBuffer.Len()
		if size == 0 {
			break
		}
		r.stats.Packets.Received++
		r.stats.Bytes.Received += size
		p := make([]byte, size)
		_, err := r.receiveBuffer.Read(p)
		r.SetError(err)
		if r.Error() != nil {
			break
		}
		r.receiveBuffer.Reset()
		if verbose {
			log.Printf("received %d-byte packet in %s state; %d bytes remaining", size, r.State(), r.ReadNumRxBytes())
		}
		return p, rssi
	}
	return nil, rssi
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
)

func main() {
	for i := 0; i <= 100; i++ {
		if (i%3 == 0) && (i%5 == 0) {
			fmt.Println("Fizz Buzz")
		} else if i%3 == 0 {
			fmt.Println("Fizz")
		} else if i%5 == 0 {
			fmt.Println("Buzz")
		} else {
			fmt.Println(i)
		}
	}
}
<commit_msg>increase index on for loop<commit_after>package main

import (
	"fmt"
)

func main() {
	for i := 1; i <= 100; i++ {
		if (i%3 == 0) && (i%5 == 0) {
			fmt.Println("Fizz Buzz")
		} else if i%3 == 0 {
			fmt.Println("Fizz")
		} else if i%5 == 0 {
			fmt.Println("Buzz")
		} else {
			fmt.Println(i)
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>Fix gofmt<commit_after><|endoftext|>


<commit_before>package gforms

import (
	"bytes"
	"strings"
)

type selectWidget struct {
	Multiple bool
	Attrs    map[string]string
	Maker    SelectOptionsMaker
	Widget
}

type selectOptionValue struct {
	Label    string
	Value    string
	Selected bool
	Disabled bool
}

type selectOptionsValues []*selectOptionValue

type selectContext struct {
	Multiple bool
	Field    FieldInterface
	Attrs    map[string]string
	Options  selectOptionsValues
}

type SelectOptionsMaker func() SelectOptions

type SelectOptions interface {
	Label(int) string
	Value(int) string
	Selected(int) bool
	Disabled(int) bool
	Len() int
}

type StringSelectOptions [][]string

func (opt StringSelectOptions) Label(i int) string {
	return opt[i][0]
}

func (opt StringSelectOptions) Value(i int) string {
	return opt[i][1]
}

func (opt StringSelectOptions) Selected(i int) bool {
	selected := opt[i][2]
	if strings.ToLower(selected) == "true" {
		return true
	} else {
		return false
	}
}

func (opt StringSelectOptions) Disabled(i int) bool {
	disabled := opt[i][3]
	if strings.ToLower(disabled) == "true" {
		return true
	} else {
		return false
	}
}

func (cs StringSelectOptions) Len() int {
	return len(cs)
}

func (wg *selectWidget) html(f FieldInterface) string {
	var buffer bytes.Buffer
	context := new(selectContext)
	context.Field = f
	context.Multiple = wg.Multiple
	opts := wg.Maker()
	for i := 0; i < opts.Len(); i++ {
		context.Options = append(context.Options, &selectOptionValue{Label: opts.Label(i), Value: opts.Value(i), Selected: opts.Selected(i), Disabled: opts.Disabled(i)})
	}
	context.Attrs = wg.Attrs
	err := Template.ExecuteTemplate(&buffer, "SelectWidget", context)
	if err != nil {
		panic(err)
	}
	return buffer.String()
}

// Generate select and options field: <select><option></option></select>
func SelectWidget(attrs map[string]string, mk SelectOptionsMaker) *selectWidget {
	wg := new(selectWidget)
	if attrs == nil {
		attrs = map[string]string{}
	}
	if isNilValue(mk) {
		mk = func() SelectOptions {
			return StringSelectOptions([][]string{})
		}
	}
	wg.Maker = mk
	wg.Attrs = attrs
	return wg
}

// Generate select-multiple and options field: <select multiple><option></option></select>
func SelectMultipleWidget(attrs map[string]string, mk SelectOptionsMaker) *selectWidget {
	wg := SelectWidget(attrs, mk)
	wg.Multiple = true
	return wg
}
<commit_msg>support fillin for select<commit_after>package gforms

import (
	"bytes"
	"strings"
)

type selectWidget struct {
	Multiple bool
	Attrs    map[string]string
	Maker    SelectOptionsMaker
	Widget
}

type selectOptionValue struct {
	Label    string
	Value    string
	Selected bool
	Disabled bool
}

type selectOptionsValues []*selectOptionValue

type selectContext struct {
	Multiple bool
	Field    FieldInterface
	Attrs    map[string]string
	Options  selectOptionsValues
}

type SelectOptionsMaker func() SelectOptions

type SelectOptions interface {
	Label(int) string
	Value(int) string
	Selected(int) bool
	Disabled(int) bool
	Len() int
}

type StringSelectOptions [][]string

func (opt StringSelectOptions) Label(i int) string {
	return opt[i][0]
}

func (opt StringSelectOptions) Value(i int) string {
	return opt[i][1]
}

func (opt StringSelectOptions) Selected(i int) bool {
	selected := opt[i][2]
	if strings.ToLower(selected) == "true" {
		return true
	} else {
		return false
	}
}

func (opt StringSelectOptions) Disabled(i int) bool {
	disabled := opt[i][3]
	if strings.ToLower(disabled) == "true" {
		return true
	} else {
		return false
	}
}

func (cs StringSelectOptions) Len() int {
	return len(cs)
}

func (wg *selectWidget) html(f FieldInterface) string {
	var buffer bytes.Buffer
	context := new(selectContext)
	context.Field = f
	context.Multiple = wg.Multiple
	opts := wg.Maker()
	for i := 0; i < opts.Len(); i++ {
		/* support fillin  */
		selected := false
		if f.GetV().RawStr == opts.Value(i) {
			selected = true
		}
		context.Options = append(context.Options, &selectOptionValue{Label: opts.Label(i), Value: opts.Value(i), Selected: selected, Disabled: opts.Disabled(i)})
		//context.Options = append(context.Options, &selectOptionValue{Label: opts.Label(i), Value: opts.Value(i), Selected: opts.Selected(i), Disabled: opts.Disabled(i)})
	}
	context.Attrs = wg.Attrs
	err := Template.ExecuteTemplate(&buffer, "SelectWidget", context)
	if err != nil {
		panic(err)
	}
	return buffer.String()
}

// Generate select and options field: <select><option></option></select>
func SelectWidget(attrs map[string]string, mk SelectOptionsMaker) *selectWidget {
	wg := new(selectWidget)
	if attrs == nil {
		attrs = map[string]string{}
	}
	if isNilValue(mk) {
		mk = func() SelectOptions {
			return StringSelectOptions([][]string{})
		}
	}
	wg.Maker = mk
	wg.Attrs = attrs
	return wg
}

// Generate select-multiple and options field: <select multiple><option></option></select>
func SelectMultipleWidget(attrs map[string]string, mk SelectOptionsMaker) *selectWidget {
	wg := SelectWidget(attrs, mk)
	wg.Multiple = true
	return wg
}
<|endoftext|>


<commit_before>// +build linux,!cgo

package goserial

import (
	"fmt"
	"io"
	"os"
	"syscall"
	"unsafe"
)

func openPort(name string, c *Config) (rwc io.ReadWriteCloser, err error) {

	var rate uint32
	switch c.Baud {
	case 115200:
		rate = syscall.B115200
	case 57600:
		rate = syscall.B57600
	case 38400:
		rate = syscall.B38400
	case 19200:
		rate = syscall.B19200
	case 9600:
		rate = syscall.B9600
	case 4800:
		rate = syscall.B4800
	default:
		return nil, fmt.Errorf("Unknown baud rate %v", c.Baud)
	}

	var stop uint32
	switch c.StopBits {
	case StopBits1:
		stop = 0
	case StopBits2:
		stop = syscall.CSTOPB
	default:
		panic("should not happen if Config.check() was called before")
	}

	var size uint32
	switch c.Size {
	case Byte5:
		size = syscall.CS5
	case Byte6:
		size = syscall.CS6
	case Byte7:
		size = syscall.CS7
	case Byte8:
		size = syscall.CS8
	default:
		panic("should not happen if Config.check() was called before")
	}

	var parity uint32
	switch c.Parity {
	case ParityNone:
		parity = 0
	case ParityEven:
		parity = 2
	case ParityOdd:
		parity = 1
	default:
		panic("should not happen if Config.check() was called before")
	}

	f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666)
	if err != nil {
		return nil, err
	}

	defer func() {
		if err != nil && f != nil {
			f.Close()
		}
	}()

	fd := f.Fd()
	t := syscall.Termios{
		Iflag:  syscall.IGNPAR,
		Cflag:  stop | size | parity | syscall.CREAD | syscall.CLOCAL | rate,
		Cc:     [32]uint8{syscall.VMIN: 1},
		Ispeed: rate,
		Ospeed: rate,
	}

	if _, _, errno := syscall.Syscall6(
		syscall.SYS_IOCTL,
		uintptr(fd),
		uintptr(syscall.TCSETS),
		uintptr(unsafe.Pointer(&t)),
		0,
		0,
		0,
	); errno != 0 {
		return nil, errno
	}

	if err = syscall.SetNonblock(int(fd), false); err != nil {
		return
	}

	return f, nil
}
<commit_msg>cleanup in openPort<commit_after>// +build linux,!cgo

package goserial

import (
	"fmt"
	"io"
	"os"
	"syscall"
	"unsafe"
)

func openPort(name string, c *Config) (rwc io.ReadWriteCloser, err error) {

	var rate uint32
	switch c.Baud {
	case 115200:
		rate = syscall.B115200
	case 57600:
		rate = syscall.B57600
	case 38400:
		rate = syscall.B38400
	case 19200:
		rate = syscall.B19200
	case 9600:
		rate = syscall.B9600
	case 4800:
		rate = syscall.B4800
	default:
		return nil, fmt.Errorf("Unknown baud rate %v", c.Baud)
	}

	var stop uint32
	switch c.StopBits {
	case StopBits1:
		stop = 0
	case StopBits2:
		stop = syscall.CSTOPB
	default:
		panic("should not happen if Config.check() was called before")
	}

	var size uint32
	switch c.Size {
	case Byte5:
		size = syscall.CS5
	case Byte6:
		size = syscall.CS6
	case Byte7:
		size = syscall.CS7
	case Byte8:
		size = syscall.CS8
	default:
		panic("should not happen if Config.check() was called before")
	}

	var parity uint32
	switch c.Parity {
	case ParityNone:
		parity = 0
	case ParityEven:
		parity = 2
	case ParityOdd:
		parity = 1
	default:
		panic("should not happen if Config.check() was called before")
	}

	f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0600)
	if err != nil {
		return nil, err
	}

	t := syscall.Termios{
		Iflag:  syscall.IGNPAR,
		Cflag:  stop | size | parity | syscall.CREAD | syscall.CLOCAL | rate,
		Cc:     [32]uint8{syscall.VMIN: 1},
		Ispeed: rate,
		Ospeed: rate,
	}

	_, _, errno := syscall.Syscall6(
		syscall.SYS_IOCTL,
		uintptr(f.Fd()),
		uintptr(syscall.TCSETS),
		uintptr(unsafe.Pointer(&t)),
		0,
		0,
		0,
	)
	if errno != 0 {
		return nil, errno
	}

	err = syscall.SetNonblock(int(f.Fd()), false)
	if err != nil {
		return nil, err
	}

	return f, nil
}
<|endoftext|>


<commit_before>// +build linux,!cgo

package serial

import (
	"os"
	"syscall"
	"io"
	"unsafe"
)

func openPort(name string, baud int) (rwc io.ReadWriteCloser, err error) {

    var bauds = map[int]uint32{
        50:      syscall.B50,
        75:      syscall.B75,
        110:     syscall.B110,
        134:     syscall.B134,
        150:     syscall.B150,
        200:     syscall.B200,
        300:     syscall.B300,
        600:     syscall.B600,
        1200:    syscall.B1200,
        1800:    syscall.B1800,
        2400:    syscall.B2400,
        4800:    syscall.B4800,
        9600:    syscall.B9600,
        19200:   syscall.B19200,
        38400:   syscall.B38400,
        57600:   syscall.B57600,
        115200:  syscall.B115200,
        230400:  syscall.B230400,
        460800:  syscall.B460800,
        500000:  syscall.B500000,
        576000:  syscall.B576000,
        921600:  syscall.B921600,
        1000000: syscall.B1000000,
        1152000: syscall.B1152000,
        1500000: syscall.B1500000,
        2000000: syscall.B2000000,
        2500000: syscall.B2500000,
        3000000: syscall.B3000000,
        3500000: syscall.B3500000,
        4000000: syscall.B4000000,
    }

    rate := bauds[baud]

	f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666)
	if err != nil {
		return nil, err
	}

	defer func(){
		if err != nil && f != nil {
			f.Close()
		}
	}()

	fd := f.Fd()
    t := syscall.Termios{
            Iflag:  syscall.IGNPAR,
            Cflag:  syscall.CS8 | syscall.CREAD | syscall.CLOCAL | rate,
            Cc:     [32]uint8{syscall.VMIN: 1},
            Ispeed: rate,
            Ospeed: rate,
    }

    if _, _, errno := syscall.Syscall6(
            syscall.SYS_IOCTL,
            uintptr(fd),
            uintptr(syscall.TCSETS),
            uintptr(unsafe.Pointer(&t)),
            0,
            0,
            0,
    ); errno != 0 {
            return nil, errno
    }

    if err = syscall.SetNonblock(int(fd), false); err != nil {
        return
    }

	return f, nil
}<commit_msg>Adding buad value error-check<commit_after>// +build linux,!cgo

package serial

import (
	"os"
	"syscall"
	"io"
	"unsafe"
)

func openPort(name string, baud int) (rwc io.ReadWriteCloser, err error) {

    var bauds = map[int]uint32{
        50:      syscall.B50,
        75:      syscall.B75,
        110:     syscall.B110,
        134:     syscall.B134,
        150:     syscall.B150,
        200:     syscall.B200,
        300:     syscall.B300,
        600:     syscall.B600,
        1200:    syscall.B1200,
        1800:    syscall.B1800,
        2400:    syscall.B2400,
        4800:    syscall.B4800,
        9600:    syscall.B9600,
        19200:   syscall.B19200,
        38400:   syscall.B38400,
        57600:   syscall.B57600,
        115200:  syscall.B115200,
        230400:  syscall.B230400,
        460800:  syscall.B460800,
        500000:  syscall.B500000,
        576000:  syscall.B576000,
        921600:  syscall.B921600,
        1000000: syscall.B1000000,
        1152000: syscall.B1152000,
        1500000: syscall.B1500000,
        2000000: syscall.B2000000,
        2500000: syscall.B2500000,
        3000000: syscall.B3000000,
        3500000: syscall.B3500000,
        4000000: syscall.B4000000,
    }

    rate := bauds[baud]

    if rate == 0 {
        return
    }

	f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666)
	if err != nil {
		return nil, err
	}

	defer func(){
		if err != nil && f != nil {
			f.Close()
		}
	}()

	fd := f.Fd()
    t := syscall.Termios{
            Iflag:  syscall.IGNPAR,
            Cflag:  syscall.CS8 | syscall.CREAD | syscall.CLOCAL | rate,
            Cc:     [32]uint8{syscall.VMIN: 1},
            Ispeed: rate,
            Ospeed: rate,
    }

    if _, _, errno := syscall.Syscall6(
            syscall.SYS_IOCTL,
            uintptr(fd),
            uintptr(syscall.TCSETS),
            uintptr(unsafe.Pointer(&t)),
            0,
            0,
            0,
    ); errno != 0 {
            return nil, errno
    }

    if err = syscall.SetNonblock(int(fd), false); err != nil {
        return
    }

	return f, nil
}<|endoftext|>


<commit_before>// Copyright 2016 Openprovider Authors. All rights reserved.
// Use of this source code is governed by a license
// that can be found in the LICENSE file.

/*
Package rates 0.0.3
This package helps to manage exchange rates from any provider

Example 1: Get all exchange rates for the ECB Provider

    package main

    import (
        "fmt"

        "github.com/openprovider/rates"
        "github.com/openprovider/rates/providers"
    )

    func main() {
        registry := rates.Registry{
            // any collection of providers which implement rates.Provider interface
            providers.NewECBProvider(new(rates.Options)),
        }
        service := rates.New(registry)
        rates, errors := service.FetchLast()
        if len(errors) != 0 {
            fmt.Println(errors)
        }
        fmt.Println("European Central Bank exchange rates for today")
        for index, rate := range rates {
            fmt.Printf("%d. %s - %v\r\n", index+1, rate.Currency, rate.Value)
        }
    }

Example 2: Get exchange rates for EUR, USD, CHF, HKD

	package main

	import (
		"fmt"

		"github.com/openprovider/rates"
		"github.com/openprovider/rates/providers"
	)

	func main() {
		registry := rates.Registry{
			// any collection of providers which implement rates.Provider interface
			providers.NewECBProvider(
				&rates.Options{
					Currencies: []string{
						providers.EUR,
						providers.USD,
						providers.CHF,
						providers.HKD,
					},
				},
			),
		}
		service := rates.New(registry)
		rates, errors := service.FetchLast()
		if len(errors) != 0 {
			fmt.Println(errors)
		}
		fmt.Println("European Central Bank exchange rates for today")
		for index, rate := range rates {
			fmt.Printf("%d. %s - %v\r\n", index+1, rate.Currency, rate.Value)
		}
	}

Exchange Rates Provider
*/
package rates

import (
	"time"

	"golang.org/x/text/currency"
)

// Rate represent date and currency exchange rates
type Rate struct {
	ID             uint64        `json:"id,omitempty"`
	DateString     string        `json:"date"`
	Date           time.Time     `json:"-"`
	CurrencyString string        `json:"currency"`
	Currency       currency.Unit `json:"-"`
	Value          interface{}   `json:"value"`
}

// Options is some specific things for the specific provider
// It should configure the provider to manage currencies
type Options struct {
	// API key/token
	Token string
	// List of the currencies which need to get from the provider
	// If it is empty, should get all of existing currencies from the provider
	Currencies []string
}

// Provider holds methods for providers which implement this interface
type Provider interface {
	FetchLast() (rates []Rate, errors []error)
	FetchHistory() (rates []Rate, errors []error)
}

// Registry contains registered providers
type Registry []Provider

// New service which contains registered providers
func New(providers ...Provider) Provider {
	var registry Registry
	for _, provider := range providers {
		registry = append(registry, provider)
	}
	return registry
}

// FetchLast returns exchange rates from all registered providers on last day
func (registry Registry) FetchLast() (rates []Rate, errors []error) {
	for _, provider := range registry {
		r, errs := provider.FetchLast()
		rates = append(rates, r...)
		errors = append(errors, errs...)
	}
	return
}

// FetchHistory returns exchange rates from all registered providers from history
func (registry Registry) FetchHistory() (rates []Rate, errors []error) {
	for _, provider := range registry {
		r, errs := provider.FetchHistory()
		rates = append(rates, r...)
		errors = append(errors, errs...)
	}
	return
}
<commit_msg>Bumped version number to 0.0.4<commit_after>// Copyright 2016 Openprovider Authors. All rights reserved.
// Use of this source code is governed by a license
// that can be found in the LICENSE file.

/*
Package rates 0.0.4
This package helps to manage exchange rates from any provider

Example 1: Get all exchange rates for the ECB Provider

    package main

    import (
        "fmt"

        "github.com/openprovider/rates"
        "github.com/openprovider/rates/providers"
    )

    func main() {
        registry := rates.Registry{
            // any collection of providers which implement rates.Provider interface
            providers.NewECBProvider(new(rates.Options)),
        }
        service := rates.New(registry)
        rates, errors := service.FetchLast()
        if len(errors) != 0 {
            fmt.Println(errors)
        }
        fmt.Println("European Central Bank exchange rates for today")
        for index, rate := range rates {
            fmt.Printf("%d. %s - %v\r\n", index+1, rate.Currency, rate.Value)
        }
    }

Example 2: Get exchange rates for EUR, USD, CHF, HKD

	package main

	import (
		"fmt"

		"github.com/openprovider/rates"
		"github.com/openprovider/rates/providers"
	)

	func main() {
		registry := rates.Registry{
			// any collection of providers which implement rates.Provider interface
			providers.NewECBProvider(
				&rates.Options{
					Currencies: []string{
						providers.EUR,
						providers.USD,
						providers.CHF,
						providers.HKD,
					},
				},
			),
		}
		service := rates.New(registry)
		rates, errors := service.FetchLast()
		if len(errors) != 0 {
			fmt.Println(errors)
		}
		fmt.Println("European Central Bank exchange rates for today")
		for index, rate := range rates {
			fmt.Printf("%d. %s - %v\r\n", index+1, rate.Currency, rate.Value)
		}
	}

Exchange Rates Provider
*/
package rates

import (
	"time"

	"golang.org/x/text/currency"
)

// Rate represent date and currency exchange rates
type Rate struct {
	ID             uint64        `json:"id,omitempty"`
	DateString     string        `json:"date"`
	Date           time.Time     `json:"-"`
	CurrencyString string        `json:"currency"`
	Currency       currency.Unit `json:"-"`
	Value          interface{}   `json:"value"`
}

// Options is some specific things for the specific provider
// It should configure the provider to manage currencies
type Options struct {
	// API key/token
	Token string
	// List of the currencies which need to get from the provider
	// If it is empty, should get all of existing currencies from the provider
	Currencies []string
}

// Provider holds methods for providers which implement this interface
type Provider interface {
	FetchLast() (rates []Rate, errors []error)
	FetchHistory() (rates []Rate, errors []error)
}

// Registry contains registered providers
type Registry []Provider

// New service which contains registered providers
func New(providers ...Provider) Provider {
	var registry Registry
	for _, provider := range providers {
		registry = append(registry, provider)
	}
	return registry
}

// FetchLast returns exchange rates from all registered providers on last day
func (registry Registry) FetchLast() (rates []Rate, errors []error) {
	for _, provider := range registry {
		r, errs := provider.FetchLast()
		rates = append(rates, r...)
		errors = append(errors, errs...)
	}
	return
}

// FetchHistory returns exchange rates from all registered providers from history
func (registry Registry) FetchHistory() (rates []Rate, errors []error) {
	for _, provider := range registry {
		r, errs := provider.FetchHistory()
		rates = append(rates, r...)
		errors = append(errors, errs...)
	}
	return
}
<|endoftext|>


<commit_before>/*                          _       _
 *__      _____  __ ___   ___  __ _| |_ ___
 *\ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
 * \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
 *  \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
 *
 * Copyright © 2016 - 2018 Weaviate. All rights reserved.
 * LICENSE: https://github.com/creativesoftwarefdn/weaviate/blob/develop/LICENSE.md
 * AUTHOR: Bob van Luijt (bob@kub.design)
 * See www.creativesoftwarefdn.org for details
 * Contact: @CreativeSofwFdn / bob@kub.design
 */

// Package graphqlapi provides the graphql endpoint for Weaviate
package graphqlapi

import (
	"fmt"
	"strings"

	"github.com/creativesoftwarefdn/weaviate/models"
	"github.com/creativesoftwarefdn/weaviate/schema"
	"github.com/graphql-go/graphql"
)

// Build the dynamically generated Get Actions part of the schema
func genActionClassFieldsFromSchema(g *GraphQL, getActionsAndThings *map[string]*graphql.Object) (*graphql.Object, error) {
	actionClassFields := graphql.Fields{}

	for _, class := range g.databaseSchema.ActionSchema.Schema.Classes {
		singleActionClassField, singleActionClassObject := genSingleActionClassField(class, getActionsAndThings)
		actionClassFields[class.Class] = singleActionClassField
		// this line assigns the created class to a Hashmap which is used in thunks to handle cyclical relationships (Classes with other Classes as properties)
		(*getActionsAndThings)[class.Class] = singleActionClassObject
	}

	localGetActions := graphql.ObjectConfig{
		Name:        "WeaviateLocalGetActionsObj",
		Fields:      actionClassFields,
		Description: "Type of Actions i.e. Actions classes to Get on the Local Weaviate",
	}

	return graphql.NewObject(localGetActions), nil
}

func genSingleActionClassField(class *models.SemanticSchemaClass, getActionsAndThings *map[string]*graphql.Object) (*graphql.Field, *graphql.Object) {
	singleActionClassPropertyFields := graphql.ObjectConfig{
		Name: class.Class,
		Fields: (graphql.FieldsThunk)(func() graphql.Fields {
			singleActionClassPropertyFields, err := genSingleActionClassPropertyFields(class, getActionsAndThings)

			if err != nil {
				panic("Failed to generate single Action Class property fields")
			}

			return singleActionClassPropertyFields
		}),
		Description: class.Description,
	}

	singleActionClassPropertyFieldsObj := graphql.NewObject(singleActionClassPropertyFields)

	singleActionClassPropertyFieldsField := &graphql.Field{
		Type:        graphql.NewList(singleActionClassPropertyFieldsObj),
		Description: class.Description,
		Args: graphql.FieldConfigArgument{
			"first": &graphql.ArgumentConfig{
				Description: "Pagination option, show the first x results",
				Type:        graphql.Int,
			},
			"after": &graphql.ArgumentConfig{
				Description: "Pagination option, show the results after the first x results",
				Type:        graphql.Int,
			},
		},
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			result, err := dbConnector.GetGraph(p)
			return result, err
		},
	}
	return singleActionClassPropertyFieldsField, singleActionClassPropertyFieldsObj
}

func genSingleActionClassPropertyFields(class *models.SemanticSchemaClass, getActionsAndThings *map[string]*graphql.Object) (graphql.Fields, error) {
	singleActionClassPropertyFields := graphql.Fields{}

	for _, property := range class.Properties {
		propertyType, err := schema.GetPropertyDataType(class, property.Name)

		if err != nil {
			return nil, err
		}

		if *propertyType == schema.DataTypeCRef {
			capitalizedPropertyName := strings.Title(property.Name)
			numberOfDataTypes := len(property.AtDataType)
			dataTypeClasses := make([]*graphql.Object, numberOfDataTypes)

			for index, dataType := range property.AtDataType {
				thingOrActionType, ok := (*getActionsAndThings)[dataType]

				if !ok {
					return nil, fmt.Errorf("no such thing/action class '%s'", property.AtDataType[index])
				}

				dataTypeClasses[index] = thingOrActionType
			}

			dataTypeUnionConf := graphql.UnionConfig{
				Name:        fmt.Sprintf("%s%s%s", class.Class, capitalizedPropertyName, "Obj"),
				Types:       dataTypeClasses,
				Description: property.Description,
			}

			multipleClassDataTypesUnion := graphql.NewUnion(dataTypeUnionConf)

			singleActionClassPropertyFields[capitalizedPropertyName] = &graphql.Field{
				Type:        multipleClassDataTypesUnion,
				Description: property.Description,
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					result, err := dbConnector.GetGraph(p)
					return result, err
				},
			}
		} else {
			convertedDataType, err := handleGetNonObjectDataTypes(*propertyType, property)

			if err != nil {
				return nil, err
			}

			singleActionClassPropertyFields[property.Name] = convertedDataType
		}
	}

	singleActionClassPropertyFields["uuid"] = &graphql.Field{
		Description: "UUID of the thing or action given by the local Weaviate instance",
		Type:        graphql.String,
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			result, err := dbConnector.GetGraph(p)
			return result, err
		},
	}

	return singleActionClassPropertyFields, nil
}

// Build the dynamically generated Get Things part of the schema
func genThingClassFieldsFromSchema(g *GraphQL, getActionsAndThings *map[string]*graphql.Object) (*graphql.Object, error) {
	thingClassFields := graphql.Fields{}

	for _, class := range g.databaseSchema.ThingSchema.Schema.Classes {
		singleThingClassField, singleThingClassObject := genSingleThingClassField(class, getActionsAndThings)
		thingClassFields[class.Class] = singleThingClassField
		// this line assigns the created class to a Hashmap which is used in thunks to handle cyclical relationships (Classes with other Classes as properties)
		(*getActionsAndThings)[class.Class] = singleThingClassObject
	}

	localGetThings := graphql.ObjectConfig{
		Name:        "WeaviateLocalGetThingsObj",
		Fields:      thingClassFields,
		Description: "Type of Things i.e. Things classes to Get on the Local Weaviate",
	}

	return graphql.NewObject(localGetThings), nil
}

func genSingleThingClassField(class *models.SemanticSchemaClass, getActionsAndThings *map[string]*graphql.Object) (*graphql.Field, *graphql.Object) {
	singleThingClassPropertyFieldsObj := graphql.ObjectConfig{
		Name: class.Class,
		Fields: (graphql.FieldsThunk)(func() graphql.Fields {
			singleThingClassPropertyFields, err := genSingleThingClassPropertyFields(class, getActionsAndThings)
			if err != nil {
				panic(fmt.Errorf("failed to assemble single Thing Class field for Class %s", class.Class))
			}
			return singleThingClassPropertyFields
		}),
		Description: class.Description,
	}

	thingClassPropertyFieldsObject := graphql.NewObject(singleThingClassPropertyFieldsObj)
	thingClassPropertyFieldsField := &graphql.Field{
		Type:        graphql.NewList(thingClassPropertyFieldsObject),
		Description: class.Description,
		Args: graphql.FieldConfigArgument{
			"first": &graphql.ArgumentConfig{
				Description: "Pagination option, show the first x results",
				Type:        graphql.Int,
			},
			"after": &graphql.ArgumentConfig{
				Description: "Pagination option, show the results after the first x results",
				Type:        graphql.Int,
			},
		},
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			result, err := dbConnector.GetGraph(p)
			return result, err
		},
	}
	return thingClassPropertyFieldsField, thingClassPropertyFieldsObject
}

func genSingleThingClassPropertyFields(class *models.SemanticSchemaClass, getActionsAndThings *map[string]*graphql.Object) (graphql.Fields, error) {
	singleThingClassPropertyFields := graphql.Fields{}

	for _, property := range class.Properties {

		propertyType, err := schema.GetPropertyDataType(class, property.Name)

		if err != nil {
			return nil, err
		}

		if *propertyType == schema.DataTypeCRef {
			capitalizedPropertyName := strings.Title(property.Name)
			numberOfDataTypes := len(property.AtDataType)
			dataTypeClasses := make([]*graphql.Object, numberOfDataTypes)

			for index, dataType := range property.AtDataType {
				thingOrActionType, ok := (*getActionsAndThings)[dataType]

				if !ok {
					return nil, fmt.Errorf("no such thing/action class '%s'", property.AtDataType[index])
				}

				dataTypeClasses[index] = thingOrActionType
			}

			dataTypeUnionConf := graphql.UnionConfig{
				Name:  fmt.Sprintf("%s%s%s", class.Class, capitalizedPropertyName, "Obj"),
				Types: dataTypeClasses,
				ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
					return nil
				},
				Description: property.Description,
			}

			multipleClassDataTypesUnion := graphql.NewUnion(dataTypeUnionConf)

			singleThingClassPropertyFields[capitalizedPropertyName] = &graphql.Field{
				Type:        multipleClassDataTypesUnion,
				Description: property.Description,
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					result, err := dbConnector.GetGraph(p)
					return result, err
				},
			}
		} else {
			convertedDataType, err := handleGetNonObjectDataTypes(*propertyType, property)

			if err != nil {
				return nil, err
			}

			singleThingClassPropertyFields[property.Name] = convertedDataType
		}
	}

	singleThingClassPropertyFields["uuid"] = &graphql.Field{
		Description: "UUID of the thing or action given by the local Weaviate instance",
		Type:        graphql.String,
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			result, err := dbConnector.GetGraph(p)
			return result, err
		},
	}

	return singleThingClassPropertyFields, nil
}

func handleGetNonObjectDataTypes(dataType schema.DataType, property *models.SemanticSchemaClassProperty) (*graphql.Field, error) {
	switch dataType {

	case schema.DataTypeString:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.String,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				return nil, fmt.Errorf("not supported")
			},
		}, nil

	case schema.DataTypeInt:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.Int,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				result, err := dbConnector.GetGraph(p)
				return result, err
			},
		}, nil

	case schema.DataTypeNumber:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.Float,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				result, err := dbConnector.GetGraph(p)
				return result, err
			},
		}, nil

	case schema.DataTypeBoolean:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.Boolean,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				result, err := dbConnector.GetGraph(p)
				return result, err
			},
		}, nil

	case schema.DataTypeDate:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.String, // String since no graphql date datatype exists
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				result, err := dbConnector.GetGraph(p)
				return result, err
			},
		}, nil

	default:
		return nil, fmt.Errorf(schema.ErrorNoSuchDatatype)
	}
}
<commit_msg>gh-488 re-add ResolveType function for dataTypeUnionConf<commit_after>/*                          _       _
 *__      _____  __ ___   ___  __ _| |_ ___
 *\ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
 * \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
 *  \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
 *
 * Copyright © 2016 - 2018 Weaviate. All rights reserved.
 * LICENSE: https://github.com/creativesoftwarefdn/weaviate/blob/develop/LICENSE.md
 * AUTHOR: Bob van Luijt (bob@kub.design)
 * See www.creativesoftwarefdn.org for details
 * Contact: @CreativeSofwFdn / bob@kub.design
 */

// Package graphqlapi provides the graphql endpoint for Weaviate
package graphqlapi

import (
	"fmt"
	"strings"

	"github.com/creativesoftwarefdn/weaviate/models"
	"github.com/creativesoftwarefdn/weaviate/schema"
	"github.com/graphql-go/graphql"
)

// Build the dynamically generated Get Actions part of the schema
func genActionClassFieldsFromSchema(g *GraphQL, getActionsAndThings *map[string]*graphql.Object) (*graphql.Object, error) {
	actionClassFields := graphql.Fields{}

	for _, class := range g.databaseSchema.ActionSchema.Schema.Classes {
		singleActionClassField, singleActionClassObject := genSingleActionClassField(class, getActionsAndThings)
		actionClassFields[class.Class] = singleActionClassField
		// this line assigns the created class to a Hashmap which is used in thunks to handle cyclical relationships (Classes with other Classes as properties)
		(*getActionsAndThings)[class.Class] = singleActionClassObject
	}

	localGetActions := graphql.ObjectConfig{
		Name:        "WeaviateLocalGetActionsObj",
		Fields:      actionClassFields,
		Description: "Type of Actions i.e. Actions classes to Get on the Local Weaviate",
	}

	return graphql.NewObject(localGetActions), nil
}

func genSingleActionClassField(class *models.SemanticSchemaClass, getActionsAndThings *map[string]*graphql.Object) (*graphql.Field, *graphql.Object) {
	singleActionClassPropertyFields := graphql.ObjectConfig{
		Name: class.Class,
		Fields: (graphql.FieldsThunk)(func() graphql.Fields {
			singleActionClassPropertyFields, err := genSingleActionClassPropertyFields(class, getActionsAndThings)

			if err != nil {
				panic("Failed to generate single Action Class property fields")
			}

			return singleActionClassPropertyFields
		}),
		Description: class.Description,
	}

	singleActionClassPropertyFieldsObj := graphql.NewObject(singleActionClassPropertyFields)

	singleActionClassPropertyFieldsField := &graphql.Field{
		Type:        graphql.NewList(singleActionClassPropertyFieldsObj),
		Description: class.Description,
		Args: graphql.FieldConfigArgument{
			"first": &graphql.ArgumentConfig{
				Description: "Pagination option, show the first x results",
				Type:        graphql.Int,
			},
			"after": &graphql.ArgumentConfig{
				Description: "Pagination option, show the results after the first x results",
				Type:        graphql.Int,
			},
		},
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			result, err := dbConnector.GetGraph(p)
			return result, err
		},
	}
	return singleActionClassPropertyFieldsField, singleActionClassPropertyFieldsObj
}

func genSingleActionClassPropertyFields(class *models.SemanticSchemaClass, getActionsAndThings *map[string]*graphql.Object) (graphql.Fields, error) {
	singleActionClassPropertyFields := graphql.Fields{}

	for _, property := range class.Properties {
		propertyType, err := schema.GetPropertyDataType(class, property.Name)

		if err != nil {
			return nil, err
		}

		if *propertyType == schema.DataTypeCRef {
			capitalizedPropertyName := strings.Title(property.Name)
			numberOfDataTypes := len(property.AtDataType)
			dataTypeClasses := make([]*graphql.Object, numberOfDataTypes)

			for index, dataType := range property.AtDataType {
				thingOrActionType, ok := (*getActionsAndThings)[dataType]

				if !ok {
					return nil, fmt.Errorf("no such thing/action class '%s'", property.AtDataType[index])
				}

				dataTypeClasses[index] = thingOrActionType
			}

			dataTypeUnionConf := graphql.UnionConfig{
				Name:  fmt.Sprintf("%s%s%s", class.Class, capitalizedPropertyName, "Obj"),
				Types: dataTypeClasses,
				ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
					return nil
				},
				Description: property.Description,
			}

			multipleClassDataTypesUnion := graphql.NewUnion(dataTypeUnionConf)

			singleActionClassPropertyFields[capitalizedPropertyName] = &graphql.Field{
				Type:        multipleClassDataTypesUnion,
				Description: property.Description,
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					result, err := dbConnector.GetGraph(p)
					return result, err
				},
			}
		} else {
			convertedDataType, err := handleGetNonObjectDataTypes(*propertyType, property)

			if err != nil {
				return nil, err
			}

			singleActionClassPropertyFields[property.Name] = convertedDataType
		}
	}

	singleActionClassPropertyFields["uuid"] = &graphql.Field{
		Description: "UUID of the thing or action given by the local Weaviate instance",
		Type:        graphql.String,
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			result, err := dbConnector.GetGraph(p)
			return result, err
		},
	}

	return singleActionClassPropertyFields, nil
}

// Build the dynamically generated Get Things part of the schema
func genThingClassFieldsFromSchema(g *GraphQL, getActionsAndThings *map[string]*graphql.Object) (*graphql.Object, error) {
	thingClassFields := graphql.Fields{}

	for _, class := range g.databaseSchema.ThingSchema.Schema.Classes {
		singleThingClassField, singleThingClassObject := genSingleThingClassField(class, getActionsAndThings)
		thingClassFields[class.Class] = singleThingClassField
		// this line assigns the created class to a Hashmap which is used in thunks to handle cyclical relationships (Classes with other Classes as properties)
		(*getActionsAndThings)[class.Class] = singleThingClassObject
	}

	localGetThings := graphql.ObjectConfig{
		Name:        "WeaviateLocalGetThingsObj",
		Fields:      thingClassFields,
		Description: "Type of Things i.e. Things classes to Get on the Local Weaviate",
	}

	return graphql.NewObject(localGetThings), nil
}

func genSingleThingClassField(class *models.SemanticSchemaClass, getActionsAndThings *map[string]*graphql.Object) (*graphql.Field, *graphql.Object) {
	singleThingClassPropertyFieldsObj := graphql.ObjectConfig{
		Name: class.Class,
		Fields: (graphql.FieldsThunk)(func() graphql.Fields {
			singleThingClassPropertyFields, err := genSingleThingClassPropertyFields(class, getActionsAndThings)
			if err != nil {
				panic(fmt.Errorf("failed to assemble single Thing Class field for Class %s", class.Class))
			}
			return singleThingClassPropertyFields
		}),
		Description: class.Description,
	}

	thingClassPropertyFieldsObject := graphql.NewObject(singleThingClassPropertyFieldsObj)
	thingClassPropertyFieldsField := &graphql.Field{
		Type:        graphql.NewList(thingClassPropertyFieldsObject),
		Description: class.Description,
		Args: graphql.FieldConfigArgument{
			"first": &graphql.ArgumentConfig{
				Description: "Pagination option, show the first x results",
				Type:        graphql.Int,
			},
			"after": &graphql.ArgumentConfig{
				Description: "Pagination option, show the results after the first x results",
				Type:        graphql.Int,
			},
		},
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			result, err := dbConnector.GetGraph(p)
			return result, err
		},
	}
	return thingClassPropertyFieldsField, thingClassPropertyFieldsObject
}

func genSingleThingClassPropertyFields(class *models.SemanticSchemaClass, getActionsAndThings *map[string]*graphql.Object) (graphql.Fields, error) {
	singleThingClassPropertyFields := graphql.Fields{}

	for _, property := range class.Properties {

		propertyType, err := schema.GetPropertyDataType(class, property.Name)

		if err != nil {
			return nil, err
		}

		if *propertyType == schema.DataTypeCRef {
			capitalizedPropertyName := strings.Title(property.Name)
			numberOfDataTypes := len(property.AtDataType)
			dataTypeClasses := make([]*graphql.Object, numberOfDataTypes)

			for index, dataType := range property.AtDataType {
				thingOrActionType, ok := (*getActionsAndThings)[dataType]

				if !ok {
					return nil, fmt.Errorf("no such thing/action class '%s'", property.AtDataType[index])
				}

				dataTypeClasses[index] = thingOrActionType
			}

			dataTypeUnionConf := graphql.UnionConfig{
				Name:  fmt.Sprintf("%s%s%s", class.Class, capitalizedPropertyName, "Obj"),
				Types: dataTypeClasses,
				ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
					return nil
				},
				Description: property.Description,
			}

			multipleClassDataTypesUnion := graphql.NewUnion(dataTypeUnionConf)

			singleThingClassPropertyFields[capitalizedPropertyName] = &graphql.Field{
				Type:        multipleClassDataTypesUnion,
				Description: property.Description,
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					result, err := dbConnector.GetGraph(p)
					return result, err
				},
			}
		} else {
			convertedDataType, err := handleGetNonObjectDataTypes(*propertyType, property)

			if err != nil {
				return nil, err
			}

			singleThingClassPropertyFields[property.Name] = convertedDataType
		}
	}

	singleThingClassPropertyFields["uuid"] = &graphql.Field{
		Description: "UUID of the thing or action given by the local Weaviate instance",
		Type:        graphql.String,
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			result, err := dbConnector.GetGraph(p)
			return result, err
		},
	}

	return singleThingClassPropertyFields, nil
}

func handleGetNonObjectDataTypes(dataType schema.DataType, property *models.SemanticSchemaClassProperty) (*graphql.Field, error) {
	switch dataType {

	case schema.DataTypeString:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.String,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				return nil, fmt.Errorf("not supported")
			},
		}, nil

	case schema.DataTypeInt:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.Int,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				result, err := dbConnector.GetGraph(p)
				return result, err
			},
		}, nil

	case schema.DataTypeNumber:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.Float,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				result, err := dbConnector.GetGraph(p)
				return result, err
			},
		}, nil

	case schema.DataTypeBoolean:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.Boolean,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				result, err := dbConnector.GetGraph(p)
				return result, err
			},
		}, nil

	case schema.DataTypeDate:
		return &graphql.Field{
			Description: property.Description,
			Type:        graphql.String, // String since no graphql date datatype exists
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				result, err := dbConnector.GetGraph(p)
				return result, err
			},
		}, nil

	default:
		return nil, fmt.Errorf(schema.ErrorNoSuchDatatype)
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2020 Shivaram Lingamneni
// Released under the MIT license

package irc

import "fmt"

const (
	// SemVer is the semantic version of Oragono.
	SemVer = "2.1.0"
)

var (
	// Ver is the full version of Oragono, used in responses to clients.
	Ver = fmt.Sprintf("oragono-%s", SemVer)
	// Commit is the full git hash, if available
	Commit string
)

// initialize version strings (these are set in package main via linker flags)
func SetVersionString(version, commit string) {
	Commit = commit
	if version != "" {
		Ver = fmt.Sprintf("oragono-%s", version)
	} else if len(Commit) == 40 {
		Ver = fmt.Sprintf("oragono-%s-%s", SemVer, Commit[:16])
	}
}
<commit_msg>bump to next development version<commit_after>// Copyright (c) 2020 Shivaram Lingamneni
// Released under the MIT license

package irc

import "fmt"

const (
	// SemVer is the semantic version of Oragono.
	SemVer = "2.2.0-unreleased"
)

var (
	// Ver is the full version of Oragono, used in responses to clients.
	Ver = fmt.Sprintf("oragono-%s", SemVer)
	// Commit is the full git hash, if available
	Commit string
)

// initialize version strings (these are set in package main via linker flags)
func SetVersionString(version, commit string) {
	Commit = commit
	if version != "" {
		Ver = fmt.Sprintf("oragono-%s", version)
	} else if len(Commit) == 40 {
		Ver = fmt.Sprintf("oragono-%s-%s", SemVer, Commit[:16])
	}
}
<|endoftext|>


<commit_before>// (c) Rick Arnold. Licensed under the BSD license (see LICENSE).

// Package us provides holiday definitions for the United States of America.
package us

import (
	"time"

	"github.com/rickar/cal/v2"
	"github.com/rickar/cal/v2/aa"
)

var (
	// Standard US weekend substitution rules:
	//   Saturdays move to Friday
	//   Sundays move to Monday
	weekendAlt = []cal.AltDay{
		{Day: time.Saturday, Offset: -1},
		{Day: time.Sunday, Offset: 1},
	}

	// NewYear represents New Year's Day on 1-Jan
	NewYear = aa.NewYear.Clone(&cal.Holiday{Name: "New Year's Day", Type: cal.ObservancePublic, Observed: weekendAlt})

	// MlkDay represents Martin Luther King Jr. Day on the 3rd Monday in January
	MlkDay = &cal.Holiday{
		Name:    "Martin Luther King Jr. Day",
		Type:    cal.ObservancePublic,
		Month:   time.January,
		Weekday: time.Monday,
		Offset:  3,
		Func:    cal.CalcWeekdayOffset,
	}

	// PresidentsDay represents Presidents' Day on the 3rd Monday in February
	PresidentsDay = &cal.Holiday{
		Name:    "Presidents' Day",
		Type:    cal.ObservancePublic,
		Month:   time.February,
		Weekday: time.Monday,
		Offset:  3,
		Func:    cal.CalcWeekdayOffset,
	}

	// MemorialDay represents Memorial Day on the last Monday in May
	MemorialDay = &cal.Holiday{
		Name:    "Memorial Day",
		Type:    cal.ObservancePublic,
		Month:   time.May,
		Weekday: time.Monday,
		Offset:  -1,
		Func:    cal.CalcWeekdayOffset,
	}

	// Juneteenth represents Juneteenth on June 19th
	Juneteenth = &cal.Holiday{
		Name:      "Juneteenth",
		Type:      cal.ObservancePublic,
		Month:     time.June,
		Day:       19,
		Observed:  weekendAlt,
		Func:      cal.CalcDayOfMonth,
		StartYear: 2021,
	}

	// IndependenceDay represents Independence Day on 4-Jul
	IndependenceDay = &cal.Holiday{
		Name:     "Independence Day",
		Type:     cal.ObservancePublic,
		Month:    time.July,
		Day:      4,
		Observed: weekendAlt,
		Func:     cal.CalcDayOfMonth,
	}

	// LaborDay represents Labor Day on the first Monday in September
	LaborDay = &cal.Holiday{
		Name:    "Labor Day",
		Type:    cal.ObservancePublic,
		Month:   time.September,
		Weekday: time.Monday,
		Offset:  1,
		Func:    cal.CalcWeekdayOffset,
	}

	// ColumbusDay represents Columbus Day on the second Monday in October
	ColumbusDay = &cal.Holiday{
		Name:    "Columbus Day",
		Type:    cal.ObservancePublic,
		Month:   time.October,
		Weekday: time.Monday,
		Offset:  2,
		Func:    cal.CalcWeekdayOffset,
	}

	// VeteransDay represents Veterans Day on 11-Nov
	VeteransDay = &cal.Holiday{
		Name:     "Veterans Day",
		Type:     cal.ObservancePublic,
		Month:    time.November,
		Day:      11,
		Observed: weekendAlt,
		Func:     cal.CalcDayOfMonth,
	}

	// ThanksgivingDay represents Thanksgiving Day on the fourth Thursday in November
	ThanksgivingDay = &cal.Holiday{
		Name:    "Thanksgiving Day",
		Type:    cal.ObservancePublic,
		Month:   time.November,
		Weekday: time.Thursday,
		Offset:  4,
		Func:    cal.CalcWeekdayOffset,
	}

	// DayAfterThanksgivingDay represents the day after Thanksgiving Day on the fourth Friday in November
	DayAfterThanksgivingDay = &cal.Holiday{
		Name:       "Day After Thanksgiving Day",
		Type:       cal.ObservancePublic,
		Month:      time.November,
		Weekday:    time.Thursday,
		Offset:     4,
		CalcOffset: 1,
		Func:       cal.CalcWeekdayOffset,
	}

	// ChristmasDay represents Christmas Day on the 25-Dec
	ChristmasDay = aa.ChristmasDay.Clone(&cal.Holiday{Name: "Christmas Day", Type: cal.ObservancePublic, Observed: weekendAlt})

	// Holidays provides a list of the standard national holidays
	Holidays = []*cal.Holiday{
		NewYear,
		MlkDay,
		PresidentsDay,
		MemorialDay,
		IndependenceDay,
		LaborDay,
		ColumbusDay,
		VeteransDay,
		ThanksgivingDay,
		ChristmasDay,
	}
)
<commit_msg>Add Juneteenth to us.Holidays list<commit_after>// (c) Rick Arnold. Licensed under the BSD license (see LICENSE).

// Package us provides holiday definitions for the United States of America.
package us

import (
	"time"

	"github.com/rickar/cal/v2"
	"github.com/rickar/cal/v2/aa"
)

var (
	// Standard US weekend substitution rules:
	//   Saturdays move to Friday
	//   Sundays move to Monday
	weekendAlt = []cal.AltDay{
		{Day: time.Saturday, Offset: -1},
		{Day: time.Sunday, Offset: 1},
	}

	// NewYear represents New Year's Day on 1-Jan
	NewYear = aa.NewYear.Clone(&cal.Holiday{Name: "New Year's Day", Type: cal.ObservancePublic, Observed: weekendAlt})

	// MlkDay represents Martin Luther King Jr. Day on the 3rd Monday in January
	MlkDay = &cal.Holiday{
		Name:    "Martin Luther King Jr. Day",
		Type:    cal.ObservancePublic,
		Month:   time.January,
		Weekday: time.Monday,
		Offset:  3,
		Func:    cal.CalcWeekdayOffset,
	}

	// PresidentsDay represents Presidents' Day on the 3rd Monday in February
	PresidentsDay = &cal.Holiday{
		Name:    "Presidents' Day",
		Type:    cal.ObservancePublic,
		Month:   time.February,
		Weekday: time.Monday,
		Offset:  3,
		Func:    cal.CalcWeekdayOffset,
	}

	// MemorialDay represents Memorial Day on the last Monday in May
	MemorialDay = &cal.Holiday{
		Name:    "Memorial Day",
		Type:    cal.ObservancePublic,
		Month:   time.May,
		Weekday: time.Monday,
		Offset:  -1,
		Func:    cal.CalcWeekdayOffset,
	}

	// Juneteenth represents Juneteenth on June 19th
	Juneteenth = &cal.Holiday{
		Name:      "Juneteenth",
		Type:      cal.ObservancePublic,
		Month:     time.June,
		Day:       19,
		Observed:  weekendAlt,
		Func:      cal.CalcDayOfMonth,
		StartYear: 2021,
	}

	// IndependenceDay represents Independence Day on 4-Jul
	IndependenceDay = &cal.Holiday{
		Name:     "Independence Day",
		Type:     cal.ObservancePublic,
		Month:    time.July,
		Day:      4,
		Observed: weekendAlt,
		Func:     cal.CalcDayOfMonth,
	}

	// LaborDay represents Labor Day on the first Monday in September
	LaborDay = &cal.Holiday{
		Name:    "Labor Day",
		Type:    cal.ObservancePublic,
		Month:   time.September,
		Weekday: time.Monday,
		Offset:  1,
		Func:    cal.CalcWeekdayOffset,
	}

	// ColumbusDay represents Columbus Day on the second Monday in October
	ColumbusDay = &cal.Holiday{
		Name:    "Columbus Day",
		Type:    cal.ObservancePublic,
		Month:   time.October,
		Weekday: time.Monday,
		Offset:  2,
		Func:    cal.CalcWeekdayOffset,
	}

	// VeteransDay represents Veterans Day on 11-Nov
	VeteransDay = &cal.Holiday{
		Name:     "Veterans Day",
		Type:     cal.ObservancePublic,
		Month:    time.November,
		Day:      11,
		Observed: weekendAlt,
		Func:     cal.CalcDayOfMonth,
	}

	// ThanksgivingDay represents Thanksgiving Day on the fourth Thursday in November
	ThanksgivingDay = &cal.Holiday{
		Name:    "Thanksgiving Day",
		Type:    cal.ObservancePublic,
		Month:   time.November,
		Weekday: time.Thursday,
		Offset:  4,
		Func:    cal.CalcWeekdayOffset,
	}

	// DayAfterThanksgivingDay represents the day after Thanksgiving Day on the fourth Friday in November
	DayAfterThanksgivingDay = &cal.Holiday{
		Name:       "Day After Thanksgiving Day",
		Type:       cal.ObservancePublic,
		Month:      time.November,
		Weekday:    time.Thursday,
		Offset:     4,
		CalcOffset: 1,
		Func:       cal.CalcWeekdayOffset,
	}

	// ChristmasDay represents Christmas Day on the 25-Dec
	ChristmasDay = aa.ChristmasDay.Clone(&cal.Holiday{Name: "Christmas Day", Type: cal.ObservancePublic, Observed: weekendAlt})

	// Holidays provides a list of the standard national holidays
	Holidays = []*cal.Holiday{
		NewYear,
		MlkDay,
		PresidentsDay,
		MemorialDay,
		Juneteenth,
		IndependenceDay,
		LaborDay,
		ColumbusDay,
		VeteransDay,
		ThanksgivingDay,
		ChristmasDay,
	}
)
<|endoftext|>