<commit_before>package ext_test

import (
	"reflect"
	"testing"

	opentracing "github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
)

func assertEqual(t *testing.T, expected, actual interface{}) {
	if !reflect.DeepEqual(expected, actual) {
		t.Fatalf("Not equal: %#v (expected)\n"+
			"        != %#v (actual)", expected, actual)
	}
}

func TestPeerTags(t *testing.T) {
	if ext.PeerService != "peer.service" {
		t.Fatalf("Invalid PeerService %v", ext.PeerService)
	}
	tracer := noopTracer{}
	span := tracer.StartSpan("my-trace")
	ext.PeerService.Add(span, "my-service")
	ext.PeerHostname.Add(span, "my-hostname")
	ext.PeerHostIPv4.Add(span, uint32(127<<24|1))
	ext.PeerHostIPv6.Add(span, "::")
	ext.PeerPort.Add(span, uint16(8080))
	span.Finish()

	rawSpan := span.(*noopSpan)
	assertEqual(t, "my-service", rawSpan.Tags[string(ext.PeerService)])
	assertEqual(t, "my-hostname", rawSpan.Tags[string(ext.PeerHostname)])
	assertEqual(t, uint32(127<<24|1), rawSpan.Tags[string(ext.PeerHostIPv4)])
	assertEqual(t, "::", rawSpan.Tags[string(ext.PeerHostIPv6)])
	assertEqual(t, uint16(8080), rawSpan.Tags[string(ext.PeerPort)])
}

// noopTracer and noopSpan with span tags implemented
type noopTracer struct{}

type noopSpan struct {
	Tags opentracing.Tags
}

type noopInjectorExtractor struct{}

func (n noopSpan) SetTag(key string, value interface{}) opentracing.Span {
	n.Tags[key] = value
	return n
}

func (n noopSpan) Finish()                                                {}
func (n noopSpan) FinishWithOptions(opts opentracing.FinishOptions)       {}
func (n noopSpan) SetTraceAttribute(key, val string) opentracing.Span     { return n }
func (n noopSpan) TraceAttribute(key string) string                       { return "" }
func (n noopSpan) LogEvent(event string)                                  {}
func (n noopSpan) LogEventWithPayload(event string, payload interface{})  {}
func (n noopSpan) Log(data opentracing.LogData)                           {}
func (n noopSpan) SetOperationName(operationName string) opentracing.Span { return n }
func (n noopSpan) Tracer() opentracing.Tracer                             { return nil }

func (n noopTracer) StartSpan(operationName string) opentracing.Span {
	return &noopSpan{Tags: make(opentracing.Tags)}
}

func (n noopTracer) StartSpanWithOptions(opts opentracing.StartSpanOptions) opentracing.Span {
	return noopSpan{Tags: make(opentracing.Tags)}
}

func (n noopTracer) Extractor(format interface{}) opentracing.Extractor {
	return noopInjectorExtractor{}
}

func (n noopTracer) Injector(format interface{}) opentracing.Injector {
	return noopInjectorExtractor{}
}

func (n noopInjectorExtractor) InjectSpan(span opentracing.Span, carrier interface{}) error {
	return nil
}

func (n noopInjectorExtractor) JoinTrace(operationName string, carrier interface{}) (opentracing.Span, error) {
	return nil, nil
}
<commit_msg>review responses<commit_after>package ext_test

import (
	"reflect"
	"testing"

	opentracing "github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
)

func assertEqual(t *testing.T, expected, actual interface{}) {
	if !reflect.DeepEqual(expected, actual) {
		t.Fatalf("Not equal: %#v (expected)\n"+
			"        != %#v (actual)", expected, actual)
	}
}

func TestPeerTags(t *testing.T) {
	if ext.PeerService != "peer.service" {
		t.Fatalf("Invalid PeerService %v", ext.PeerService)
	}
	tracer := noopTracer{}
	span := tracer.StartSpan("my-trace")
	ext.PeerService.Add(span, "my-service")
	ext.PeerHostname.Add(span, "my-hostname")
	ext.PeerHostIPv4.Add(span, uint32(127<<24|1))
	ext.PeerHostIPv6.Add(span, "::")
	ext.PeerPort.Add(span, uint16(8080))
	span.Finish()

	rawSpan := span.(*noopSpan)
	assertEqual(t, "my-service", rawSpan.Tags[string(ext.PeerService)])
	assertEqual(t, "my-hostname", rawSpan.Tags[string(ext.PeerHostname)])
	assertEqual(t, uint32(127<<24|1), rawSpan.Tags[string(ext.PeerHostIPv4)])
	assertEqual(t, "::", rawSpan.Tags[string(ext.PeerHostIPv6)])
	assertEqual(t, uint16(8080), rawSpan.Tags[string(ext.PeerPort)])
}

// noopTracer and noopSpan with span tags implemented
type noopTracer struct{}

type noopSpan struct {
	Tags opentracing.Tags
}

type noopInjectorExtractor struct{}

func (n noopSpan) SetTag(key string, value interface{}) opentracing.Span {
	n.Tags[key] = value
	return n
}

func (n noopSpan) Finish()                                                {}
func (n noopSpan) FinishWithOptions(opts opentracing.FinishOptions)       {}
func (n noopSpan) SetTraceAttribute(key, val string) opentracing.Span     { return n }
func (n noopSpan) TraceAttribute(key string) string                       { return "" }
func (n noopSpan) LogEvent(event string)                                  {}
func (n noopSpan) LogEventWithPayload(event string, payload interface{})  {}
func (n noopSpan) Log(data opentracing.LogData)                           {}
func (n noopSpan) SetOperationName(operationName string) opentracing.Span { return n }
func (n noopSpan) Tracer() opentracing.Tracer                             { return nil }

func (n noopTracer) StartSpan(operationName string) opentracing.Span {
	return &noopSpan{Tags: make(opentracing.Tags)}
}

func (n noopTracer) StartSpanWithOptions(opts opentracing.StartSpanOptions) opentracing.Span {
	return noopSpan{Tags: make(opentracing.Tags)}
}

func (n noopTracer) Extractor(format interface{}) opentracing.Extractor {
	return noopInjectorExtractor{}
}

func (n noopTracer) Injector(format interface{}) opentracing.Injector {
	return noopInjectorExtractor{}
}

func (n noopInjectorExtractor) InjectSpan(span opentracing.Span, carrier interface{}) error {
	return nil
}

func (n noopInjectorExtractor) JoinTrace(operationName string, carrier interface{}) (opentracing.Span, error) {
	panic("not implemented")
}
<|endoftext|>


<commit_before>package main // for feqbbb.go

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
	"runtime"
	"time"
)

/*
  REVISION HISTORY
  ----------------
   6 Apr 13 -- M2:  First modified version of module.  I will use VLI to compare all digits of the hashes.
  23 Apr 13 -- Fixed problem of a single line in the hashes file, that does not contain an EOL character, causes
                an immediate return without processing of the characters just read in.
  24 Apr 13 -- Added output of which file either matches or does not match.
  19 Sep 16 -- Finished conversion to Go, that was started 13 Sep 16.  Added the removal of '*' which is part of a std linux formatted hash file.  And I forgot that
                 the routine allowed either order in the file.  If the token has a '.' I assume it is a filename, else it is a hash value.
  21 Sep 16 -- Fixed the case issue in tokenize.GetToken.  Edited code here to correspond to this fix.
  25 Nov 16 -- Need to not panic when target file is not found, only panic when hash file is not found.
                 And added a LastCompiled message and string.
  13 Oct 17 -- No changes here, but tokenize was changed so that horizontal tab char is now a delim.
  14 Oct 17 -- Tweaked output a bit.  And added executable timestamp code.
  19 Oct 17 -- Added ability to ignore the * that standard hash files for linux use.
  22 Oct 17 -- Added filepicker.
  21 Jan 18 -- Really ignore *.  Before method did not work.
  26 Jan 18 -- Changed tokenize so that SetMapDelim change sticks and actually works.
  13 Nov 18 -- Will use "-" and "_" also to detect a filename token.
  10 Nov 19 -- Now uses ToLower to compare the string hashes, to ignore case.
  15 Jul 20 -- Decided to make better guesses.  Sha1 has 40 digits, Sha256 has 64 digits and Sha512 has 128 digits.
  27 Sep 20 -- From help file of TakeCommand: MD-5 has 32 digits, SHA384 has 96 digits, and the above hash lengths are correct.
                 And I'm going to change from tokenize to tknptr.  Just to see if it works.
  25 Feb 21 -- Added 999 as a stop code.
   3 Mar 21 -- Now called sha.go, which will always use hash length, while ignoring file extension.
                 Errors now go to Stderr.  Uses bytes buffer to read sha file using os.ReadAll, using go 1.16.
   7 Mar 21 -- Added use of strings.TrimSpace()
   8 Apr 21 -- Converting to module version of ~/go/src.
  24 Jan 22 -- Adding a help message using the flag package.  And since I recently changed the interface for filepicker, I have to fix that here too.
   9 Mar 22 -- Using package constants instead of my magic numbers.
                  Now called feq for File Equal, that is, it will determine if 2 files are equal by computing a bunch of hashes.
                  And as this can apply to non-text files as well as text, I won't assume an extension.  Binaries on linux don't have one, anyway.
                  Turns out that crc is much more complex than I expected.  I tried each method just to see if I could get it to work.  But only once.
  12 Mar 22 -- Adding timing info.  For a 3.5 GB file, the results on leox are:
                  Castognoli 2.4s, IEEE 3.6s, byte-by-byte 4.7s, crc64 ECMA 11.5s, sha1 20.3s, md5 28.2s, sha512 35.7s, Koopman 46.8s, sha256 52.8s.
               Now called feqlarge.go, intended for files that are quite large.  I will only open one file at a time, calculate some of the hashes, and
                  compare them afterwards.  When I tested feq.go on a large file (22GB, IIRC), the OS shut it down.
                  I'll only use Castognoli, crc64 ECMA and sha512.  I can't do byte-by-byte because this is intended for very large files that can't both be in memory.
                  I forgot that some of the above timings include 2 methods of computation, checksum and sum32.
               Now called feq64.go, and will only compute crc64 ECMA checksum, in a way that only opens 1 file at a time.  And it doesn't need a bytes.Reader.
  21 May 22 -- Since I want to be able to process huge files > 3 GB, I can't read in the entire file at once.  I'll switch to a file reader algorithm.
                  Now called feq32, to play w/ the crc32 functions.  Since I intend this for huge files (> 3 GB), I'll use a flag to determine which crc32 to use.
  24 May 22 -- Now called feqbbb, for byte by byte.  I'll read in chunks and compare them, so very large files can be handled, too.
*/

const LastCompiled = "25 May 2022"
const K = 1024
const M = K * K

//* ************************* MAIN ***************************************************************
func main() {

	var filename1, filename2 string

	workingDir, _ := os.Getwd()
	execName, _ := os.Executable()
	ExecFI, _ := os.Stat(execName)
	LastLinkedTimeStamp := ExecFI.ModTime().Format("Mon Jan 2 2006 15:04:05 MST")

	// flag help message
	flag.Usage = func() {
		fmt.Fprintf(flag.CommandLine.Output(), " file equal byte by byte tester, last modified %s, compiled with %s.\n", LastCompiled, runtime.Version())
		fmt.Fprintf(flag.CommandLine.Output(), " Filenames to compare are given on the command line.\n")
		fmt.Fprintf(flag.CommandLine.Output(), " %s has timestamp of %s.  Working directory is %s.  Full name of executable is %s.\n",
			ExecFI.Name(), LastLinkedTimeStamp, workingDir, execName)
		fmt.Fprintln(flag.CommandLine.Output())
		flag.PrintDefaults()
	}
	var verboseFlag bool
	flag.BoolVar(&verboseFlag, "v", false, " verbose mode.")
	flag.Parse()

	if verboseFlag {
		fmt.Printf("\n feqbbb File equal using byte by byte comparisons of chunks, last modified %s, compiled by %s\n\n", LastCompiled, runtime.Version())
	}

	if flag.NArg() == 0 {
		fmt.Printf("\n Need two files on the command line to determine if they're equal.  Exiting. \n\n")
		os.Exit(1)
	} else if flag.NArg() >= 2 { // will use first 2 filenames entered on commandline
		filename1 = flag.Arg(0)
		filename2 = flag.Arg(1)
	} else {
		fmt.Printf("\n Need two files on the command line to determine if they're equal.  Exiting. ")
		os.Exit(1)
	}

	openedFile1, err1 := os.Open(filename1)
	check(err1, " Reading first file error is")
	defer openedFile1.Close()
	fi1, e1 := openedFile1.Stat()
	if e1 != nil {
		fmt.Fprintf(os.Stderr, " Opening %s and error is: %v.  Exiting. \n", filename1, e1)
		os.Exit(1)
	}
	fileReader1 := bufio.NewReader(openedFile1)

	openedFile2, err2 := os.Open(filename2)
	check(err2, " Reading 2nd file error is")
	defer openedFile2.Close()
	fi2, e2 := openedFile2.Stat()
	if e2 != nil {
		fmt.Fprintf(os.Stderr, " Opening %s and error is %v.  Exiting.\n", filename2, e2)
		os.Exit(1)
	}
	fileReader2 := bufio.NewReader(openedFile2)

	if fi1.Size() != fi2.Size() {
		fmt.Printf(" Files not equal as their sizes are not equal.  %s size is %d, and %s size is %d.\n", filename1, fi1.Size(), filename2, fi2.Size())
		os.Exit(1)
	}

	buf1 := make([]byte, M) // I initially wrote this as ([]byte,0,M) so the slice was 0 bytes long.  This is what I need when using append() as in other code.
	buf2 := make([]byte, M) // But it's completely wrong here.  The backing array of size M is irrelevant; the slice behaves as a buffer of length 0.

	t0 := time.Now()
	matched := true

	var counter int

outerLoop:
	for { //outer loop to refill the buffers
		n1, er1 := fileReader1.Read(buf1)
		n2, er2 := fileReader2.Read(buf2)
		counter++
		if er1 != nil || er2 != nil {
			if er1 == io.EOF || er2 == io.EOF {
				break outerLoop
			}
			fmt.Fprintf(os.Stderr, " File read errors.  %s err is %v, %s err is %v\n\n", filename1, er1, filename2, er2)
			break outerLoop
		}
		if n1 != n2 { // should never happen.  If file sizes are different should be caught above by the stat calls.
			matched = false
			fmt.Printf(" n1 is %d, n2 is %d\n", n1, n2)
			break outerLoop
		}
		if n1 == 0 || n2 == 0 { // I don't know if this will ever happen.
			break outerLoop
		}

		for i := range buf1 {
			if buf1[i] != buf2[i] {
				matched = false
				fmt.Printf(" First mismatching character is at position %d in loop %d.\n", i, counter)
				if verboseFlag {
					fmt.Printf(" The mismatched characters are %c in %s, and %c in %s.\n", buf1[i], filename1, buf2[i], filename2)
				}
				break outerLoop
			}
		}
	}

	if verboseFlag {
		fmt.Printf(" Outer loop counter is %d.  %s and %s are ", counter, filename1, filename2)
	} else {
		fmt.Print(" Files are ")
	}

	if matched {
		fmt.Print("equal")
	} else {
		fmt.Print("NOT equal")
	}
	fmt.Printf(".  Elapsed time is %s\n\n", time.Since(t0))

} // Main for feqbbb.go.

// ------------------------------------------------------- check -------------------------------
func check(e error, msg string) {
	if e != nil {
		fmt.Fprintln(os.Stderr, msg, e)
	}
}
<commit_msg>05/26/2022 07:41:19 AM feqbbb/feqbbb.go -- including timing info.<commit_after>package main // for feqbbb.go

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
	"runtime"
	"time"
)

/*
  REVISION HISTORY
  ----------------
   6 Apr 13 -- M2:  First modified version of module.  I will use VLI to compare all digits of the hashes.
  23 Apr 13 -- Fixed problem of a single line in the hashes file, that does not contain an EOL character, causes
                an immediate return without processing of the characters just read in.
  24 Apr 13 -- Added output of which file either matches or does not match.
  19 Sep 16 -- Finished conversion to Go, that was started 13 Sep 16.  Added the removal of '*' which is part of a std linux formatted hash file.  And I forgot that
                 the routine allowed either order in the file.  If the token has a '.' I assume it is a filename, else it is a hash value.
  21 Sep 16 -- Fixed the case issue in tokenize.GetToken.  Edited code here to correspond to this fix.
  25 Nov 16 -- Need to not panic when target file is not found, only panic when hash file is not found.
                 And added a LastCompiled message and string.
  13 Oct 17 -- No changes here, but tokenize was changed so that horizontal tab char is now a delim.
  14 Oct 17 -- Tweaked output a bit.  And added executable timestamp code.
  19 Oct 17 -- Added ability to ignore the * that standard hash files for linux use.
  22 Oct 17 -- Added filepicker.
  21 Jan 18 -- Really ignore *.  Before method did not work.
  26 Jan 18 -- Changed tokenize so that SetMapDelim change sticks and actually works.
  13 Nov 18 -- Will use "-" and "_" also to detect a filename token.
  10 Nov 19 -- Now uses ToLower to compare the string hashes, to ignore case.
  15 Jul 20 -- Decided to make better guesses.  Sha1 has 40 digits, Sha256 has 64 digits and Sha512 has 128 digits.
  27 Sep 20 -- From help file of TakeCommand: MD-5 has 32 digits, SHA384 has 96 digits, and the above hash lengths are correct.
                 And I'm going to change from tokenize to tknptr.  Just to see if it works.
  25 Feb 21 -- Added 999 as a stop code.
   3 Mar 21 -- Now called sha.go, which will always use hash length, while ignoring file extension.
                 Errors now go to Stderr.  Uses bytes buffer to read sha file using os.ReadAll, using go 1.16.
   7 Mar 21 -- Added use of strings.TrimSpace()
   8 Apr 21 -- Converting to module version of ~/go/src.
  24 Jan 22 -- Adding a help message using the flag package.  And since I recently changed the interface for filepicker, I have to fix that here too.
   9 Mar 22 -- Using package constants instead of my magic numbers.
                  Now called feq for File Equal, that is, it will determine if 2 files are equal by computing a bunch of hashes.
                  And as this can apply to non-text files as well as text, I won't assume an extension.  Binaries on linux don't have one, anyway.
                  Turns out that crc is much more complex than I expected.  I tried each method just to see if I could get it to work.  But only once.
  12 Mar 22 -- Adding timing info.  For a 3.5 GB file, the results on leox are:
                  Castognoli 2.4s, IEEE 3.6s, byte-by-byte 4.7s, crc64 ECMA 11.5s, sha1 20.3s, md5 28.2s, sha512 35.7s, Koopman 46.8s, sha256 52.8s.
               Now called feqlarge.go, intended for files that are quite large.  I will only open one file at a time, calculate some of the hashes, and
                  compare them afterwards.  When I tested feq.go on a large file (22GB, IIRC), the OS shut it down.
                  I'll only use Castognoli, crc64 ECMA and sha512.  I can't do byte-by-byte because this is intended for very large files that can't both be in memory.
                  I forgot that some of the above timings include 2 methods of computation, checksum and sum32.
               Now called feq64.go, and will only compute crc64 ECMA checksum, in a way that only opens 1 file at a time.  And it doesn't need a bytes.Reader.
  21 May 22 -- Since I want to be able to process huge files > 3 GB, I can't read in the entire file at once.  I'll switch to a file reader algorithm.
                  Now called feq32, to play w/ the crc32 functions.  Since I intend this for huge files (> 3 GB), I'll use a flag to determine which crc32 to use.
  24 May 22 -- Now called feqbbb, for byte by byte.  I'll read in chunks and compare them, so very large files can be handled, too.
                 On leox, a 2.3 GB file comparison is ~1.6 s, about the same as feq32 -IEEE, and slightly slower than feq32 -cast which is ~1.4 s.
                 Using a 10 MB buffer instead of a 1 MB buffer is slower, at ~1.9 s.  Imagine that.
*/

const LastCompiled = "26 May 2022"
const K = 1024
const M = K * K

//* ************************* MAIN ***************************************************************
func main() {

	var filename1, filename2 string

	workingDir, _ := os.Getwd()
	execName, _ := os.Executable()
	ExecFI, _ := os.Stat(execName)
	LastLinkedTimeStamp := ExecFI.ModTime().Format("Mon Jan 2 2006 15:04:05 MST")

	// flag help message
	flag.Usage = func() {
		fmt.Fprintf(flag.CommandLine.Output(), " file equal byte by byte tester, last modified %s, compiled with %s.\n", LastCompiled, runtime.Version())
		fmt.Fprintf(flag.CommandLine.Output(), " Filenames to compare are given on the command line.\n")
		fmt.Fprintf(flag.CommandLine.Output(), " %s has timestamp of %s.  Working directory is %s.  Full name of executable is %s.\n",
			ExecFI.Name(), LastLinkedTimeStamp, workingDir, execName)
		fmt.Fprintln(flag.CommandLine.Output())
		flag.PrintDefaults()
	}
	var verboseFlag bool
	flag.BoolVar(&verboseFlag, "v", false, " verbose mode.")
	flag.Parse()

	if verboseFlag {
		fmt.Printf("\n feqbbb File equal using byte by byte comparisons of chunks, last modified %s, compiled by %s\n\n", LastCompiled, runtime.Version())
	}

	if flag.NArg() == 0 {
		fmt.Printf("\n Need two files on the command line to determine if they're equal.  Exiting. \n\n")
		os.Exit(1)
	} else if flag.NArg() >= 2 { // will use first 2 filenames entered on commandline
		filename1 = flag.Arg(0)
		filename2 = flag.Arg(1)
	} else {
		fmt.Printf("\n Need two files on the command line to determine if they're equal.  Exiting. ")
		os.Exit(1)
	}

	openedFile1, err1 := os.Open(filename1)
	check(err1, " Reading first file error is")
	defer openedFile1.Close()
	fi1, e1 := openedFile1.Stat()
	if e1 != nil {
		fmt.Fprintf(os.Stderr, " Opening %s and error is: %v.  Exiting. \n", filename1, e1)
		os.Exit(1)
	}
	fileReader1 := bufio.NewReader(openedFile1)

	openedFile2, err2 := os.Open(filename2)
	check(err2, " Reading 2nd file error is")
	defer openedFile2.Close()
	fi2, e2 := openedFile2.Stat()
	if e2 != nil {
		fmt.Fprintf(os.Stderr, " Opening %s and error is %v.  Exiting.\n", filename2, e2)
		os.Exit(1)
	}
	fileReader2 := bufio.NewReader(openedFile2)

	if fi1.Size() != fi2.Size() {
		fmt.Printf(" Files not equal as their sizes are not equal.  %s size is %d, and %s size is %d.\n", filename1, fi1.Size(), filename2, fi2.Size())
		os.Exit(1)
	}

	buf1 := make([]byte, 1*M) // I initially wrote this as ([]byte,0,M) so the slice was 0 bytes long.  This is what I need when using append() as in other code.
	buf2 := make([]byte, 1*M) // But it's completely wrong here.  The backing array of size M is irrelevant; the slice behaves as a buffer of length 0.

	t0 := time.Now()
	matched := true

	var counter int

outerLoop:
	for { //outer loop to refill the buffers
		n1, er1 := fileReader1.Read(buf1)
		n2, er2 := fileReader2.Read(buf2)
		counter++
		if er1 != nil || er2 != nil {
			if er1 == io.EOF || er2 == io.EOF {
				break outerLoop
			}
			fmt.Fprintf(os.Stderr, " File read errors.  %s err is %v, %s err is %v\n\n", filename1, er1, filename2, er2)
			break outerLoop
		}
		if n1 != n2 { // should never happen.  If file sizes are different should be caught above by the stat calls.
			matched = false
			fmt.Printf(" n1 is %d, n2 is %d\n", n1, n2)
			break outerLoop
		}
		if n1 == 0 || n2 == 0 { // I don't know if this will ever happen.
			break outerLoop
		}

		for i := range buf1 {
			if buf1[i] != buf2[i] {
				matched = false
				fmt.Printf(" First mismatching character is at position %d in loop %d.\n", i, counter)
				if verboseFlag {
					fmt.Printf(" The mismatched characters are %c in %s, and %c in %s.\n", buf1[i], filename1, buf2[i], filename2)
				}
				break outerLoop
			}
		}
	}

	if verboseFlag {
		fmt.Printf(" Outer loop counter is %d.  %s and %s are ", counter, filename1, filename2)
	} else {
		fmt.Print(" Files are ")
	}

	if matched {
		fmt.Print("equal")
	} else {
		fmt.Print("NOT equal")
	}
	fmt.Printf(".  Elapsed time is %s\n\n", time.Since(t0))

} // Main for feqbbb.go.

// ------------------------------------------------------- check -------------------------------
func check(e error, msg string) {
	if e != nil {
		fmt.Fprintln(os.Stderr, msg, e)
	}
}
<|endoftext|>


<commit_before>package fetch

import (
	"encoding/json"
	"io"
	"net/http"
	"net/url"

	"github.com/juju/persistent-cookiejar"
	"github.com/slotix/dataflowkit/splash"
	"github.com/slotix/dataflowkit/storage"
	"github.com/spf13/viper"
	"golang.org/x/net/publicsuffix"
)

// Service defines Fetch service interface
type Service interface {
	Response(req FetchRequester) (FetchResponser, error)
	Fetch(req FetchRequester) (io.ReadCloser, error)
}

// FetchService implements service with empty struct
type FetchService struct {
}

// ServiceMiddleware defines a middleware for a Fetch service
type ServiceMiddleware func(Service) Service

//Response returns splash.Response
func (fs FetchService) Response(req FetchRequester) (FetchResponser, error) {

	var err error
	var fetcher Fetcher
	switch req.(type) {
	case BaseFetcherRequest:
		fetcher, err = NewFetcher(Base)
	case splash.Request:
		fetcher, err = NewFetcher(Splash)
	default:
		panic("invalid fetcher request")
	}

	if err != nil {
		logger.Error(err)
	}
	var (
		jar     *cookiejar.Jar
		cookies []byte
		cArr    []*http.Cookie
		s       storage.Store
	)
	if req.GetUserToken() != "" {
		storageType, err = storage.TypeString(viper.GetString("STORAGE_TYPE"))
		if err != nil {
			return nil, err
		}
		s = storage.NewStore(storageType)
		cookies, _ = s.Read(req.GetUserToken())
		jarOpts := &cookiejar.Options{PublicSuffixList: publicsuffix.List}
		jar, err = cookiejar.New(jarOpts)
		if err != nil {
			logger.Error("Failed to create Cookie Jar")

		}
		cArr = []*http.Cookie{}
		if len(cookies) != 0 {
			err = json.Unmarshal(cookies, &cArr)
			if err != nil {
				return nil, err
			}
			u, err := url.Parse(req.GetURL())
			if err != nil {
				return nil, err
			}
			tempCarr := []*http.Cookie{}
			for i := 0; i < len(cArr); i++ {
				c := cArr[i]
				if u.Host == c.Domain {
					tempCarr = append(tempCarr, c)
					cArr = append(cArr[:i], cArr[i+1:]...)
					i--
				}
			}
			jar.SetCookies(u, tempCarr)
		}
		fetcher.SetCookieJar(jar)
	}
	//res, err := fetcher.Fetch(req)
	res, err := fetcher.Response(req)
	if err != nil {
		return nil, err
	}
	if req.GetUserToken() != "" {
		jar = fetcher.GetCookieJar()
		cArr = append(cArr, jar.AllCookies()...)
		cookies, err = json.Marshal(cArr)
		logger.Info(string(cookies))
		if err != nil {
			return nil, err
		}
		err = s.Write(req.GetUserToken(), cookies, 0)
		if err != nil {
			return nil, err
		}
	}
	return res, nil
}

//Fetch downloads web page content and returns it
func (fs FetchService) Fetch(req FetchRequester) (io.ReadCloser, error) {
	res, err := fs.Response(req)
	if err != nil {
		return nil, err
	}
	return res.GetHTML()
}
<commit_msg>comment log string<commit_after>package fetch

import (
	"encoding/json"
	"io"
	"net/http"
	"net/url"

	"github.com/juju/persistent-cookiejar"
	"github.com/slotix/dataflowkit/splash"
	"github.com/slotix/dataflowkit/storage"
	"github.com/spf13/viper"
	"golang.org/x/net/publicsuffix"
)

// Service defines Fetch service interface
type Service interface {
	Response(req FetchRequester) (FetchResponser, error)
	Fetch(req FetchRequester) (io.ReadCloser, error)
}

// FetchService implements service with empty struct
type FetchService struct {
}

// ServiceMiddleware defines a middleware for a Fetch service
type ServiceMiddleware func(Service) Service

//Response returns splash.Response
func (fs FetchService) Response(req FetchRequester) (FetchResponser, error) {

	var err error
	var fetcher Fetcher
	switch req.(type) {
	case BaseFetcherRequest:
		fetcher, err = NewFetcher(Base)
	case splash.Request:
		fetcher, err = NewFetcher(Splash)
	default:
		panic("invalid fetcher request")
	}

	if err != nil {
		logger.Error(err)
	}
	var (
		jar     *cookiejar.Jar
		cookies []byte
		cArr    []*http.Cookie
		s       storage.Store
	)
	if req.GetUserToken() != "" {
		storageType, err = storage.TypeString(viper.GetString("STORAGE_TYPE"))
		if err != nil {
			return nil, err
		}
		s = storage.NewStore(storageType)
		cookies, _ = s.Read(req.GetUserToken())
		jarOpts := &cookiejar.Options{PublicSuffixList: publicsuffix.List}
		jar, err = cookiejar.New(jarOpts)
		if err != nil {
			logger.Error("Failed to create Cookie Jar")

		}
		cArr = []*http.Cookie{}
		if len(cookies) != 0 {
			err = json.Unmarshal(cookies, &cArr)
			if err != nil {
				return nil, err
			}
			u, err := url.Parse(req.GetURL())
			if err != nil {
				return nil, err
			}
			tempCarr := []*http.Cookie{}
			for i := 0; i < len(cArr); i++ {
				c := cArr[i]
				if u.Host == c.Domain {
					tempCarr = append(tempCarr, c)
					cArr = append(cArr[:i], cArr[i+1:]...)
					i--
				}
			}
			jar.SetCookies(u, tempCarr)
		}
		fetcher.SetCookieJar(jar)
	}
	//res, err := fetcher.Fetch(req)
	res, err := fetcher.Response(req)
	if err != nil {
		return nil, err
	}
	if req.GetUserToken() != "" {
		jar = fetcher.GetCookieJar()
		cArr = append(cArr, jar.AllCookies()...)
		cookies, err = json.Marshal(cArr)
		//logger.Info(string(cookies))
		if err != nil {
			return nil, err
		}
		err = s.Write(req.GetUserToken(), cookies, 0)
		if err != nil {
			return nil, err
		}
	}
	return res, nil
}

//Fetch downloads web page content and returns it
func (fs FetchService) Fetch(req FetchRequester) (io.ReadCloser, error) {
	res, err := fs.Response(req)
	if err != nil {
		return nil, err
	}
	return res.GetHTML()
}
<|endoftext|>


<commit_before>// Tideland Go CouchDB Client - Find - Selector
//
// Copyright (C) 2016-2017 Frank Mueller / Tideland / Oldenburg / Germany
//
// All rights reserved. Use of this source code is governed
// by the new BSD license.

package find

//--------------------
// IMPORTS
//--------------------

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

//--------------------
// CONSTANTS
//--------------------

// FieldType describes the valid types of document fields.
type FieldType string

// List of valid field types.
const (
	FieldTypeNull    FieldType = "null"
	FieldTypeBoolean FieldType = "boolean"
	FieldTypeNumber  FieldType = "number"
	FieldTypeString  FieldType = "string"
	FieldTypeArray   FieldType = "array"
	FieldTypeObject  FieldType = "object"
)

// Operators expecting an array.
var arrayOperators = map[string]bool{
	"$and": true,
	"$or":  true,
	"$nor": true,
	"$all": true,
	"$in":  true,
	"$nin": true,
}

//--------------------
// NEGATABLE
//--------------------

// Negatable allows to negate a selector.
type Negatable interface {
	// Not negates a selector.
	Not()
}

//--------------------
// CRITERION
//--------------------

// Criterion defines one selector criterion. They are created by several extra
// functions. Some of those expect a field name for their operation. In case of
// MatchElement() and MatchAll() the fields of the sub-criteria have
type Criterion interface {
	// Not allows to negate this criterion.
	Not() Criterion

	// Marshaler allows to write this selector in its JSON encoding.
	json.Marshaler
}

// criterion implements Criterion.
type criterion struct {
	not       bool
	field     string
	operator  string
	arguments []interface{}
}

// newValuesCriterion creates a createrion with N values as arguments.
func newValuesCriterion(field, operator string, values ...interface{}) *criterion {
	return &criterion{
		field:     field,
		operator:  operator,
		arguments: values,
	}
}

// newCriteriaCriterion creates a createrion with N criteria as arguments.
func newCriteriaCriterion(field, operator string, criteria ...Criterion) *criterion {
	arguments := make([]interface{}, len(criteria))
	for i, c := range criteria {
		arguments[i] = c
	}
	return newValuesCriterion(field, operator, arguments...)
}

// Not implements Criterion.
func (c *criterion) Not() Criterion {
	c.not = true
	return c
}

// MarshalJSON implements json.Marshaler.
func (c *criterion) MarshalJSON() ([]byte, error) {
	var sbuf bytes.Buffer
	var jargs [][]byte
	var jargslen int

	// Praparations first.
	for _, argument := range c.arguments {
		jarg, err := json.Marshal(argument)
		if err != nil {
			return nil, err
		}
		jargs = append(jargs, jarg)
	}
	jargslen = len(jargs)

	// Is negated?
	if c.not {
		fmt.Fprint(&sbuf, "{\"$not\":")
	}
	// Prepend with field if needed.
	if c.field != "" {
		fmt.Fprintf(&sbuf, "{%q:", c.field)
	}
	// Now operator and argument(s).
	fmt.Fprintf(&sbuf, "{%q:", c.operator)
	if arrayOperators[c.operator] {
		fmt.Fprint(&sbuf, "[")
	}
	for i, jarg := range jargs {
		fmt.Fprintf(&sbuf, "%s", jarg)
		if i < jargslen-1 {
			fmt.Fprint(&sbuf, ",")
		}
	}
	if arrayOperators[c.operator] {
		fmt.Fprint(&sbuf, "]")
	}
	fmt.Fprint(&sbuf, "}")
	// Append closing brace if field has been prepended.
	if c.field != "" {
		fmt.Fprint(&sbuf, "}")
	}
	// Append closing brace if selector is negated.
	if c.not {
		fmt.Fprint(&sbuf, "}")
	}

	return sbuf.Bytes(), nil
}

// And creates a criterion where all sub-criteria have to be true.
func And(criteria ...Criterion) Criterion {
	return newCriteriaCriterion("", "$and", criteria...)
}

// Or creates a criterion where any sub-criteria have to be true.
func Or(criteria ...Criterion) Criterion {
	return newCriteriaCriterion("", "$or", criteria...)
}

// None creates a criterion where none of the sub-criteria may be true.
func None(criteria ...Criterion) Criterion {
	return newCriteriaCriterion("", "$nor", criteria...)
}

// Exists checks if the field exists.
func Exists(field string) Criterion {
	return newValuesCriterion(field, "$exists", true)
}

// Type checks the type of the field.
func Type(field string, fieldType FieldType) Criterion {
	return newValuesCriterion(field, "$type", fieldType)
}

// Equal checks if the field is equal to the value.
func Equal(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$eq", value)
}

// Equal checks if the field is not equal to the value.
func NotEqual(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$ne", value)
}

// Size checks the length of the array addressed with field.
func Size(field string, size int) Criterion {
	return newValuesCriterion(field, "$size", size)
}

// In checks if the field contains one of the values.
func In(field string, values ...interface{}) Criterion {
	return newValuesCriterion(field, "$in", values...)
}

// NotIn checks if the field contains none of the values.
func NotIn(field string, values ...interface{}) Criterion {
	return newValuesCriterion(field, "$nin", values...)
}

// All checks if the field contains all of the values.
func All(field string, values ...interface{}) Criterion {
	return newValuesCriterion(field, "$all", values...)
}

// GreaterThan checks if the field is greater than the value.
func GreaterThan(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$gt", value)
}

// GreaterEqualThan checks if the field is greater or equal than the value.
func GreaterEqualThan(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$gte", value)
}

// LowerThan checks if the field is lower than the value.
func LowerThan(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$lt", value)
}

// LowerEqualThan checks if the field is loweer or equal than the value.
func LowerEqualThan(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$lte", value)
}

// Modulo checks the remainder of the field devided by divisor.
func Modulo(field string, divisor, remainder int) Criterion {
	return newValuesCriterion(field, "$mod", divisor, remainder)
}

// RegExp checks if the field matches the given pattern.
func RegExp(field, pattern string) Criterion {
	return newValuesCriterion(field, "$regex", pattern)
}

//--------------------
// SELECTOR
//--------------------

// Selector contains one or more criteria to find documents.
type Selector json.Marshaler

// selector implements Selector.
type selector []Criterion

// MarshalJSON implements json.Marshaler.
func (s selector) MarshalJSON() ([]byte, error) {
	// Special case: Only one criterion.
	if len(s) == 1 {
		return s[0].MarshalJSON()
	}
	// Regular case.
	var buf bytes.Buffer
	var slen = len(s)

	fmt.Fprint(&buf, "{")
	for i, c := range s {
		b, err := c.MarshalJSON()
		if err != nil {
			return nil, err
		}
		buf.Write(b[1 : len(b)-1])
		if i < slen-1 {
			fmt.Fprint(&buf, ",")
		}
	}
	fmt.Fprint(&buf, "}")

	return buf.Bytes(), nil
}

// Select creates a selector based on the passed criteria.
func Select(criteria ...Criterion) Selector {
	return selector(criteria)
}

// EOF
<commit_msg>One more change for criteria (WiP)<commit_after>// Tideland Go CouchDB Client - Find - Selector
//
// Copyright (C) 2016-2017 Frank Mueller / Tideland / Oldenburg / Germany
//
// All rights reserved. Use of this source code is governed
// by the new BSD license.

package find

//--------------------
// IMPORTS
//--------------------

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

//--------------------
// CONSTANTS
//--------------------

// FieldType describes the valid types of document fields.
type FieldType string

// List of valid field types.
const (
	FieldTypeNull    FieldType = "null"
	FieldTypeBoolean FieldType = "boolean"
	FieldTypeNumber  FieldType = "number"
	FieldTypeString  FieldType = "string"
	FieldTypeArray   FieldType = "array"
	FieldTypeObject  FieldType = "object"
)

// Operators expecting an array.
var arrayOperators = map[string]bool{
	"$and": true,
	"$or":  true,
	"$nor": true,
	"$all": true,
	"$in":  true,
	"$nin": true,
}

//--------------------
// NEGATABLE
//--------------------

// Negatable allows to negate a selector.
type Negatable interface {
	// Not negates a selector.
	Not()
}

//--------------------
// CRITERION
//--------------------

// Criterion defines one selector criterion. They are created by several extra
// functions. Some of those expect a field name for their operation. In case of
// MatchElement() and MatchAll() the fields of the sub-criteria have
type Criterion interface {
	// Not allows to negate this criterion.
	Not() Criterion

	// Marshaler allows to write this selector in its JSON encoding.
	json.Marshaler
}

// Criteria defines a number of selector criteria.
type Criteria json.Marshaler

// criteria implements Criteria.
type criteria []Criterion

// MarshalJSON implements json.Marshaler.
func (cs criteria) MarshalJSON() ([]byte, error) {
	// Special case: Only one criterion.
	if len(cs) == 1 {
		return cs[0].MarshalJSON()
	}
	// Regular case.
	var buf bytes.Buffer
	var cslen = len(cs)

	fmt.Fprint(&buf, "{")
	for i, c := range cs {
		b, err := c.MarshalJSON()
		if err != nil {
			return nil, err
		}
		buf.Write(b[1 : len(b)-1])
		if i < cslen-1 {
			fmt.Fprint(&buf, ",")
		}
	}
	fmt.Fprint(&buf, "}")

	return buf.Bytes(), nil
}

// criterion implements Criterion.
type criterion struct {
	not      bool
	field    string
	operator string
	criteria Criteria
	values   []interface{}
}

// newValuesCriterion creates a createrion with N values as arguments.
func newValuesCriterion(field, operator string, values ...interface{}) *criterion {
	return &criterion{
		field:    field,
		operator: operator,
		values:   values,
	}
}

// newCriteriaCriterion creates a createrion with N criteria as arguments.
func newCriteriaCriterion(field, operator string, criteria ...Criterion) *criterion {
	return &criterion{
		field:    field,
		operator: operator,
		criteria: Criteria(criteria),
	}
}

// Not implements Criterion.
func (c *criterion) Not() Criterion {
	c.not = true
	return c
}

// MarshalJSON implements json.Marshaler.
func (c *criterion) MarshalJSON() ([]byte, error) {
	var sbuf bytes.Buffer
	var jvalues [][]byte
	var jvalueslen int

	// Preparations first.
	for _, value := range c.values {
		jvalue, err := json.Marshal(value)
		if err != nil {
			return nil, err
		}
		jvalues = append(jvalues, jvalue)
	}
	jvalueslen = len(jvalues)

	// Is negated?
	if c.not {
		fmt.Fprint(&sbuf, "{\"$not\":")
	}
	// Prepend with field if needed.
	if c.field != "" {
		fmt.Fprintf(&sbuf, "{%q:", c.field)
	}
	// Now operator and values(s).
	fmt.Fprintf(&sbuf, "{%q:", c.operator)
	// Decide between criteria and values.
	if c.criteria != nil {
		// Criteria.
		b, err := c.criteria.MarshalJSON()
		if err != nil {
			return nil, err
		}
		sbuf.Write(b)
	} else {
		// Value(s).
		vlen := len(c.values)
		if arrayOperators[c.operator] {
			fmt.Fprint(&sbuf, "[")
		}
		for i, value := range c.values {
			b, err := json.Marshal(value)
			if err != nil {
				return nil, err
			}
			if i < vlen-1 {
				fmt.Fprint(&sbuf, ",")
			}
		}
		if arrayOperators[c.operator] {
			fmt.Fprint(&sbuf, "]")
		}
	}
	fmt.Fprint(&sbuf, "}")
	// Append closing brace if field has been prepended.
	if c.field != "" {
		fmt.Fprint(&sbuf, "}")
	}
	// Append closing brace if selector is negated.
	if c.not {
		fmt.Fprint(&sbuf, "}")
	}

	return sbuf.Bytes(), nil
}

// And creates a criterion where all sub-criteria have to be true.
func And(criteria ...Criterion) Criterion {
	return newCriteriaCriterion("", "$and", criteria...)
}

// Or creates a criterion where any sub-criteria have to be true.
func Or(criteria ...Criterion) Criterion {
	return newCriteriaCriterion("", "$or", criteria...)
}

// None creates a criterion where none of the sub-criteria may be true.
func None(criteria ...Criterion) Criterion {
	return newCriteriaCriterion("", "$nor", criteria...)
}

// Exists checks if the field exists.
func Exists(field string) Criterion {
	return newValuesCriterion(field, "$exists", true)
}

// Type checks the type of the field.
func Type(field string, fieldType FieldType) Criterion {
	return newValuesCriterion(field, "$type", fieldType)
}

// Equal checks if the field is equal to the value.
func Equal(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$eq", value)
}

// Equal checks if the field is not equal to the value.
func NotEqual(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$ne", value)
}

// Size checks the length of the array addressed with field.
func Size(field string, size int) Criterion {
	return newValuesCriterion(field, "$size", size)
}

// In checks if the field contains one of the values.
func In(field string, values ...interface{}) Criterion {
	return newValuesCriterion(field, "$in", values...)
}

// NotIn checks if the field contains none of the values.
func NotIn(field string, values ...interface{}) Criterion {
	return newValuesCriterion(field, "$nin", values...)
}

// All checks if the field contains all of the values.
func All(field string, values ...interface{}) Criterion {
	return newValuesCriterion(field, "$all", values...)
}

// GreaterThan checks if the field is greater than the value.
func GreaterThan(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$gt", value)
}

// GreaterEqualThan checks if the field is greater or equal than the value.
func GreaterEqualThan(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$gte", value)
}

// LowerThan checks if the field is lower than the value.
func LowerThan(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$lt", value)
}

// LowerEqualThan checks if the field is loweer or equal than the value.
func LowerEqualThan(field string, value interface{}) Criterion {
	return newValuesCriterion(field, "$lte", value)
}

// Modulo checks the remainder of the field devided by divisor.
func Modulo(field string, divisor, remainder int) Criterion {
	return newValuesCriterion(field, "$mod", divisor, remainder)
}

// RegExp checks if the field matches the given pattern.
func RegExp(field, pattern string) Criterion {
	return newValuesCriterion(field, "$regex", pattern)
}

//--------------------
// SELECTOR
//--------------------

// Selector contains one or more criteria to find documents.
type Selector Criteria

// Select creates a selector based on the passed criteria.
func Select(criteria ...Criterion) Selector {
	return criteria
}

// EOF
<|endoftext|>


<commit_before>package controller

import (
	"bufio"
	"os"
	"strings"
)

//NewInput is used to create an input controller
func NewInput(listener chan string) *input {
	newController := input{}
	newController.isRunning = true
	newController.listener = listener
	newController.isDone = make(chan bool)

	go newController.process()
	return &newController
}

//Input is a controller designed for passing input controls.
type input struct {
	listener  chan string
	isDone    chan bool
	isRunning bool
}

//Stop causes the Input controller to stop.
func (controller *input) Stop() {
	controller.isDone <- true
	controller.isRunning = false
	close(controller.isDone)
}

//process runs a loop awaiting input from the keyboard and passing
//it along to any channel registered.
func (controller *input) process() {

	outChannel := make(chan string)
	defer close(outChannel)
	exitChannel := make(chan bool)

	go getInput(outChannel, exitChannel)

	for {
		select {
		case output := <-outChannel:
			controller.listener <- output
		case <-controller.isDone:
			exitChannel <- true
			return
		}
	}
}

//getInput handles waiting for keyboard input and sending
//the first character out on the out channel.
func getInput(out chan string, isDone chan bool) {
	reader := bufio.NewReader(os.Stdin)
	defer close(isDone)

	for {
		input, _ := reader.ReadString('\n')
		select {
		case out <- strings.Split(input, "")[0]:
		case done := <-isDone:
			if done {
				return
			}
		}
	}
}
<commit_msg>changed local variable name in input controller newController function<commit_after>package controller

import (
	"bufio"
	"os"
	"strings"
)

//NewInput is used to create an input controller
func NewInput(listener chan string) *input {
	controller := input{}
	controller.isRunning = true
	controller.listener = listener
	controller.isDone = make(chan bool)

	go controller.process()
	return &controller
}

//Input is a controller designed for passing input controls.
type input struct {
	listener  chan string
	isDone    chan bool
	isRunning bool
}

//Stop causes the Input controller to stop.
func (controller *input) Stop() {
	controller.isDone <- true
	controller.isRunning = false
	close(controller.isDone)
}

//process runs a loop awaiting input from the keyboard and passing
//it along to any channel registered.
func (controller *input) process() {

	outChannel := make(chan string)
	defer close(outChannel)
	exitChannel := make(chan bool)

	go getInput(outChannel, exitChannel)

	for {
		select {
		case output := <-outChannel:
			controller.listener <- output
		case <-controller.isDone:
			exitChannel <- true
			return
		}
	}
}

//getInput handles waiting for keyboard input and sending
//the first character out on the out channel.
func getInput(out chan string, isDone chan bool) {
	reader := bufio.NewReader(os.Stdin)
	defer close(isDone)

	for {
		input, _ := reader.ReadString('\n')
		select {
		case out <- strings.Split(input, "")[0]:
		case done := <-isDone:
			if done {
				return
			}
		}
	}
}
<|endoftext|>


<commit_before>// clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	target := time.Date(2016, 8, 15, 0, 0, 0, 0, time.Local)
	motto := "Just Go"
	printTargetTime(target, motto)
	exitOnEnterKey()

	var previous time.Time
	for {
		now := time.Now()
		now = now.Add(time.Duration(-now.Nanosecond())) // truncate to second
		if now != previous {
			previous = now
			remaining := target.Sub(now)
			printTimeRemaining(now, remaining)
		}
		time.Sleep(50 * time.Millisecond)
	}
}

func exitOnEnterKey() {
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()
}

const (
	indent         = "\t"
	highlightStart = "\x1b[1;35m"
	highlightEnd   = "\x1b[0m"
)

func printTargetTime(target time.Time, motto string) {
	fmt.Print(indent, highlightStart, motto, highlightEnd, "\n")
	fmt.Print(indent, target.Format(time.UnixDate), "\n")
}

func printTimeRemaining(now time.Time, remaining time.Duration) {
	var sign string
	if remaining > 0 {
		sign = "-" // countdown is "T minus..."
	} else {
		sign = "+" // count up is "T plus..."
		remaining = -remaining
	}

	var days int
	if remaining >= 24*time.Hour {
		days = int(remaining / (24 * time.Hour))
		remaining = remaining % (24 * time.Hour)
	}

	fmt.Print(indent, now.Format(time.UnixDate), "  ", sign)
	if days > 0 {
		fmt.Print(days, "d")
	}
	fmt.Print(remaining, "          \r")
	os.Stdout.Sync()
}
<commit_msg>Go 1.7<commit_after>// clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	target := time.Date(2016, 8, 16, 0, 0, 0, 0, time.UTC)
	motto := "Just Go"
	printTargetTime(target, motto)
	exitOnEnterKey()

	var previous time.Time
	for {
		now := time.Now()
		now = now.Add(time.Duration(-now.Nanosecond())) // truncate to second
		if now != previous {
			previous = now
			remaining := target.Sub(now)
			printTimeRemaining(now, remaining)
		}
		time.Sleep(50 * time.Millisecond)
	}
}

func exitOnEnterKey() {
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()
}

const (
	indent         = "\t"
	highlightStart = "\x1b[1;35m"
	highlightEnd   = "\x1b[0m"
)

func printTargetTime(target time.Time, motto string) {
	fmt.Print(indent, highlightStart, motto, highlightEnd, "\n")
	fmt.Print(indent, target.Format(time.UnixDate), "\n")
}

func printTimeRemaining(now time.Time, remaining time.Duration) {
	var sign string
	if remaining > 0 {
		sign = "-" // countdown is "T minus..."
	} else {
		sign = "+" // count up is "T plus..."
		remaining = -remaining
	}

	var days int
	if remaining >= 24*time.Hour {
		days = int(remaining / (24 * time.Hour))
		remaining = remaining % (24 * time.Hour)
	}

	fmt.Print(indent, now.Format(time.UnixDate), "  ", sign)
	if days > 0 {
		fmt.Print(days, "d")
	}
	fmt.Print(remaining, "          \r")
	os.Stdout.Sync()
}
<|endoftext|>


<commit_before>// Copyright 2015 Robert S. Gerus. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package bot

import (
	"errors"
	"io"
	"net/http"
	"time"

	"github.com/moovweb/gokogiri"
	"github.com/moovweb/gokogiri/xpath"

	cfg "github.com/arachnist/gorepost/config"
	"github.com/arachnist/gorepost/irc"
)

var errElementNotFound = errors.New("element not found in document")

func httpGet(l string) ([]byte, error) {
	var buf []byte
	tr := &http.Transport{
		TLSHandshakeTimeout:   5 * time.Second,
		ResponseHeaderTimeout: 5 * time.Second,
	}
	client := &http.Client{Transport: tr}

	resp, err := client.Get(l)
	if err != nil {
		return []byte{}, err
	}

	// 5MiB
	if resp.ContentLength > 5*1024*1024 || resp.ContentLength < 0 {
		buf = make([]byte, 5*1024*1024)
	} else if resp.ContentLength == 0 {
		return []byte{}, nil
	} else {
		buf = make([]byte, resp.ContentLength)
	}

	i, err := io.ReadFull(resp.Body, buf)
	if err == io.ErrUnexpectedEOF {
		buf = buf[:i]
	} else if err != nil {
		return []byte{}, err
	}

	return buf, nil
}

func httpGetXpath(l, x string) (string, error) {
	buf, err := httpGet(l)
	if err != nil {
		return "", err
	}

	doc, err := gokogiri.ParseHtml(buf)
	defer doc.Free()
	if err != nil {
		return "", err
	}

	xpath := xpath.Compile(x)
	sr, err := doc.Root().Search(xpath)
	if err != nil {
		return "", err
	}

	if len(sr) > 0 {
		return sr[0].InnerHtml(), nil
	}

	return "", errElementNotFound
}

func reply(msg irc.Message, text string) irc.Message {
	if msg.Params[0] == cfg.LookupString(msg.Context, "Nick") {
		return irc.Message{
			Command:  "PRIVMSG",
			Params:   []string{msg.Prefix.Name},
			Trailing: text,
		}
	}

	return irc.Message{
		Command:  "PRIVMSG",
		Params:   msg.Params,
		Trailing: text,
	}
}
<commit_msg>Fix a crash in httpGetXpath()<commit_after>// Copyright 2015 Robert S. Gerus. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package bot

import (
	"errors"
	"io"
	"net/http"
	"time"

	"github.com/moovweb/gokogiri"
	"github.com/moovweb/gokogiri/xpath"

	cfg "github.com/arachnist/gorepost/config"
	"github.com/arachnist/gorepost/irc"
)

var errElementNotFound = errors.New("element not found in document")

func httpGet(l string) ([]byte, error) {
	var buf []byte
	tr := &http.Transport{
		TLSHandshakeTimeout:   5 * time.Second,
		ResponseHeaderTimeout: 5 * time.Second,
	}
	client := &http.Client{Transport: tr}

	resp, err := client.Get(l)
	if err != nil {
		return []byte{}, err
	}

	// 5MiB
	if resp.ContentLength > 5*1024*1024 || resp.ContentLength < 0 {
		buf = make([]byte, 5*1024*1024)
	} else if resp.ContentLength == 0 {
		return []byte{}, nil
	} else {
		buf = make([]byte, resp.ContentLength)
	}

	i, err := io.ReadFull(resp.Body, buf)
	if err == io.ErrUnexpectedEOF {
		buf = buf[:i]
	} else if err != nil {
		return []byte{}, err
	}

	return buf, nil
}

func httpGetXpath(l, x string) (string, error) {
	buf, err := httpGet(l)
	if err != nil {
		return "", err
	}

	doc, err := gokogiri.ParseHtml(buf)
	defer doc.Free()
	if err != nil {
		return "", err
	}
	if doc.Root() == nil {
		return "", errElementNotFound
	}

	xpath := xpath.Compile(x)
	sr, err := doc.Root().Search(xpath)
	if err != nil {
		return "", err
	}

	if len(sr) > 0 {
		return sr[0].InnerHtml(), nil
	}

	return "", errElementNotFound
}

func reply(msg irc.Message, text string) irc.Message {
	if msg.Params[0] == cfg.LookupString(msg.Context, "Nick") {
		return irc.Message{
			Command:  "PRIVMSG",
			Params:   []string{msg.Prefix.Name},
			Trailing: text,
		}
	}

	return irc.Message{
		Command:  "PRIVMSG",
		Params:   msg.Params,
		Trailing: text,
	}
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright 2014 by Artem Andreenko, Openstat.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 ******************************************************************************/
 package msgbatch

import (
	"code.google.com/p/snappy-go/snappy"
	"github.com/vmihailenco/msgpack"
)

type Batch struct {
	Length  int
	Columns []string
	Values  [][][]interface{}
}

func (batch *Batch) Add(e map[string]interface{}) {
	for key, value := range e {
		columnIndex := -1
		for i, column := range batch.Columns {
			if column == key {
				columnIndex = i
				break
			}
		}
		if columnIndex == -1 {
			columnIndex = len(batch.Columns)
			batch.Columns = append(batch.Columns, key)
			batch.Values = append(batch.Values, [][]interface{}{})
		}
		batch.Values[columnIndex] = append(batch.Values[columnIndex], []interface{}{batch.Length, value})
	}
	batch.Length++
}

func (batch *Batch) GetValues() (values []map[string]interface{}) {
	for i := 0; i < batch.Length; i++ {
		values = append(values, make(map[string]interface{}))
	}
	for columnIndex, column := range batch.Values {
		columnName := batch.Columns[columnIndex]
		for _, value := range column {
			values[value[0].(int64)][columnName] = value[1]
		}
	}
	return
}

func (batch *Batch) Encode() (data []byte, err error) {
	rawBatch := make([]interface{}, 3)
	rawBatch[0] = batch.Length
	rawBatch[1] = batch.Columns
	rawBatch[2] = batch.Values
	data, err = msgpack.Marshal(batch)
	if err != nil {
		return
	}
	data, err = snappy.Encode(nil, data)
	return
}

func Decode(data []byte) (batch Batch, err error) {
	data, err = snappy.Decode(nil, data)
	if err != nil {
		return
	}
	var rawBatch []interface{}
	err = msgpack.Unmarshal(data, &rawBatch)
	batch.Length = rawBatch[0].(int)
	batch.Columns = rawBatch[1].([]string)
	batch.Values = rawBatch[2].([][][]interface{})
	return
}
<commit_msg>add check decode format<commit_after>/*******************************************************************************
 * Copyright 2014 by Artem Andreenko, Openstat.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 ******************************************************************************/
 package msgbatch

import (
	"code.google.com/p/snappy-go/snappy"
	"github.com/vmihailenco/msgpack"
	"fmt"
)

type Batch struct {
	Length  int
	Columns []string
	Values  [][][]interface{}
}

func (batch *Batch) Add(e map[string]interface{}) {
	for key, value := range e {
		columnIndex := -1
		for i, column := range batch.Columns {
			if column == key {
				columnIndex = i
				break
			}
		}
		if columnIndex == -1 {
			columnIndex = len(batch.Columns)
			batch.Columns = append(batch.Columns, key)
			batch.Values = append(batch.Values, [][]interface{}{})
		}
		batch.Values[columnIndex] = append(batch.Values[columnIndex], []interface{}{batch.Length, value})
	}
	batch.Length++
}

func (batch *Batch) GetValues() (values []map[string]interface{}) {
	for i := 0; i < batch.Length; i++ {
		values = append(values, make(map[string]interface{}))
	}
	for columnIndex, column := range batch.Values {
		columnName := batch.Columns[columnIndex]
		for _, value := range column {
			values[value[0].(int64)][columnName] = value[1]
		}
	}
	return
}

func (batch *Batch) Encode() (data []byte, err error) {
	rawBatch := make([]interface{}, 3)
	rawBatch[0] = batch.Length
	rawBatch[1] = batch.Columns
	rawBatch[2] = batch.Values
	data, err = msgpack.Marshal(batch)
	if err != nil {
		return
	}
	data, err = snappy.Encode(nil, data)
	return
}

func Decode(data []byte) (batch Batch, err error) {
	data, err = snappy.Decode(nil, data)
	if err != nil {
		return
	}
	var rawBatch []interface{}
	err = msgpack.Unmarshal(data, &rawBatch)
	if len(rawBatch) != 3 {
		err = fmt.Errorf("bad batch data: root columns not equals 3: %d", len(rawBatch))
		return
	}
	batch.Length = rawBatch[0].(int)
	batch.Columns = rawBatch[1].([]string)
	batch.Values = rawBatch[2].([][][]interface{})
	return
}
<|endoftext|>


<commit_before>package mackerel

import (
	"encoding/json"
	"fmt"
	"net/http"
)

/*
`/dashboards` Response
Legacy
{
  "dashboards": [
	{
	  "id": "2c5bLca8d",
	  "title": "My Dashboard",
	  "bodyMarkdown": "# A test dashboard",
	  "urlPath": "2u4PP3TJqbu",
	  "createdAt": 1439346145003,
	  "updatedAt": 1439346145003,
	  "isLegacy": true
	}
  ]
}

Current
{
	"dashboards": [
		{
			"id":        "2c5bLca8e",
			"title":     "My Custom Dashboard(Current)",
			"urlPath":   "2u4PP3TJqbv",
			"createdAt": 1552909732,
			"updatedAt": 1552992837,
			"memo":      "A test Current Dashboard"
		}
	]
}
*/

/*
`/dashboards/${ID}` Response`
Legacy
{
	"id": "2c5bLca8d",
	"title": "My Dashboard",
	"bodyMarkdown": "# A test dashboard",
	"urlPath": "2u4PP3TJqbu",
	"createdAt": 1439346145003,
	"updatedAt": 1439346145003,
	"isLegacy": true
}
Current
{
  "id": "2c5bLca8e",
  "createdAt": 1552909732,
  "updatedAt": 1552992837,
  "title": "My Custom Dashboard(Current),
  "urlPath": "2u4PP3TJqbv",
  "memo": "A test Current Dashboard",
  "widgets": [
    {
      "type": "markdown",
      "title": "markdown",
      "markdown": "# body",
      "layout": {
        "x": 0,
        "y": 0,
        "width": 24,
        "height": 3
      }
    },
    {
      "type": "graph",
      "title": "graph",
      "graph": {
        "type": "host",
        "hostId": "2u4PP3TJqbw",
        "name": "loadavg.loadavg15"
      },
      "layout": {
        "x": 0,
        "y": 7,
        "width": 8,
        "height": 10
      }
    },
    {
      "type": "value",
      "title": "value",
      "metric": {
        "type": "expression",
        "expression": "alias(scale(\nsum(\n  group(\n    host(2u4PP3TJqbx,loadavg.*)\n  )\n),\n1\n), 'test')"
      },
      "layout": {
        "x": 0,
        "y": 17,
        "width": 8,
        "height": 5
      }
    }
  ]
}
*/

// Dashboard information
type Dashboard struct {
	ID           string   `json:"id,omitempty"`
	Title        string   `json:"title,omitempty"`
	BodyMarkDown string   `json:"bodyMarkdown,omitempty"`
	URLPath      string   `json:"urlPath,omitempty"`
	CreatedAt    int64    `json:"createdAt,omitempty"`
	UpdatedAt    int64    `json:"updatedAt,omitempty"`
	IsLegacy     bool     `json:"isLegacy,omitempty"`
	Memo         string   `json:"memo,omitempty"`
	Widgets      []Widget `json:"widgets,omitenpty"`
}

// Widget information
type Widget struct {
	Type   string   `json:"type,omitempty"`
	Title  string   `json:"title,omitempty"`
	Metric []Metric `json:"metric,omitempty"`
	Graph  []Graph  `json:"graph,omitempty"`
	Layout []Layout `json:"layout,omitempty"`
}

// Metric information
type Metric struct {
	Type string `json:"type,omitempty"`
}

// Graph information
type Graph struct {
	Type string `json:"type,omitempty"`
}

// Layout information
type Layout struct {
	X      uint8  `json:"x,omitempty"`
	Y      uint8  `json:"y,omitempty"`
	Width  uint16 `json:"width,omitempty"`
	Height uint16 `json:"height,omitempty"`
}

// FindDashboards find dashboards
func (c *Client) FindDashboards() ([]*Dashboard, error) {
	req, err := http.NewRequest("GET", c.urlFor("/api/v0/dashboards").String(), nil)
	if err != nil {
		return nil, err
	}
	resp, err := c.Request(req)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data struct {
		Dashboards []*Dashboard `json:"dashboards"`
	}
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}

	return data.Dashboards, err
}

// FindDashboard find dashboard
func (c *Client) FindDashboard(dashboardID string) (*Dashboard, error) {
	req, err := http.NewRequest("GET", c.urlFor(fmt.Sprintf("/api/v0/dashboards/%s", dashboardID)).String(), nil)
	if err != nil {
		return nil, err
	}
	resp, err := c.Request(req)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data Dashboard
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}
	return &data, err
}

// CreateDashboard creating dashboard
func (c *Client) CreateDashboard(param *Dashboard) (*Dashboard, error) {
	resp, err := c.PostJSON("/api/v0/dashboards", param)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data Dashboard
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}
	return &data, nil
}

// UpdateDashboard update dashboard
func (c *Client) UpdateDashboard(dashboardID string, param *Dashboard) (*Dashboard, error) {
	resp, err := c.PutJSON(fmt.Sprintf("/api/v0/dashboards/%s", dashboardID), param)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data Dashboard
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}
	return &data, nil
}

// DeleteDashboard delete dashboard
func (c *Client) DeleteDashboard(dashboardID string) (*Dashboard, error) {
	req, err := http.NewRequest(
		"DELETE",
		c.urlFor(fmt.Sprintf("/api/v0/dashboards/%s", dashboardID)).String(),
		nil,
	)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")

	resp, err := c.Request(req)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data Dashboard
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}
	return &data, nil
}
<commit_msg>add new Struct and members for Current Response<commit_after>package mackerel

import (
	"encoding/json"
	"fmt"
	"net/http"
)

/*
`/dashboards` Response
Legacy
{
  "dashboards": [
	{
	  "id": "2c5bLca8d",
	  "title": "My Dashboard",
	  "bodyMarkdown": "# A test dashboard",
	  "urlPath": "2u4PP3TJqbu",
	  "createdAt": 1439346145003,
	  "updatedAt": 1439346145003,
	  "isLegacy": true
	}
  ]
}

Current
{
	"dashboards": [
		{
			"id":        "2c5bLca8e",
			"title":     "My Custom Dashboard(Current)",
			"urlPath":   "2u4PP3TJqbv",
			"createdAt": 1552909732,
			"updatedAt": 1552992837,
			"memo":      "A test Current Dashboard"
		}
	]
}
*/

/*
`/dashboards/${ID}` Response`
Legacy
{
	"id": "2c5bLca8d",
	"title": "My Dashboard",
	"bodyMarkdown": "# A test dashboard",
	"urlPath": "2u4PP3TJqbu",
	"createdAt": 1439346145003,
	"updatedAt": 1439346145003,
	"isLegacy": true
}
Current
{
  "id": "2c5bLca8e",
  "createdAt": 1552909732,
  "updatedAt": 1552992837,
  "title": "My Custom Dashboard(Current),
  "urlPath": "2u4PP3TJqbv",
  "memo": "A test Current Dashboard",
  "widgets": [
    {
      "type": "markdown",
      "title": "markdown",
      "markdown": "# body",
      "layout": {
        "x": 0,
        "y": 0,
        "width": 24,
        "height": 3
      }
    },
    {
      "type": "graph",
      "title": "graph",
      "graph": {
        "type": "host",
        "hostId": "2u4PP3TJqbw",
        "name": "loadavg.loadavg15"
      },
      "layout": {
        "x": 0,
        "y": 7,
        "width": 8,
        "height": 10
      }
    },
    {
      "type": "value",
      "title": "value",
      "metric": {
        "type": "expression",
        "expression": "alias(scale(\nsum(\n  group(\n    host(2u4PP3TJqbx,loadavg.*)\n  )\n),\n1\n), 'test')"
      },
      "layout": {
        "x": 0,
        "y": 17,
        "width": 8,
        "height": 5
      }
    }
  ]
}
*/

// Dashboard information
type Dashboard struct {
	ID           string   `json:"id,omitempty"`
	Title        string   `json:"title,omitempty"`
	BodyMarkDown string   `json:"bodyMarkdown,omitempty"`
	URLPath      string   `json:"urlPath,omitempty"`
	CreatedAt    int64    `json:"createdAt,omitempty"`
	UpdatedAt    int64    `json:"updatedAt,omitempty"`
	IsLegacy     bool     `json:"isLegacy,omitempty"`
	Memo         string   `json:"memo,omitempty"`
	Widgets      []Widget `json:"widgets,omitenpty"`
}

// Widget information
type Widget struct {
	Type     string   `json:"type,omitempty"`
	Title    string   `json:"title,omitempty"`
	Metric   []Metric `json:"metric,omitempty"`
	Graph    []Graph  `json:"graph,omitempty"`
	Layout   []Layout `json:"layout,omitempty"`
	Markdown string   `json:"markdown,omitempty"`
	Range    []Range  `json:"range,omitempty"`
}

// Metric information
type Metric struct {
	Type        string `json:"type,omitempty"`
	HostID      string `json:"hostId,omitempty"`
	Name        string `json:"name,omitempty"`
	ServiceName string `json:"seriviceName,omitempty"`
	Expression  string `json:"expression,omitempty"`
}

// Graph information
type Graph struct {
	Type         string `json:"type,omitempty"`
	HostID       string `json:"hostId,omitempty"`
	Name         string `json:"name,omitempty"`
	RoleFullName string `json:"roleFullname,omitempty"`
	ServiceName  string `json:"seriviceName,omitempty"`
	Expression   string `json:"expression,omitempty"`
	IsStacked    bool   `json:"isStacked,omitempty"`
}

// Range information
type Range struct {
	Type   string `json:"type,omitempty"`
	Period int64  `json:"period,omitempty"`
	Offset int64  `json:"offset,omitempty"`
	Start  int64  `json:"start,omitempty"`
	End    int64  `json:"end,omitempty"`
}

// Layout information
type Layout struct {
	X      uint8  `json:"x,omitempty"`
	Y      uint8  `json:"y,omitempty"`
	Width  uint16 `json:"width,omitempty"`
	Height uint16 `json:"height,omitempty"`
}

// FindDashboards find dashboards
func (c *Client) FindDashboards() ([]*Dashboard, error) {
	req, err := http.NewRequest("GET", c.urlFor("/api/v0/dashboards").String(), nil)
	if err != nil {
		return nil, err
	}
	resp, err := c.Request(req)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data struct {
		Dashboards []*Dashboard `json:"dashboards"`
	}
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}

	return data.Dashboards, err
}

// FindDashboard find dashboard
func (c *Client) FindDashboard(dashboardID string) (*Dashboard, error) {
	req, err := http.NewRequest("GET", c.urlFor(fmt.Sprintf("/api/v0/dashboards/%s", dashboardID)).String(), nil)
	if err != nil {
		return nil, err
	}
	resp, err := c.Request(req)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data Dashboard
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}
	return &data, err
}

// CreateDashboard creating dashboard
func (c *Client) CreateDashboard(param *Dashboard) (*Dashboard, error) {
	resp, err := c.PostJSON("/api/v0/dashboards", param)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data Dashboard
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}
	return &data, nil
}

// UpdateDashboard update dashboard
func (c *Client) UpdateDashboard(dashboardID string, param *Dashboard) (*Dashboard, error) {
	resp, err := c.PutJSON(fmt.Sprintf("/api/v0/dashboards/%s", dashboardID), param)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data Dashboard
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}
	return &data, nil
}

// DeleteDashboard delete dashboard
func (c *Client) DeleteDashboard(dashboardID string) (*Dashboard, error) {
	req, err := http.NewRequest(
		"DELETE",
		c.urlFor(fmt.Sprintf("/api/v0/dashboards/%s", dashboardID)).String(),
		nil,
	)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")

	resp, err := c.Request(req)
	defer closeResponse(resp)
	if err != nil {
		return nil, err
	}

	var data Dashboard
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		return nil, err
	}
	return &data, nil
}
<|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 internal // import "go.opentelemetry.io/collector/pdata/internal"

import (
	otlpcollectormetrics "go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/metrics/v1"
	otlpmetrics "go.opentelemetry.io/collector/pdata/internal/data/protogen/metrics/v1"
)

// MetricsToOtlp internal helper to convert Metrics to otlp request representation.
func MetricsToOtlp(mw Metrics) *otlpcollectormetrics.ExportMetricsServiceRequest {
	return mw.orig
}

// MetricsFromOtlp internal helper to convert otlp request representation to Metrics.
func MetricsFromOtlp(orig *otlpcollectormetrics.ExportMetricsServiceRequest) Metrics {
	return Metrics{orig: orig}
}

// MetricsToProto internal helper to convert Metrics to protobuf representation.
func MetricsToProto(l Metrics) otlpmetrics.MetricsData {
	return otlpmetrics.MetricsData{
		ResourceMetrics: l.orig.ResourceMetrics,
	}
}

// MetricsFromProto internal helper to convert protobuf representation to Metrics.
func MetricsFromProto(orig otlpmetrics.MetricsData) Metrics {
	return Metrics{orig: &otlpcollectormetrics.ExportMetricsServiceRequest{
		ResourceMetrics: orig.ResourceMetrics,
	}}
}

// Metrics is the top-level struct that is propagated through the metrics pipeline.
// Use NewMetrics to create new instance, zero-initialized instance is not valid for use.
type Metrics struct {
	orig *otlpcollectormetrics.ExportMetricsServiceRequest
}

// NewMetrics creates a new Metrics struct.
func NewMetrics() Metrics {
	return Metrics{orig: &otlpcollectormetrics.ExportMetricsServiceRequest{}}
}

// Clone returns a copy of MetricData.
func (md Metrics) Clone() Metrics {
	cloneMd := NewMetrics()
	md.ResourceMetrics().CopyTo(cloneMd.ResourceMetrics())
	return cloneMd
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value.
func (md Metrics) MoveTo(dest Metrics) {
	*dest.orig = *md.orig
	*md.orig = otlpcollectormetrics.ExportMetricsServiceRequest{}
}

// ResourceMetrics returns the ResourceMetricsSlice associated with this Metrics.
func (md Metrics) ResourceMetrics() ResourceMetricsSlice {
	return newResourceMetricsSlice(&md.orig.ResourceMetrics)
}

// MetricCount calculates the total number of metrics.
func (md Metrics) MetricCount() int {
	metricCount := 0
	rms := md.ResourceMetrics()
	for i := 0; i < rms.Len(); i++ {
		rm := rms.At(i)
		ilms := rm.ScopeMetrics()
		for j := 0; j < ilms.Len(); j++ {
			ilm := ilms.At(j)
			metricCount += ilm.Metrics().Len()
		}
	}
	return metricCount
}

// DataPointCount calculates the total number of data points.
func (md Metrics) DataPointCount() (dataPointCount int) {
	rms := md.ResourceMetrics()
	for i := 0; i < rms.Len(); i++ {
		rm := rms.At(i)
		ilms := rm.ScopeMetrics()
		for j := 0; j < ilms.Len(); j++ {
			ilm := ilms.At(j)
			ms := ilm.Metrics()
			for k := 0; k < ms.Len(); k++ {
				m := ms.At(k)
				switch m.DataType() {
				case MetricDataTypeGauge:
					dataPointCount += m.Gauge().DataPoints().Len()
				case MetricDataTypeSum:
					dataPointCount += m.Sum().DataPoints().Len()
				case MetricDataTypeHistogram:
					dataPointCount += m.Histogram().DataPoints().Len()
				case MetricDataTypeExponentialHistogram:
					dataPointCount += m.ExponentialHistogram().DataPoints().Len()
				case MetricDataTypeSummary:
					dataPointCount += m.Summary().DataPoints().Len()
				}
			}
		}
	}
	return
}

// MetricDataType specifies the type of data in a Metric.
type MetricDataType int32

const (
	MetricDataTypeNone MetricDataType = iota
	MetricDataTypeGauge
	MetricDataTypeSum
	MetricDataTypeHistogram
	MetricDataTypeExponentialHistogram
	MetricDataTypeSummary
)

// String returns the string representation of the MetricDataType.
func (mdt MetricDataType) String() string {
	switch mdt {
	case MetricDataTypeNone:
		return "None"
	case MetricDataTypeGauge:
		return "Gauge"
	case MetricDataTypeSum:
		return "Sum"
	case MetricDataTypeHistogram:
		return "Histogram"
	case MetricDataTypeExponentialHistogram:
		return "ExponentialHistogram"
	case MetricDataTypeSummary:
		return "Summary"
	}
	return ""
}

// SetDataType clears any existing data and initialize it with an empty data of the given type.
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) SetDataType(ty MetricDataType) {
	switch ty {
	case MetricDataTypeGauge:
		ms.orig.Data = &otlpmetrics.Metric_Gauge{Gauge: &otlpmetrics.Gauge{}}
	case MetricDataTypeSum:
		ms.orig.Data = &otlpmetrics.Metric_Sum{Sum: &otlpmetrics.Sum{}}
	case MetricDataTypeHistogram:
		ms.orig.Data = &otlpmetrics.Metric_Histogram{Histogram: &otlpmetrics.Histogram{}}
	case MetricDataTypeExponentialHistogram:
		ms.orig.Data = &otlpmetrics.Metric_ExponentialHistogram{ExponentialHistogram: &otlpmetrics.ExponentialHistogram{}}
	case MetricDataTypeSummary:
		ms.orig.Data = &otlpmetrics.Metric_Summary{Summary: &otlpmetrics.Summary{}}
	}
}

// MetricAggregationTemporality defines how a metric aggregator reports aggregated values.
// It describes how those values relate to the time interval over which they are aggregated.
type MetricAggregationTemporality int32

const (
	// MetricAggregationTemporalityUnspecified is the default MetricAggregationTemporality, it MUST NOT be used.
	MetricAggregationTemporalityUnspecified = MetricAggregationTemporality(otlpmetrics.AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED)
	// MetricAggregationTemporalityDelta is a MetricAggregationTemporality for a metric aggregator which reports changes since last report time.
	MetricAggregationTemporalityDelta = MetricAggregationTemporality(otlpmetrics.AggregationTemporality_AGGREGATION_TEMPORALITY_DELTA)
	// MetricAggregationTemporalityCumulative is a MetricAggregationTemporality for a metric aggregator which reports changes since a fixed start time.
	MetricAggregationTemporalityCumulative = MetricAggregationTemporality(otlpmetrics.AggregationTemporality_AGGREGATION_TEMPORALITY_CUMULATIVE)
)

// String returns the string representation of the MetricAggregationTemporality.
func (at MetricAggregationTemporality) String() string {
	return otlpmetrics.AggregationTemporality(at).String()
}

// Flags returns the flags associated with this NumberDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms NumberDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.orig.Flags)
}

// SetFlags replaces the flags associated with this NumberDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms NumberDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.orig.Flags = uint32(v)
}

// Flags returns the flags associated with this HistogramDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms HistogramDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.orig.Flags)
}

// SetFlags replaces the flags associated with this HistogramDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms HistogramDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.orig.Flags = uint32(v)
}

// Flags returns the flags associated with this ExponentialHistogramDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms ExponentialHistogramDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.orig.Flags)
}

// SetFlags replaces the flags associated with this ExponentialHistogramDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms ExponentialHistogramDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.orig.Flags = uint32(v)
}

// Flags returns the flags associated with this SummaryDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms SummaryDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.orig.Flags)
}

// SetFlags replaces the flags associated with this SummaryDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms SummaryDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.orig.Flags = uint32(v)
}

// MetricDataPointFlagsStruct defines how a metric aggregator reports aggregated values.
// It describes how those values relate to the time interval over which they are aggregated.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewMetricDataPointFlagsStruct function to create new instances.
// Important: zero-initialized instance is not valid for use.
type MetricDataPointFlagsStruct struct {
	orig *uint32
}

func newMetricDataPointFlagsStruct(orig *uint32) MetricDataPointFlagsStruct {
	return MetricDataPointFlagsStruct{orig: orig}
}

// NewMetricDataPointFlagsStruct creates a new empty MetricDataPointFlagsStruct.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewMetricDataPointFlagsStruct() MetricDataPointFlagsStruct {
	return newMetricDataPointFlagsStruct(new(uint32))
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms MetricDataPointFlagsStruct) MoveTo(dest MetricDataPointFlagsStruct) {
	*dest.orig = *ms.orig
	*ms.orig = uint32(otlpmetrics.DataPointFlags_FLAG_NONE)
}

// CopyTo copies all properties from the current struct to the dest.
func (ms MetricDataPointFlagsStruct) CopyTo(dest MetricDataPointFlagsStruct) {
	*dest.orig = *ms.orig
}

// NoRecordedValue returns true if the MetricDataPointFlags contains the NO_RECORDED_VALUE flag.
func (ms MetricDataPointFlagsStruct) NoRecordedValue() bool {
	return *ms.orig&uint32(otlpmetrics.DataPointFlags_FLAG_NO_RECORDED_VALUE) != 0
}

// SetNoRecordedValue sets the FLAG_NO_RECORDED_VALUE flag if true and removes it if false.
// Setting this Flag when it is already set will change nothing.
func (ms MetricDataPointFlagsStruct) SetNoRecordedValue(b bool) {
	if b {
		*ms.orig |= uint32(otlpmetrics.DataPointFlags_FLAG_NO_RECORDED_VALUE)
	} else {
		*ms.orig &^= uint32(otlpmetrics.DataPointFlags_FLAG_NO_RECORDED_VALUE)
	}
}

// String returns the string representation of the MetricDataPointFlags.
func (ms MetricDataPointFlagsStruct) String() string {
	return otlpmetrics.DataPointFlags(*ms.orig).String()
}

// MetricDataPointFlags defines how a metric aggregator reports aggregated values.
// It describes how those values relate to the time interval over which they are aggregated.
type MetricDataPointFlags uint32

const (
	// MetricDataPointFlagsNone is the default MetricDataPointFlags.
	MetricDataPointFlagsNone = MetricDataPointFlags(otlpmetrics.DataPointFlags_FLAG_NONE)
)

// NewMetricDataPointFlags returns a new MetricDataPointFlags combining the flags passed
// in as parameters.
func NewMetricDataPointFlags(flags ...MetricDataPointFlag) MetricDataPointFlags {
	var flag MetricDataPointFlags
	for _, f := range flags {
		flag |= MetricDataPointFlags(f)
	}
	return flag
}

// HasFlag returns true if the MetricDataPointFlags contains the specified flag
func (d MetricDataPointFlags) HasFlag(flag MetricDataPointFlag) bool {
	return d&MetricDataPointFlags(flag) != 0
}

// String returns the string representation of the MetricDataPointFlags.
func (d MetricDataPointFlags) String() string {
	return otlpmetrics.DataPointFlags(d).String()
}

// MetricDataPointFlag allow users to configure DataPointFlags. This is achieved via NewMetricDataPointFlags.
// The separation between MetricDataPointFlags and MetricDataPointFlag exists to prevent users accidentally
// comparing the value of individual flags with MetricDataPointFlags. Instead, users must use the HasFlag method.
type MetricDataPointFlag uint32

const (
	// MetricDataPointFlagNoRecordedValue is flag for a metric aggregator which reports changes since last report time.
	MetricDataPointFlagNoRecordedValue = MetricDataPointFlag(otlpmetrics.DataPointFlags_FLAG_NO_RECORDED_VALUE)
)

// NumberDataPointValueType specifies the type of NumberDataPoint value.
type NumberDataPointValueType int32

const (
	NumberDataPointValueTypeNone NumberDataPointValueType = iota
	NumberDataPointValueTypeInt
	NumberDataPointValueTypeDouble
)

// String returns the string representation of the NumberDataPointValueType.
func (nt NumberDataPointValueType) String() string {
	switch nt {
	case NumberDataPointValueTypeNone:
		return "None"
	case NumberDataPointValueTypeInt:
		return "Int"
	case NumberDataPointValueTypeDouble:
		return "Double"
	}
	return ""
}

// ExemplarValueType specifies the type of Exemplar measurement value.
type ExemplarValueType int32

const (
	ExemplarValueTypeNone ExemplarValueType = iota
	ExemplarValueTypeInt
	ExemplarValueTypeDouble
)

// String returns the string representation of the ExemplarValueType.
func (nt ExemplarValueType) String() string {
	switch nt {
	case ExemplarValueTypeNone:
		return "None"
	case ExemplarValueTypeInt:
		return "Int"
	case ExemplarValueTypeDouble:
		return "Double"
	}
	return ""
}

// OptionalType wraps optional fields into oneof fields
type OptionalType int32

const (
	OptionalTypeNone OptionalType = iota
	OptionalTypeDouble
)

// String returns the string representation of the OptionalType.
func (ot OptionalType) String() string {
	switch ot {
	case OptionalTypeNone:
		return "None"
	case OptionalTypeDouble:
		return "Double"
	}
	return ""
}

// Deprecated: [0.54.0] Use BucketCounts instead.
func (ms HistogramDataPoint) MBucketCounts() []uint64 {
	return ms.BucketCounts().AsRaw()
}

// Deprecated: [0.54.0] Use SetBucketCounts instead.
func (ms HistogramDataPoint) SetMBucketCounts(v []uint64) {
	ms.SetBucketCounts(NewImmutableUInt64Slice(v))
}

// Deprecated: [0.54.0] Use ExplicitBounds instead.
func (ms HistogramDataPoint) MExplicitBounds() []float64 {
	return ms.ExplicitBounds().AsRaw()
}

// Deprecated: [0.54.0] Use SetExplicitBounds instead.
func (ms HistogramDataPoint) SetMExplicitBounds(v []float64) {
	ms.SetExplicitBounds(NewImmutableFloat64Slice(v))
}

// Deprecated: [0.54.0] Use BucketCounts instead.
func (ms Buckets) MBucketCounts() []uint64 {
	return ms.BucketCounts().AsRaw()
}

// Deprecated: [0.54.0] Use SetBucketCounts instead.
func (ms Buckets) SetMBucketCounts(v []uint64) {
	ms.SetBucketCounts(NewImmutableUInt64Slice(v))
}
<commit_msg>Revert "Restore deprecated funcs still in use in third-party dependencies (#5786)" (#5797)<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 internal // import "go.opentelemetry.io/collector/pdata/internal"

import (
	otlpcollectormetrics "go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/metrics/v1"
	otlpmetrics "go.opentelemetry.io/collector/pdata/internal/data/protogen/metrics/v1"
)

// MetricsToOtlp internal helper to convert Metrics to otlp request representation.
func MetricsToOtlp(mw Metrics) *otlpcollectormetrics.ExportMetricsServiceRequest {
	return mw.orig
}

// MetricsFromOtlp internal helper to convert otlp request representation to Metrics.
func MetricsFromOtlp(orig *otlpcollectormetrics.ExportMetricsServiceRequest) Metrics {
	return Metrics{orig: orig}
}

// MetricsToProto internal helper to convert Metrics to protobuf representation.
func MetricsToProto(l Metrics) otlpmetrics.MetricsData {
	return otlpmetrics.MetricsData{
		ResourceMetrics: l.orig.ResourceMetrics,
	}
}

// MetricsFromProto internal helper to convert protobuf representation to Metrics.
func MetricsFromProto(orig otlpmetrics.MetricsData) Metrics {
	return Metrics{orig: &otlpcollectormetrics.ExportMetricsServiceRequest{
		ResourceMetrics: orig.ResourceMetrics,
	}}
}

// Metrics is the top-level struct that is propagated through the metrics pipeline.
// Use NewMetrics to create new instance, zero-initialized instance is not valid for use.
type Metrics struct {
	orig *otlpcollectormetrics.ExportMetricsServiceRequest
}

// NewMetrics creates a new Metrics struct.
func NewMetrics() Metrics {
	return Metrics{orig: &otlpcollectormetrics.ExportMetricsServiceRequest{}}
}

// Clone returns a copy of MetricData.
func (md Metrics) Clone() Metrics {
	cloneMd := NewMetrics()
	md.ResourceMetrics().CopyTo(cloneMd.ResourceMetrics())
	return cloneMd
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value.
func (md Metrics) MoveTo(dest Metrics) {
	*dest.orig = *md.orig
	*md.orig = otlpcollectormetrics.ExportMetricsServiceRequest{}
}

// ResourceMetrics returns the ResourceMetricsSlice associated with this Metrics.
func (md Metrics) ResourceMetrics() ResourceMetricsSlice {
	return newResourceMetricsSlice(&md.orig.ResourceMetrics)
}

// MetricCount calculates the total number of metrics.
func (md Metrics) MetricCount() int {
	metricCount := 0
	rms := md.ResourceMetrics()
	for i := 0; i < rms.Len(); i++ {
		rm := rms.At(i)
		ilms := rm.ScopeMetrics()
		for j := 0; j < ilms.Len(); j++ {
			ilm := ilms.At(j)
			metricCount += ilm.Metrics().Len()
		}
	}
	return metricCount
}

// DataPointCount calculates the total number of data points.
func (md Metrics) DataPointCount() (dataPointCount int) {
	rms := md.ResourceMetrics()
	for i := 0; i < rms.Len(); i++ {
		rm := rms.At(i)
		ilms := rm.ScopeMetrics()
		for j := 0; j < ilms.Len(); j++ {
			ilm := ilms.At(j)
			ms := ilm.Metrics()
			for k := 0; k < ms.Len(); k++ {
				m := ms.At(k)
				switch m.DataType() {
				case MetricDataTypeGauge:
					dataPointCount += m.Gauge().DataPoints().Len()
				case MetricDataTypeSum:
					dataPointCount += m.Sum().DataPoints().Len()
				case MetricDataTypeHistogram:
					dataPointCount += m.Histogram().DataPoints().Len()
				case MetricDataTypeExponentialHistogram:
					dataPointCount += m.ExponentialHistogram().DataPoints().Len()
				case MetricDataTypeSummary:
					dataPointCount += m.Summary().DataPoints().Len()
				}
			}
		}
	}
	return
}

// MetricDataType specifies the type of data in a Metric.
type MetricDataType int32

const (
	MetricDataTypeNone MetricDataType = iota
	MetricDataTypeGauge
	MetricDataTypeSum
	MetricDataTypeHistogram
	MetricDataTypeExponentialHistogram
	MetricDataTypeSummary
)

// String returns the string representation of the MetricDataType.
func (mdt MetricDataType) String() string {
	switch mdt {
	case MetricDataTypeNone:
		return "None"
	case MetricDataTypeGauge:
		return "Gauge"
	case MetricDataTypeSum:
		return "Sum"
	case MetricDataTypeHistogram:
		return "Histogram"
	case MetricDataTypeExponentialHistogram:
		return "ExponentialHistogram"
	case MetricDataTypeSummary:
		return "Summary"
	}
	return ""
}

// SetDataType clears any existing data and initialize it with an empty data of the given type.
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) SetDataType(ty MetricDataType) {
	switch ty {
	case MetricDataTypeGauge:
		ms.orig.Data = &otlpmetrics.Metric_Gauge{Gauge: &otlpmetrics.Gauge{}}
	case MetricDataTypeSum:
		ms.orig.Data = &otlpmetrics.Metric_Sum{Sum: &otlpmetrics.Sum{}}
	case MetricDataTypeHistogram:
		ms.orig.Data = &otlpmetrics.Metric_Histogram{Histogram: &otlpmetrics.Histogram{}}
	case MetricDataTypeExponentialHistogram:
		ms.orig.Data = &otlpmetrics.Metric_ExponentialHistogram{ExponentialHistogram: &otlpmetrics.ExponentialHistogram{}}
	case MetricDataTypeSummary:
		ms.orig.Data = &otlpmetrics.Metric_Summary{Summary: &otlpmetrics.Summary{}}
	}
}

// MetricAggregationTemporality defines how a metric aggregator reports aggregated values.
// It describes how those values relate to the time interval over which they are aggregated.
type MetricAggregationTemporality int32

const (
	// MetricAggregationTemporalityUnspecified is the default MetricAggregationTemporality, it MUST NOT be used.
	MetricAggregationTemporalityUnspecified = MetricAggregationTemporality(otlpmetrics.AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED)
	// MetricAggregationTemporalityDelta is a MetricAggregationTemporality for a metric aggregator which reports changes since last report time.
	MetricAggregationTemporalityDelta = MetricAggregationTemporality(otlpmetrics.AggregationTemporality_AGGREGATION_TEMPORALITY_DELTA)
	// MetricAggregationTemporalityCumulative is a MetricAggregationTemporality for a metric aggregator which reports changes since a fixed start time.
	MetricAggregationTemporalityCumulative = MetricAggregationTemporality(otlpmetrics.AggregationTemporality_AGGREGATION_TEMPORALITY_CUMULATIVE)
)

// String returns the string representation of the MetricAggregationTemporality.
func (at MetricAggregationTemporality) String() string {
	return otlpmetrics.AggregationTemporality(at).String()
}

// Flags returns the flags associated with this NumberDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms NumberDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.orig.Flags)
}

// SetFlags replaces the flags associated with this NumberDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms NumberDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.orig.Flags = uint32(v)
}

// Flags returns the flags associated with this HistogramDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms HistogramDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.orig.Flags)
}

// SetFlags replaces the flags associated with this HistogramDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms HistogramDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.orig.Flags = uint32(v)
}

// Flags returns the flags associated with this ExponentialHistogramDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms ExponentialHistogramDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.orig.Flags)
}

// SetFlags replaces the flags associated with this ExponentialHistogramDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms ExponentialHistogramDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.orig.Flags = uint32(v)
}

// Flags returns the flags associated with this SummaryDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms SummaryDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.orig.Flags)
}

// SetFlags replaces the flags associated with this SummaryDataPoint.
// Deprecated: [v0.57.0] Use FlagsStruct instead.
func (ms SummaryDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.orig.Flags = uint32(v)
}

// MetricDataPointFlagsStruct defines how a metric aggregator reports aggregated values.
// It describes how those values relate to the time interval over which they are aggregated.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewMetricDataPointFlagsStruct function to create new instances.
// Important: zero-initialized instance is not valid for use.
type MetricDataPointFlagsStruct struct {
	orig *uint32
}

func newMetricDataPointFlagsStruct(orig *uint32) MetricDataPointFlagsStruct {
	return MetricDataPointFlagsStruct{orig: orig}
}

// NewMetricDataPointFlagsStruct creates a new empty MetricDataPointFlagsStruct.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewMetricDataPointFlagsStruct() MetricDataPointFlagsStruct {
	return newMetricDataPointFlagsStruct(new(uint32))
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms MetricDataPointFlagsStruct) MoveTo(dest MetricDataPointFlagsStruct) {
	*dest.orig = *ms.orig
	*ms.orig = uint32(otlpmetrics.DataPointFlags_FLAG_NONE)
}

// CopyTo copies all properties from the current struct to the dest.
func (ms MetricDataPointFlagsStruct) CopyTo(dest MetricDataPointFlagsStruct) {
	*dest.orig = *ms.orig
}

// NoRecordedValue returns true if the MetricDataPointFlags contains the NO_RECORDED_VALUE flag.
func (ms MetricDataPointFlagsStruct) NoRecordedValue() bool {
	return *ms.orig&uint32(otlpmetrics.DataPointFlags_FLAG_NO_RECORDED_VALUE) != 0
}

// SetNoRecordedValue sets the FLAG_NO_RECORDED_VALUE flag if true and removes it if false.
// Setting this Flag when it is already set will change nothing.
func (ms MetricDataPointFlagsStruct) SetNoRecordedValue(b bool) {
	if b {
		*ms.orig |= uint32(otlpmetrics.DataPointFlags_FLAG_NO_RECORDED_VALUE)
	} else {
		*ms.orig &^= uint32(otlpmetrics.DataPointFlags_FLAG_NO_RECORDED_VALUE)
	}
}

// String returns the string representation of the MetricDataPointFlags.
func (ms MetricDataPointFlagsStruct) String() string {
	return otlpmetrics.DataPointFlags(*ms.orig).String()
}

// MetricDataPointFlags defines how a metric aggregator reports aggregated values.
// It describes how those values relate to the time interval over which they are aggregated.
type MetricDataPointFlags uint32

const (
	// MetricDataPointFlagsNone is the default MetricDataPointFlags.
	MetricDataPointFlagsNone = MetricDataPointFlags(otlpmetrics.DataPointFlags_FLAG_NONE)
)

// NewMetricDataPointFlags returns a new MetricDataPointFlags combining the flags passed
// in as parameters.
func NewMetricDataPointFlags(flags ...MetricDataPointFlag) MetricDataPointFlags {
	var flag MetricDataPointFlags
	for _, f := range flags {
		flag |= MetricDataPointFlags(f)
	}
	return flag
}

// HasFlag returns true if the MetricDataPointFlags contains the specified flag
func (d MetricDataPointFlags) HasFlag(flag MetricDataPointFlag) bool {
	return d&MetricDataPointFlags(flag) != 0
}

// String returns the string representation of the MetricDataPointFlags.
func (d MetricDataPointFlags) String() string {
	return otlpmetrics.DataPointFlags(d).String()
}

// MetricDataPointFlag allow users to configure DataPointFlags. This is achieved via NewMetricDataPointFlags.
// The separation between MetricDataPointFlags and MetricDataPointFlag exists to prevent users accidentally
// comparing the value of individual flags with MetricDataPointFlags. Instead, users must use the HasFlag method.
type MetricDataPointFlag uint32

const (
	// MetricDataPointFlagNoRecordedValue is flag for a metric aggregator which reports changes since last report time.
	MetricDataPointFlagNoRecordedValue = MetricDataPointFlag(otlpmetrics.DataPointFlags_FLAG_NO_RECORDED_VALUE)
)

// NumberDataPointValueType specifies the type of NumberDataPoint value.
type NumberDataPointValueType int32

const (
	NumberDataPointValueTypeNone NumberDataPointValueType = iota
	NumberDataPointValueTypeInt
	NumberDataPointValueTypeDouble
)

// String returns the string representation of the NumberDataPointValueType.
func (nt NumberDataPointValueType) String() string {
	switch nt {
	case NumberDataPointValueTypeNone:
		return "None"
	case NumberDataPointValueTypeInt:
		return "Int"
	case NumberDataPointValueTypeDouble:
		return "Double"
	}
	return ""
}

// ExemplarValueType specifies the type of Exemplar measurement value.
type ExemplarValueType int32

const (
	ExemplarValueTypeNone ExemplarValueType = iota
	ExemplarValueTypeInt
	ExemplarValueTypeDouble
)

// String returns the string representation of the ExemplarValueType.
func (nt ExemplarValueType) String() string {
	switch nt {
	case ExemplarValueTypeNone:
		return "None"
	case ExemplarValueTypeInt:
		return "Int"
	case ExemplarValueTypeDouble:
		return "Double"
	}
	return ""
}

// OptionalType wraps optional fields into oneof fields
type OptionalType int32

const (
	OptionalTypeNone OptionalType = iota
	OptionalTypeDouble
)

// String returns the string representation of the OptionalType.
func (ot OptionalType) String() string {
	switch ot {
	case OptionalTypeNone:
		return "None"
	case OptionalTypeDouble:
		return "Double"
	}
	return ""
}
<|endoftext|>