<commit_before>// +build !goji_router_simple

package goji

import (
	"net/http"
	"sort"
	"strings"

	"goji.io/internal"
	"golang.org/x/net/context"
)

type router struct {
	routes   []route
	methods  map[string]*trieNode
	wildcard trieNode
}

type route struct {
	Pattern
	Handler
}

type child struct {
	prefix string
	node   *trieNode
}

type trieNode struct {
	routes   []int
	children []child
}

func (rt *router) add(p Pattern, h Handler) {
	i := len(rt.routes)
	rt.routes = append(rt.routes, route{p, h})

	var prefix string
	if pp, ok := p.(pathPrefix); ok {
		prefix = pp.PathPrefix()
	}

	var methods map[string]struct{}
	if hm, ok := p.(httpMethods); ok {
		methods = hm.HTTPMethods()
	}
	if methods == nil {
		rt.wildcard.add(prefix, i)
		for _, sub := range rt.methods {
			sub.add(prefix, i)
		}
	} else {
		if rt.methods == nil {
			rt.methods = make(map[string]*trieNode)
		}

		for method := range methods {
			if _, ok := rt.methods[method]; !ok {
				rt.methods[method] = rt.wildcard.clone()
			}
			rt.methods[method].add(prefix, i)
		}
	}
}

func (rt *router) route(ctx context.Context, r *http.Request) context.Context {
	tn := &rt.wildcard
	if tn2, ok := rt.methods[r.Method]; ok {
		tn = tn2
	}

	path := ctx.Value(internal.Path).(string)
	for {
		i := sort.Search(len(tn.children), func(i int) bool {
			p := tn.children[i].prefix
			return path < p || strings.HasPrefix(path, p)
		})
		if i == len(tn.children) || !strings.HasPrefix(path, tn.children[i].prefix) {
			break
		}

		path = path[len(tn.children[i].prefix):]
		tn = tn.children[i].node
	}
	for _, i := range tn.routes {
		if ctx := rt.routes[i].Match(ctx, r); ctx != nil {
			return &match{ctx, rt.routes[i].Pattern, rt.routes[i].Handler}
		}
	}
	return &match{Context: ctx}
}

// We can be a teensy bit more efficient here: we're maintaining a sorted list,
// so we know exactly where to insert the new element. But since that involves
// more bookkeeping and makes the code messier, let's cross that bridge when we
// come to it.
type byPrefix []child

func (b byPrefix) Len() int {
	return len(b)
}
func (b byPrefix) Less(i, j int) bool {
	return b[i].prefix < b[j].prefix
}
func (b byPrefix) Swap(i, j int) {
	b[i], b[j] = b[j], b[i]
}

func longestPrefix(a, b string) string {
	mlen := len(a)
	if len(b) < mlen {
		mlen = len(b)
	}
	for i := 0; i < mlen; i++ {
		if a[i] != b[i] {
			return a[:i]
		}
	}
	return a[:mlen]
}

func (tn *trieNode) add(prefix string, idx int) {
	if len(prefix) == 0 {
		tn.routes = append(tn.routes, idx)
		for i := range tn.children {
			tn.children[i].node.add(prefix, idx)
		}
		return
	}

	ch := prefix[0]
	i := sort.Search(len(tn.children), func(i int) bool {
		return ch <= tn.children[i].prefix[0]
	})

	for ; i < len(tn.children); i++ {
		if tn.children[i].prefix[0] > ch {
			break
		}

		lp := longestPrefix(prefix, tn.children[i].prefix)

		if tn.children[i].prefix == lp {
			tn.children[i].node.add(prefix[len(lp):], idx)
			return
		}

		split := new(trieNode)
		split.children = []child{
			{tn.children[i].prefix[len(lp):], tn.children[i].node},
		}
		split.routes = append([]int(nil), tn.routes...)
		split.add(prefix[len(lp):], idx)

		tn.children[i].prefix = lp
		tn.children[i].node = split
		sort.Sort(byPrefix(tn.children))
		return
	}

	routes := append([]int(nil), tn.routes...)
	tn.children = append(tn.children, child{
		prefix: prefix,
		node:   &trieNode{routes: append(routes, idx)},
	})
	sort.Sort(byPrefix(tn.children))
}

func (tn *trieNode) clone() *trieNode {
	clone := new(trieNode)
	clone.routes = append(clone.routes, tn.routes...)
	clone.children = append(clone.children, tn.children...)
	for i := range clone.children {
		clone.children[i].node = tn.children[i].node.clone()
	}
	return clone
}
<commit_msg>goji: work less when searching for trie children<commit_after>// +build !goji_router_simple

package goji

import (
	"net/http"
	"sort"
	"strings"

	"goji.io/internal"
	"golang.org/x/net/context"
)

type router struct {
	routes   []route
	methods  map[string]*trieNode
	wildcard trieNode
}

type route struct {
	Pattern
	Handler
}

type child struct {
	prefix string
	node   *trieNode
}

type trieNode struct {
	routes   []int
	children []child
}

func (rt *router) add(p Pattern, h Handler) {
	i := len(rt.routes)
	rt.routes = append(rt.routes, route{p, h})

	var prefix string
	if pp, ok := p.(pathPrefix); ok {
		prefix = pp.PathPrefix()
	}

	var methods map[string]struct{}
	if hm, ok := p.(httpMethods); ok {
		methods = hm.HTTPMethods()
	}
	if methods == nil {
		rt.wildcard.add(prefix, i)
		for _, sub := range rt.methods {
			sub.add(prefix, i)
		}
	} else {
		if rt.methods == nil {
			rt.methods = make(map[string]*trieNode)
		}

		for method := range methods {
			if _, ok := rt.methods[method]; !ok {
				rt.methods[method] = rt.wildcard.clone()
			}
			rt.methods[method].add(prefix, i)
		}
	}
}

func (rt *router) route(ctx context.Context, r *http.Request) context.Context {
	tn := &rt.wildcard
	if tn2, ok := rt.methods[r.Method]; ok {
		tn = tn2
	}

	path := ctx.Value(internal.Path).(string)
	for path != "" {
		i := sort.Search(len(tn.children), func(i int) bool {
			return path[0] <= tn.children[i].prefix[0]
		})
		if i == len(tn.children) || !strings.HasPrefix(path, tn.children[i].prefix) {
			break
		}

		path = path[len(tn.children[i].prefix):]
		tn = tn.children[i].node
	}
	for _, i := range tn.routes {
		if ctx := rt.routes[i].Match(ctx, r); ctx != nil {
			return &match{ctx, rt.routes[i].Pattern, rt.routes[i].Handler}
		}
	}
	return &match{Context: ctx}
}

// We can be a teensy bit more efficient here: we're maintaining a sorted list,
// so we know exactly where to insert the new element. But since that involves
// more bookkeeping and makes the code messier, let's cross that bridge when we
// come to it.
type byPrefix []child

func (b byPrefix) Len() int {
	return len(b)
}
func (b byPrefix) Less(i, j int) bool {
	return b[i].prefix < b[j].prefix
}
func (b byPrefix) Swap(i, j int) {
	b[i], b[j] = b[j], b[i]
}

func longestPrefix(a, b string) string {
	mlen := len(a)
	if len(b) < mlen {
		mlen = len(b)
	}
	for i := 0; i < mlen; i++ {
		if a[i] != b[i] {
			return a[:i]
		}
	}
	return a[:mlen]
}

func (tn *trieNode) add(prefix string, idx int) {
	if len(prefix) == 0 {
		tn.routes = append(tn.routes, idx)
		for i := range tn.children {
			tn.children[i].node.add(prefix, idx)
		}
		return
	}

	ch := prefix[0]
	i := sort.Search(len(tn.children), func(i int) bool {
		return ch <= tn.children[i].prefix[0]
	})

	for ; i < len(tn.children); i++ {
		if tn.children[i].prefix[0] > ch {
			break
		}

		lp := longestPrefix(prefix, tn.children[i].prefix)

		if tn.children[i].prefix == lp {
			tn.children[i].node.add(prefix[len(lp):], idx)
			return
		}

		split := new(trieNode)
		split.children = []child{
			{tn.children[i].prefix[len(lp):], tn.children[i].node},
		}
		split.routes = append([]int(nil), tn.routes...)
		split.add(prefix[len(lp):], idx)

		tn.children[i].prefix = lp
		tn.children[i].node = split
		sort.Sort(byPrefix(tn.children))
		return
	}

	routes := append([]int(nil), tn.routes...)
	tn.children = append(tn.children, child{
		prefix: prefix,
		node:   &trieNode{routes: append(routes, idx)},
	})
	sort.Sort(byPrefix(tn.children))
}

func (tn *trieNode) clone() *trieNode {
	clone := new(trieNode)
	clone.routes = append(clone.routes, tn.routes...)
	clone.children = append(clone.children, tn.children...)
	for i := range clone.children {
		clone.children[i].node = tn.children[i].node.clone()
	}
	return clone
}
<|endoftext|>


<commit_before>package gructl

import (
	"os"
	"time"

	"github.com/dnaeon/gru/gructl/command"
	"github.com/dnaeon/gru/version"
	"github.com/urfave/cli"
)

// Main is the entry point of gructl
func Main() {
	app := cli.NewApp()
	app.Name = "gructl"
	app.Version = version.Version
	app.Usage = "command line tool for managing minions"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "endpoint",
			Value:  "http://127.0.0.1:2379,http://localhost:4001",
			Usage:  "etcd cluster endpoints",
			EnvVar: "GRU_ENDPOINT",
		},
		cli.StringFlag{
			Name:   "username",
			Value:  "",
			Usage:  "username to use for authentication",
			EnvVar: "GRU_USERNAME",
		},
		cli.StringFlag{
			Name:   "password",
			Value:  "",
			Usage:  "password to use for authentication",
			EnvVar: "GRU_PASSWORD",
		},
		cli.DurationFlag{
			Name:   "timeout",
			Value:  time.Second,
			Usage:  "connection timeout per request",
			EnvVar: "GRU_TIMEOUT",
		},
	}

	app.Commands = []cli.Command{
		command.NewApplyCommand(),
		command.NewListCommand(),
		command.NewInfoCommand(),
		command.NewServeCommand(),
		command.NewPushCommand(),
		command.NewClassifierCommand(),
		command.NewReportCommand(),
		command.NewQueueCommand(),
		command.NewLogCommand(),
		command.NewLastseenCommand(),
		command.NewResultCommand(),
		command.NewGraphCommand(),
	}

	app.Run(os.Args)
}
<commit_msg>gructl: enable bash completions<commit_after>package gructl

import (
	"os"
	"time"

	"github.com/dnaeon/gru/gructl/command"
	"github.com/dnaeon/gru/version"
	"github.com/urfave/cli"
)

// Main is the entry point of gructl
func Main() {
	app := cli.NewApp()
	app.Name = "gructl"
	app.Version = version.Version
	app.EnableBashCompletion = true
	app.Usage = "command line tool for managing minions"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "endpoint",
			Value:  "http://127.0.0.1:2379,http://localhost:4001",
			Usage:  "etcd cluster endpoints",
			EnvVar: "GRU_ENDPOINT",
		},
		cli.StringFlag{
			Name:   "username",
			Value:  "",
			Usage:  "username to use for authentication",
			EnvVar: "GRU_USERNAME",
		},
		cli.StringFlag{
			Name:   "password",
			Value:  "",
			Usage:  "password to use for authentication",
			EnvVar: "GRU_PASSWORD",
		},
		cli.DurationFlag{
			Name:   "timeout",
			Value:  time.Second,
			Usage:  "connection timeout per request",
			EnvVar: "GRU_TIMEOUT",
		},
	}

	app.Commands = []cli.Command{
		command.NewApplyCommand(),
		command.NewListCommand(),
		command.NewInfoCommand(),
		command.NewServeCommand(),
		command.NewPushCommand(),
		command.NewClassifierCommand(),
		command.NewReportCommand(),
		command.NewQueueCommand(),
		command.NewLogCommand(),
		command.NewLastseenCommand(),
		command.NewResultCommand(),
		command.NewGraphCommand(),
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package api

import (
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/dgrijalva/jwt-go"
	"github.com/gorilla/mux"
)

const (
	tokenName = "AccessToken"
)

var (
	verifyKey, signKey    []byte
	errWhileSigningToken  = errors.New("error while signing token")
	errPleaseLogIn        = errors.New("please log in")
	errWhileParsingCookie = errors.New("error while parsing cookie")
	errTokenExpired       = errors.New("token expired")
	errGenericError       = errors.New("generic error")
	errAccessDenied       = errors.New("insufficient privileges")
)

func SetupCerts(p string) error {
	var err error
	if err != nil {
		log.Fatalf("Path error: ", err)
	}

	// openssl genrsa -out app.rsa keysize
	privKeyPath := fmt.Sprintf("%vapp.rsa", p)
	signKey, err = ioutil.ReadFile(privKeyPath)
	if err != nil {
		log.Fatalf("Error reading private key: ", err)
		return err
	}

	// openssl rsa -in app.rsa -pubout > app.rsa.pub
	pubKeyPath := fmt.Sprintf("%vapp.rsa.pub", p)
	verifyKey, err = ioutil.ReadFile(pubKeyPath)
	if err != nil {
		log.Fatalf("Error reading public key: ", err)
		return err
	}
	return nil
}

type authHandler func(http.ResponseWriter, *http.Request) error

// Only accessible with a valid token
func (h authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// Even though writeJSON sets the content type, we need to set it here because
	// calls to WriteHeader write out the entire header.
	w.Header().Set("content-type", "application/json; charset=utf-8")
	tokenCookie, err := r.Cookie(tokenName)
	switch {
	case err == http.ErrNoCookie:
		w.WriteHeader(http.StatusUnauthorized)
		writeJSON(w, Error{errPleaseLogIn})
		return
	case err != nil:
		w.WriteHeader(http.StatusInternalServerError)
		writeJSON(w, Error{errWhileParsingCookie})
		return
	}

	if tokenCookie.Value == "" {
		w.WriteHeader(http.StatusUnauthorized)
		writeJSON(w, Error{errPleaseLogIn})
		return
	}

	// Validate the token
	token, err := jwt.Parse(tokenCookie.Value, func(token *jwt.Token) (interface{}, error) {
		return verifyKey, nil
	})

	// Branch out into the possible error from signing
	switch err.(type) {
	case nil: // No error
		if !token.Valid { // But may still be invalid
			w.WriteHeader(http.StatusUnauthorized)
			writeJSON(w, Error{errPleaseLogIn})
			return
		}
	case *jwt.ValidationError: // Something was wrong during the validation
		vErr := err.(*jwt.ValidationError)
		switch vErr.Errors {
		case jwt.ValidationErrorExpired:
			w.WriteHeader(http.StatusUnauthorized)
			writeJSON(w, Error{errTokenExpired})
			return
		default:
			w.WriteHeader(http.StatusInternalServerError)
			writeJSON(w, Error{errGenericError})
			return
		}
	default: // Something else went wrong
		w.WriteHeader(http.StatusInternalServerError)
		writeJSON(w, Error{errGenericError})
		return
	}
	if mux.Vars(r)["genus"] != token.Claims["genus"] {
		w.WriteHeader(http.StatusInternalServerError)
		writeJSON(w, Error{errAccessDenied})
		return
	}
	hErr := h(w, r)
	if hErr != nil {
		w.WriteHeader(http.StatusInternalServerError)
		writeJSON(w, Error{hErr})
	}
}
<commit_msg>Oops — don’t worry about genus for non soubrettes.<commit_after>package api

import (
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/dgrijalva/jwt-go"
	"github.com/gorilla/mux"
)

const (
	tokenName = "AccessToken"
)

var (
	verifyKey, signKey    []byte
	errWhileSigningToken  = errors.New("error while signing token")
	errPleaseLogIn        = errors.New("please log in")
	errWhileParsingCookie = errors.New("error while parsing cookie")
	errTokenExpired       = errors.New("token expired")
	errGenericError       = errors.New("generic error")
	errAccessDenied       = errors.New("insufficient privileges")
)

func SetupCerts(p string) error {
	var err error
	if err != nil {
		log.Fatalf("Path error: ", err)
	}

	// openssl genrsa -out app.rsa keysize
	privKeyPath := fmt.Sprintf("%vapp.rsa", p)
	signKey, err = ioutil.ReadFile(privKeyPath)
	if err != nil {
		log.Fatalf("Error reading private key: ", err)
		return err
	}

	// openssl rsa -in app.rsa -pubout > app.rsa.pub
	pubKeyPath := fmt.Sprintf("%vapp.rsa.pub", p)
	verifyKey, err = ioutil.ReadFile(pubKeyPath)
	if err != nil {
		log.Fatalf("Error reading public key: ", err)
		return err
	}
	return nil
}

type authHandler func(http.ResponseWriter, *http.Request) error

// Only accessible with a valid token
func (h authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// Even though writeJSON sets the content type, we need to set it here because
	// calls to WriteHeader write out the entire header.
	w.Header().Set("content-type", "application/json; charset=utf-8")
	tokenCookie, err := r.Cookie(tokenName)
	switch {
	case err == http.ErrNoCookie:
		w.WriteHeader(http.StatusUnauthorized)
		writeJSON(w, Error{errPleaseLogIn})
		return
	case err != nil:
		w.WriteHeader(http.StatusInternalServerError)
		writeJSON(w, Error{errWhileParsingCookie})
		return
	}

	if tokenCookie.Value == "" {
		w.WriteHeader(http.StatusUnauthorized)
		writeJSON(w, Error{errPleaseLogIn})
		return
	}

	// Validate the token
	token, err := jwt.Parse(tokenCookie.Value, func(token *jwt.Token) (interface{}, error) {
		return verifyKey, nil
	})

	// Branch out into the possible error from signing
	switch err.(type) {
	case nil: // No error
		if !token.Valid { // But may still be invalid
			w.WriteHeader(http.StatusUnauthorized)
			writeJSON(w, Error{errPleaseLogIn})
			return
		}
	case *jwt.ValidationError: // Something was wrong during the validation
		vErr := err.(*jwt.ValidationError)
		switch vErr.Errors {
		case jwt.ValidationErrorExpired:
			w.WriteHeader(http.StatusUnauthorized)
			writeJSON(w, Error{errTokenExpired})
			return
		default:
			w.WriteHeader(http.StatusInternalServerError)
			writeJSON(w, Error{errGenericError})
			return
		}
	default: // Something else went wrong
		w.WriteHeader(http.StatusInternalServerError)
		writeJSON(w, Error{errGenericError})
		return
	}
	genus := mux.Vars(r)["genus"]
	// We don't care about this if we aren't accessing one of the subrouter routes.
	if genus != "" && genus != token.Claims["genus"] {
		w.WriteHeader(http.StatusInternalServerError)
		writeJSON(w, Error{errAccessDenied})
		return
	}
	hErr := h(w, r)
	if hErr != nil {
		w.WriteHeader(http.StatusInternalServerError)
		writeJSON(w, Error{hErr})
	}
}
<|endoftext|>


<commit_before>package api

import (
	"encoding/base64"
	"log"
	"net/url"
	"path"
	"strings"

	"github.com/ondevice/ondevice/config"
)

// Authentication -- authentication and other API options)
type Authentication struct {
	user      string
	auth      string
	apiServer string
}

// GetAuthHeader -- Return the value of the HTTP Basic Authentication header
func (a Authentication) GetAuthHeader() string {
	token := a.user + ":" + a.auth
	return "Basic " + base64.StdEncoding.EncodeToString([]byte(token))
}

// GetURL -- Get the full API server URL for the apiServer we store internally and the params we get
func (a Authentication) GetURL(endpoint string, params map[string]string, scheme string) string {
	server := a.apiServer

	if server == "" {
		server = "https://api.ondevice.io/"
		//server = "http://localhost:8080/"
	}

	u, err := url.Parse(server)
	if err != nil {
		log.Fatal("URL parsing error: ", err)
	}

	if strings.HasPrefix(endpoint, "/") {
		endpoint = endpoint[1:]
	}
	u.Path = path.Join("/v1.1", endpoint)

	// parse query params
	query := url.Values{}
	for k, v := range params {
		query.Add(k, v)
	}
	u.RawQuery = query.Encode()

	// use ws:// if the API server URL was http:// (for local testing)
	if u.Scheme == "http" && scheme == "wss" {
		u.Scheme = "ws"
	} else {
		u.Scheme = scheme
	}

	return u.String()
}

// CreateAuth -- Create Authentication object
func CreateAuth(user string, auth string) Authentication {
	return Authentication{
		user: user,
		auth: auth,
	}
}

// CreateClientAuth -- Create default authentication
func CreateClientAuth() (Authentication, error) {
	user, auth, err := config.GetClientAuth()
	if err != nil {
		return Authentication{}, err
	}
	return CreateAuth(user, auth), nil
}
<commit_msg>Authentication: added CreateDeviceAuth() and SetServerURL()<commit_after>package api

import (
	"encoding/base64"
	"log"
	"net/url"
	"path"
	"strings"

	"github.com/ondevice/ondevice/config"
)

// Authentication -- authentication and other API options)
type Authentication struct {
	user      string
	auth      string
	apiServer string
}

// GetAuthHeader -- Return the value of the HTTP Basic Authentication header
func (a Authentication) GetAuthHeader() string {
	token := a.user + ":" + a.auth
	return "Basic " + base64.StdEncoding.EncodeToString([]byte(token))
}

// GetURL -- Get the full API server URL for the apiServer we store internally and the params we get
func (a Authentication) GetURL(endpoint string, params map[string]string, scheme string) string {
	server := a.apiServer

	if server == "" {
		server = "https://api.ondevice.io/"
		//server = "http://localhost:8080/"
	}

	u, err := url.Parse(server)
	if err != nil {
		log.Fatal("URL parsing error: ", err)
	}

	if strings.HasPrefix(endpoint, "/") {
		endpoint = endpoint[1:]
	}
	u.Path = path.Join("/v1.1", endpoint)

	// parse query params
	query := url.Values{}
	for k, v := range params {
		query.Add(k, v)
	}
	u.RawQuery = query.Encode()

	// use ws:// if the API server URL was http:// (for local testing)
	if u.Scheme == "http" && scheme == "wss" {
		u.Scheme = "ws"
	} else {
		u.Scheme = scheme
	}

	return u.String()
}

// SetServerURL -- Set the API server's URL (used by GetURL(), necessary to use the correct API server in tunnel.Accept())
func (a *Authentication) SetServerURL(apiServer string) {
	a.apiServer = apiServer
}

// CreateAuth -- Create Authentication object
func CreateAuth(user string, auth string) Authentication {
	return Authentication{
		user: user,
		auth: auth,
	}
}

// CreateClientAuth -- Create default authentication
func CreateClientAuth() (Authentication, error) {
	user, auth, err := config.GetClientAuth()
	if err != nil {
		return Authentication{}, err
	}
	return CreateAuth(user, auth), nil
}

// CreateDeviceAuth -- Create default device authentication
func CreateDeviceAuth() (Authentication, error) {
	user, auth, err := config.GetDeviceAuth()
	if err != nil {
		return Authentication{}, err
	}
	return CreateAuth(user, auth), nil
}
<|endoftext|>


<commit_before>/* implement iterator pattern */

package main

import "fmt"

type Iterator interface {
	hasNext() bool
	next() interface{}
}

func NewBookShelfIterator(this *BookShelf) *BookShelfIterator {
	FIRST_ITEM := 0
	return &BookShelfIterator{this, FIRST_ITEM}
}

type BookShelfIterator struct {
	bookshelf *BookShelf
	index     int
}

func (bsi *BookShelfIterator) hasNext() bool {
	return bsi.index < bsi.bookshelf.last
}

func (bsi *BookShelfIterator) next() interface{} {
	if bsi.index >= bsi.bookshelf.last {
		return nil
	}
	book := bsi.bookshelf.BookAt(bsi.index)
	bsi.index += 1
	return book

}

type Aggregate interface {
	iterator() *Iterator
}

// bookshelf : iteratable
type BookShelf struct {
	books []Book
	last  int
}

func (bs *BookShelf) BookAt(n int) Book {
	return bs.books[n]
}

func (bs *BookShelf) AppendBook(b Book) {
	bs.books = append(bs.books, b)
	bs.last += 1
}

func (bs *BookShelf) Volumes() int {
	return len(bs.books)
}

func (bs *BookShelf) Iterator() Iterator {
	return NewBookShelfIterator(bs)
}

// represent book
type Book struct {
	name string
}

func (book *Book) Name() string {
	return book.name
}

func main() {
	books := []Book{
		Book{"foo"},
		Book{"bar"},
		Book{"hoge"},
		Book{"fuga"},
		Book{"weeeei"},
	}
	bs := &BookShelf{books, len(books)}
	bs.AppendBook(Book{"appended book"})
	bsi := bs.Iterator()
	// pattern 1
	var book Book
	for bsi.hasNext() {
		book = bsi.next().(Book)
		fmt.Printf("%#v\n", book)
	}
	// pattern 2
	//for book = bsi.next(); book != nil; book = bsi.next() {
	//	fmt.Printf("%#v\n", book)
	//}
	fmt.Printf("Volumes: %#d\n", bs.Volumes())
}
<commit_msg>Fix invalid syntax.<commit_after>/* implement iterator pattern */

package main

import "fmt"

type Iterator interface {
	hasNext() bool
	next() interface{}
}

func NewBookShelfIterator(this *BookShelf) *BookShelfIterator {
	FIRST_ITEM := 0
	return &BookShelfIterator{this, FIRST_ITEM}
}

type BookShelfIterator struct {
	bookshelf *BookShelf
	index     int
}

func (bsi *BookShelfIterator) hasNext() bool {
	return bsi.index < bsi.bookshelf.last
}

func (bsi *BookShelfIterator) next() interface{} {
	if bsi.index >= bsi.bookshelf.last {
		return nil
	}
	book := bsi.bookshelf.BookAt(bsi.index)
	bsi.index += 1
	return book

}

type Aggregate interface {
	iterator() *Iterator
}

// bookshelf : iteratable
type BookShelf struct {
	books []Book
	last  int
}

func (bs *BookShelf) BookAt(n int) Book {
	return bs.books[n]
}

func (bs *BookShelf) AppendBook(b Book) {
	bs.books = append(bs.books, b)
	bs.last += 1
}

func (bs *BookShelf) Volumes() int {
	return len(bs.books)
}

func (bs *BookShelf) Iterator() Iterator {
	return NewBookShelfIterator(bs)
}

// represent book
type Book struct {
	name string
}

func (book *Book) Name() string {
	return book.name
}

func main() {
	books := []Book{
		Book{"foo"},
		Book{"bar"},
		Book{"hoge"},
		Book{"fuga"},
		Book{"weeeei"},
	}
	bs := &BookShelf{books, len(books)}
	bs.AppendBook(Book{"appended book"})
	bsi := bs.Iterator()
	// pattern 1
	var book Book
	for bsi.hasNext() {
		book = bsi.next().(Book)
		fmt.Printf("%#v\n", book)
	}
	// pattern 2
	//for book = bsi.next(); book != nil; book = bsi.next() {
	//	fmt.Printf("%#v\n", book)
	//}
	fmt.Printf("Volumes: %#v\n", bs.Volumes())
}
<|endoftext|>


<commit_before>// Copyright 2016 The Linux Foundation
//
// 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 image

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/opencontainers/image-spec/schema"
	"github.com/opencontainers/image-spec/specs-go/v1"
	"github.com/opencontainers/runtime-spec/specs-go"
	"github.com/pkg/errors"
)

type config v1.Image

func findConfig(w walker, d *descriptor) (*config, error) {
	var c config
	cpath := filepath.Join("blobs", d.algo(), d.hash())

	switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
		if info.IsDir() || filepath.Clean(path) != cpath {
			return nil
		}
		buf, err := ioutil.ReadAll(r)
		if err != nil {
			return errors.Wrapf(err, "%s: error reading config", path)
		}

		if err := schema.MediaTypeImageConfig.Validate(bytes.NewReader(buf)); err != nil {
			return errors.Wrapf(err, "%s: config validation failed", path)
		}

		if err := json.Unmarshal(buf, &c); err != nil {
			return err
		}
		// check if the rootfs type is 'layers'
		if c.RootFS.Type != "layers" {
			return fmt.Errorf("'%s' is an unknown rootfs type, MUST be 'layers'", c.RootFS.Type)
		}
		return errEOW
	}); err {
	case nil:
		return nil, fmt.Errorf("%s: config not found", cpath)
	case errEOW:
		return &c, nil
	default:
		return nil, err
	}
}

func (c *config) runtimeSpec(rootfs string) (*specs.Spec, error) {
	if c.OS != "linux" {
		return nil, fmt.Errorf("%s: unsupported OS", c.OS)
	}

	var s specs.Spec
	s.Version = specs.Version
	// we should at least apply the default spec, otherwise this is totally useless
	s.Process.Terminal = true
	s.Root.Path = rootfs
	s.Process.Cwd = "/"
	if c.Config.WorkingDir != "" {
		s.Process.Cwd = c.Config.WorkingDir
	}
	s.Process.Env = append(s.Process.Env, c.Config.Env...)
	s.Process.Args = append(s.Process.Args, c.Config.Entrypoint...)
	s.Process.Args = append(s.Process.Args, c.Config.Cmd...)

	if len(s.Process.Args) == 0 {
		s.Process.Args = append(s.Process.Args, "sh")
	}

	if uid, err := strconv.Atoi(c.Config.User); err == nil {
		s.Process.User.UID = uint32(uid)
	} else if ug := strings.Split(c.Config.User, ":"); len(ug) == 2 {
		uid, err := strconv.Atoi(ug[0])
		if err != nil {
			return nil, errors.New("config.User: unsupported uid format")
		}

		gid, err := strconv.Atoi(ug[1])
		if err != nil {
			return nil, errors.New("config.User: unsupported gid format")
		}

		s.Process.User.UID = uint32(uid)
		s.Process.User.GID = uint32(gid)
	} else if c.Config.User != "" {
		return nil, errors.New("config.User: unsupported format")
	}

	s.Platform.OS = c.OS
	s.Platform.Arch = c.Architecture

	mem := uint64(c.Config.Memory)
	swap := uint64(c.Config.MemorySwap)
	shares := uint64(c.Config.CPUShares)

	s.Linux.Resources = &specs.Resources{
		CPU: &specs.CPU{
			Shares: &shares,
		},

		Memory: &specs.Memory{
			Limit:       &mem,
			Reservation: &mem,
			Swap:        &swap,
		},
	}

	for vol := range c.Config.Volumes {
		s.Mounts = append(
			s.Mounts,
			specs.Mount{
				Destination: vol,
				Type:        "bind",
				Options:     []string{"rbind"},
			},
		)
	}

	return &s, nil
}
<commit_msg>image/config: Replace `'%s'` with `%q`<commit_after>// Copyright 2016 The Linux Foundation
//
// 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 image

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/opencontainers/image-spec/schema"
	"github.com/opencontainers/image-spec/specs-go/v1"
	"github.com/opencontainers/runtime-spec/specs-go"
	"github.com/pkg/errors"
)

type config v1.Image

func findConfig(w walker, d *descriptor) (*config, error) {
	var c config
	cpath := filepath.Join("blobs", d.algo(), d.hash())

	switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
		if info.IsDir() || filepath.Clean(path) != cpath {
			return nil
		}
		buf, err := ioutil.ReadAll(r)
		if err != nil {
			return errors.Wrapf(err, "%s: error reading config", path)
		}

		if err := schema.MediaTypeImageConfig.Validate(bytes.NewReader(buf)); err != nil {
			return errors.Wrapf(err, "%s: config validation failed", path)
		}

		if err := json.Unmarshal(buf, &c); err != nil {
			return err
		}
		// check if the rootfs type is 'layers'
		if c.RootFS.Type != "layers" {
			return fmt.Errorf("%q is an unknown rootfs type, MUST be 'layers'", c.RootFS.Type)
		}
		return errEOW
	}); err {
	case nil:
		return nil, fmt.Errorf("%s: config not found", cpath)
	case errEOW:
		return &c, nil
	default:
		return nil, err
	}
}

func (c *config) runtimeSpec(rootfs string) (*specs.Spec, error) {
	if c.OS != "linux" {
		return nil, fmt.Errorf("%s: unsupported OS", c.OS)
	}

	var s specs.Spec
	s.Version = specs.Version
	// we should at least apply the default spec, otherwise this is totally useless
	s.Process.Terminal = true
	s.Root.Path = rootfs
	s.Process.Cwd = "/"
	if c.Config.WorkingDir != "" {
		s.Process.Cwd = c.Config.WorkingDir
	}
	s.Process.Env = append(s.Process.Env, c.Config.Env...)
	s.Process.Args = append(s.Process.Args, c.Config.Entrypoint...)
	s.Process.Args = append(s.Process.Args, c.Config.Cmd...)

	if len(s.Process.Args) == 0 {
		s.Process.Args = append(s.Process.Args, "sh")
	}

	if uid, err := strconv.Atoi(c.Config.User); err == nil {
		s.Process.User.UID = uint32(uid)
	} else if ug := strings.Split(c.Config.User, ":"); len(ug) == 2 {
		uid, err := strconv.Atoi(ug[0])
		if err != nil {
			return nil, errors.New("config.User: unsupported uid format")
		}

		gid, err := strconv.Atoi(ug[1])
		if err != nil {
			return nil, errors.New("config.User: unsupported gid format")
		}

		s.Process.User.UID = uint32(uid)
		s.Process.User.GID = uint32(gid)
	} else if c.Config.User != "" {
		return nil, errors.New("config.User: unsupported format")
	}

	s.Platform.OS = c.OS
	s.Platform.Arch = c.Architecture

	mem := uint64(c.Config.Memory)
	swap := uint64(c.Config.MemorySwap)
	shares := uint64(c.Config.CPUShares)

	s.Linux.Resources = &specs.Resources{
		CPU: &specs.CPU{
			Shares: &shares,
		},

		Memory: &specs.Memory{
			Limit:       &mem,
			Reservation: &mem,
			Swap:        &swap,
		},
	}

	for vol := range c.Config.Volumes {
		s.Mounts = append(
			s.Mounts,
			specs.Mount{
				Destination: vol,
				Type:        "bind",
				Options:     []string{"rbind"},
			},
		)
	}

	return &s, nil
}
<|endoftext|>


<commit_before>// Copyright 2015 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 comebackfs

import (
	"errors"
	"fmt"
	"log"

	"golang.org/x/net/context"

	"github.com/jacobsa/comeback/internal/blob"
	"github.com/jacobsa/comeback/internal/fs"
	"github.com/jacobsa/comeback/internal/repr"
	"github.com/jacobsa/fuse/fuseops"
	"github.com/jacobsa/fuse/fuseutil"
	"github.com/jacobsa/syncutil"
)

// Create an inode with the supplied attributes. The supplied score should
// contain the inode's listing.
func newDirInode(
	attrs fuseops.InodeAttributes,
	score blob.Score,
	blobStore blob.Store) (d *dirInode) {
	d = &dirInode{
		score:     score,
		blobStore: blobStore,
		attrs:     attrs,
	}

	d.mu = syncutil.NewInvariantMutex(d.checkInvariants)

	return
}

////////////////////////////////////////////////////////////////////////
// Internal
////////////////////////////////////////////////////////////////////////

type dirInode struct {
	score     blob.Score
	blobStore blob.Store

	/////////////////////////
	// Constant data
	/////////////////////////

	attrs fuseops.InodeAttributes

	/////////////////////////
	// Mutable data
	/////////////////////////

	mu syncutil.InvariantMutex

	// A list of entries in the directory, or nil if we haven't yet read the
	// blob.
	//
	// INVARIANT: For each v, v.HardLinkTarget == nil
	//
	// GUARDED_BY(mu)
	entries []*fs.DirectoryEntry
}

func (d *dirInode) checkInvariants() {
	// INVARIANT: For each v, v.HardLinkTarget == nil
	for _, v := range d.entries {
		if v.HardLinkTarget != nil {
			log.Fatalf("Found a hard link for name %q", v.Name)
		}
	}
}

// Ensure that d.entries is non-nil.
//
// LOCKS_REQUIRED(d)
func (d *dirInode) ensureEntries(ctx context.Context) (err error) {
	if d.entries != nil {
		return
	}

	// Read the blob.
	contents, err := d.blobStore.Load(ctx, d.score)
	if err != nil {
		err = fmt.Errorf("blobStore.Load: %v", err)
		return
	}

	// Parse it.
	entries, err := repr.UnmarshalDir(contents)
	if err != nil {
		err = fmt.Errorf("UnmarshalDir: %v", err)
		return
	}

	// We cound on nil being a sentinel, so don't let a nil slice above (for an
	// empty lit of entries) escape.
	if entries == nil {
		entries = make([]*fs.DirectoryEntry, 0, 1)
	}

	// We don't support hard links.
	for _, e := range entries {
		if e.HardLinkTarget != nil {
			err = errors.New("Hard link enountered.")
			return
		}
	}

	d.entries = entries
	return
}

func convertEntryType(t fs.EntryType) fuseutil.DirentType {
	switch t {
	case fs.TypeFile:
		return fuseutil.DT_File

	case fs.TypeDirectory:
		return fuseutil.DT_Directory

	case fs.TypeSymlink:
		return fuseutil.DT_Link

	default:
		return fuseutil.DT_Unknown
	}
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

// LOCKS_EXCLUDED(d)
func (d *dirInode) Lock() {
	d.mu.Lock()
}

// LOCKS_REQUIRED(d)
func (d *dirInode) Unlock() {
	d.mu.Unlock()
}

// Return the score backing the inode's listing's contents. No lock required.
func (d *dirInode) Score() blob.Score {
	return d.score
}

// LOCKS_REQUIRED(d)
func (d *dirInode) Attributes() (attrs fuseops.InodeAttributes) {
	attrs = d.attrs
	return
}

// Serve the supplied read dir op.
//
// LOCKS_REQUIRED(d)
func (d *dirInode) Read(
	ctx context.Context,
	op *fuseops.ReadDirOp) (err error) {
	// Make sure the list of entries is present.
	err = d.ensureEntries(ctx)
	if err != nil {
		err = fmt.Errorf("ensureEntries: %v", err)
		return
	}

	// Check that the offset is in range.
	if op.Offset > fuseops.DirOffset(len(d.entries)) {
		err = fmt.Errorf("Out of range offset: %d", op.Offset)
		return
	}

	// Write out the entries in range.
	for i := op.Offset; i < fuseops.DirOffset(len(d.entries)); i++ {
		e := d.entries[i]
		de := fuseutil.Dirent{
			Offset: i + 1,
			Inode:  fuseops.InodeID(e.Inode),
			Name:   e.Name,
			Type:   convertEntryType(e.Type),
		}

		n := fuseutil.WriteDirent(op.Dst, de)
		if n == 0 {
			break
		}

		op.BytesRead += n
	}

	return
}

// Look up the supplied child name, returning an entry if found. If not found,
// return nil.
//
// LOCKS_REQUIRED(d)
func (d *dirInode) LookUpChild(
	ctx context.Context,
	name string) (e *fs.DirectoryEntry, err error) {
	err = errors.New("TODO")
	return
}
<commit_msg>Fixed a bug.<commit_after>// Copyright 2015 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 comebackfs

import (
	"errors"
	"fmt"
	"log"

	"golang.org/x/net/context"

	"github.com/jacobsa/comeback/internal/blob"
	"github.com/jacobsa/comeback/internal/fs"
	"github.com/jacobsa/comeback/internal/repr"
	"github.com/jacobsa/fuse/fuseops"
	"github.com/jacobsa/fuse/fuseutil"
	"github.com/jacobsa/syncutil"
)

// Create an inode with the supplied attributes. The supplied score should
// contain the inode's listing.
func newDirInode(
	attrs fuseops.InodeAttributes,
	score blob.Score,
	blobStore blob.Store) (d *dirInode) {
	d = &dirInode{
		score:     score,
		blobStore: blobStore,
		attrs:     attrs,
	}

	d.mu = syncutil.NewInvariantMutex(d.checkInvariants)

	return
}

////////////////////////////////////////////////////////////////////////
// Internal
////////////////////////////////////////////////////////////////////////

type dirInode struct {
	score     blob.Score
	blobStore blob.Store

	/////////////////////////
	// Constant data
	/////////////////////////

	attrs fuseops.InodeAttributes

	/////////////////////////
	// Mutable data
	/////////////////////////

	mu syncutil.InvariantMutex

	// A list of entries in the directory, or nil if we haven't yet read the
	// blob.
	//
	// INVARIANT: For each v, v.HardLinkTarget == nil
	//
	// GUARDED_BY(mu)
	entries []*fs.DirectoryEntry
}

func (d *dirInode) checkInvariants() {
	// INVARIANT: For each v, v.HardLinkTarget == nil
	for _, v := range d.entries {
		if v.HardLinkTarget != nil {
			log.Fatalf("Found a hard link for name %q", v.Name)
		}
	}
}

// Ensure that d.entries is non-nil.
//
// LOCKS_REQUIRED(d)
func (d *dirInode) ensureEntries(ctx context.Context) (err error) {
	if d.entries != nil {
		return
	}

	// Read the blob.
	contents, err := d.blobStore.Load(ctx, d.score)
	if err != nil {
		err = fmt.Errorf("blobStore.Load: %v", err)
		return
	}

	// Parse it.
	entries, err := repr.UnmarshalDir(contents)
	if err != nil {
		err = fmt.Errorf("UnmarshalDir: %v", err)
		return
	}

	// We cound on nil being a sentinel, so don't let a nil slice above (for an
	// empty lit of entries) escape.
	if entries == nil {
		entries = make([]*fs.DirectoryEntry, 0, 1)
	}

	// We don't support hard links.
	for _, e := range entries {
		if e.HardLinkTarget != nil {
			err = errors.New("Hard link enountered.")
			return
		}
	}

	d.entries = entries
	return
}

func convertEntryType(t fs.EntryType) fuseutil.DirentType {
	switch t {
	case fs.TypeFile:
		return fuseutil.DT_File

	case fs.TypeDirectory:
		return fuseutil.DT_Directory

	case fs.TypeSymlink:
		return fuseutil.DT_Link

	default:
		return fuseutil.DT_Unknown
	}
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

// LOCKS_EXCLUDED(d)
func (d *dirInode) Lock() {
	d.mu.Lock()
}

// LOCKS_REQUIRED(d)
func (d *dirInode) Unlock() {
	d.mu.Unlock()
}

// Return the score backing the inode's listing's contents. No lock required.
func (d *dirInode) Score() blob.Score {
	return d.score
}

// LOCKS_REQUIRED(d)
func (d *dirInode) Attributes() (attrs fuseops.InodeAttributes) {
	attrs = d.attrs
	return
}

// Serve the supplied read dir op.
//
// LOCKS_REQUIRED(d)
func (d *dirInode) Read(
	ctx context.Context,
	op *fuseops.ReadDirOp) (err error) {
	// Make sure the list of entries is present.
	err = d.ensureEntries(ctx)
	if err != nil {
		err = fmt.Errorf("ensureEntries: %v", err)
		return
	}

	// Check that the offset is in range.
	if op.Offset > fuseops.DirOffset(len(d.entries)) {
		err = fmt.Errorf("Out of range offset: %d", op.Offset)
		return
	}

	// Write out the entries in range.
	for i := op.Offset; i < fuseops.DirOffset(len(d.entries)); i++ {
		e := d.entries[i]
		de := fuseutil.Dirent{
			Offset: i + 1,
			Inode:  fuseops.InodeID(e.Inode),
			Name:   e.Name,
			Type:   convertEntryType(e.Type),
		}

		n := fuseutil.WriteDirent(op.Dst[op.BytesRead:], de)
		if n == 0 {
			break
		}

		op.BytesRead += n
	}

	return
}

// Look up the supplied child name, returning an entry if found. If not found,
// return nil.
//
// LOCKS_REQUIRED(d)
func (d *dirInode) LookUpChild(
	ctx context.Context,
	name string) (e *fs.DirectoryEntry, err error) {
	err = errors.New("TODO")
	return
}
<|endoftext|>


<commit_before>package compare

import "testing"

func TestCompareString(t *testing.T) {

	// simple
	Assert(t, "a", "a")
	Assert(t, "á", "á")
	Assert(t, "something longer\nwith two lines", "something longer\nwith two lines")

	AssertFalse(t, "a", "b")
	AssertFalse(t, "a", 1)
	AssertFalse(t, "a", []interface{}{})
	AssertFalse(t, "a", nil)
	AssertFalse(t, "a", []interface{}{"a"})
	AssertFalse(t, "a", map[string]interface{}{"a": 1})
}
func TestCompareArray(t *testing.T) {

	// simple pass
	Assert(t, []interface{}{1, 2, 3}, []interface{}{1, 2, 3})

	// out of order
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 3, 2})

	// totally mistmatched lists
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{3, 4, 5})

	// missing items
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 2})
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 3})

	// extra items
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 2, 3, 4})

	// empty array
	Assert(t, []interface{}{}, []interface{}{})
	AssertFalse(t, []interface{}{1}, []interface{}{})
	AssertFalse(t, []interface{}{}, []interface{}{1})
	AssertFalse(t, []interface{}{}, nil)

	// strings
	Assert(t, []interface{}{"a", "b"}, []interface{}{"a", "b"})
	AssertFalse(t, []interface{}{"a", "c"}, []interface{}{"a", "b"})

	// multiple of a single value
	Assert(t, []interface{}{1, 2, 2, 3, 3, 3}, []interface{}{1, 2, 2, 3, 3, 3})
	AssertFalse(t, []interface{}{1, 2, 2, 3, 3, 3}, []interface{}{1, 2, 3})
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 2, 2, 3, 3, 3})
}
func TestCompareArray_PartialMatch(t *testing.T) {
	// note that these are all in-order

	// simple
	Assert(t, PartialMatch([]interface{}{1}), []interface{}{1, 2, 3})
	Assert(t, PartialMatch([]interface{}{2}), []interface{}{1, 2, 3})
	Assert(t, PartialMatch([]interface{}{3}), []interface{}{1, 2, 3})

	Assert(t, PartialMatch([]interface{}{1, 2}), []interface{}{1, 2, 3})
	Assert(t, PartialMatch([]interface{}{1, 3}), []interface{}{1, 2, 3})

	Assert(t, PartialMatch([]interface{}{1, 2, 3}), []interface{}{1, 2, 3})

	AssertFalse(t, PartialMatch([]interface{}{4}), []interface{}{1, 2, 3})

	// ordered
	AssertFalse(t, PartialMatch([]interface{}{3, 2, 1}).SetOrdered(true), []interface{}{1, 2, 3})
	AssertFalse(t, PartialMatch([]interface{}{1, 3, 2}).SetOrdered(true), []interface{}{1, 2, 3})

	// empty array
	Assert(t, PartialMatch([]interface{}{}), []interface{}{1, 2, 3})

	// multiple of a single items
	Assert(t, PartialMatch([]interface{}{1, 2, 2}), []interface{}{1, 2, 2, 3, 3, 3})
	AssertFalse(t, PartialMatch([]interface{}{1, 2, 2, 2}), []interface{}{1, 2, 2, 3, 3, 3})
}
func TestCompareArray_unordered(t *testing.T) {

	// simple
	Assert(t, UnorderedMatch([]interface{}{1, 2}), []interface{}{1, 2})
	Assert(t, UnorderedMatch([]interface{}{2, 1}), []interface{}{1, 2})

	AssertFalse(t, UnorderedMatch([]interface{}{1, 2}), []interface{}{1, 2, 3})
	AssertFalse(t, UnorderedMatch([]interface{}{1, 3}), []interface{}{1, 2, 3})
	AssertFalse(t, UnorderedMatch([]interface{}{3, 1}), []interface{}{1, 2, 3})

	// empty array
	Assert(t, UnorderedMatch([]interface{}{}), []interface{}{})
}
func TestCompareMap(t *testing.T) {

	// simple
	Assert(t, map[string]interface{}{"a": 1, "b": 2, "c": 3}, map[string]interface{}{"a": 1, "b": 2, "c": 3})
	Assert(t, map[string]interface{}{"a": 1, "b": 2, "c": 3}, map[string]interface{}{"c": 3, "a": 1, "b": 2})

	AssertFalse(t, map[string]interface{}{"a": 1, "b": 2, "c": 3}, map[string]interface{}{"a": 1})
	AssertFalse(t, map[string]interface{}{"a": 1}, map[string]interface{}{"a": 1, "b": 2, "c": 3})

	// empty
	Assert(t, map[string]interface{}{}, map[string]interface{}{})
	AssertFalse(t, map[string]interface{}{}, map[string]interface{}{"a": 1})
	AssertFalse(t, map[string]interface{}{"a": 1}, map[string]interface{}{})

	Assert(t, map[interface{}]interface{}{1: 1225, 2: 1250, 3: 1275, 0: 1200}, map[string]interface{}{"2": 1250, "3": 1275, "0": 1200, "1": 1225})
	Assert(t, map[interface{}]interface{}{nil: 33, 0: 22, 20: 22, 30: 23}, map[string]interface{}{"30": 23, "": 33, "0": 22, "20": 22})
}
func TestCompareMap_PartialMatch(t *testing.T) {

	// simple
	Assert(t, PartialMatch(map[string]interface{}{"a": 1}), map[string]interface{}{"a": 1})
	Assert(t, PartialMatch(map[string]interface{}{"a": 1}), map[string]interface{}{"a": 1, "b": 2})

	AssertFalse(t, PartialMatch(map[string]interface{}{"a": 2}), map[string]interface{}{"a": 1, "b": 2})
	AssertFalse(t, PartialMatch(map[string]interface{}{"c": 1}), map[string]interface{}{"a": 1, "b": 2})
	AssertFalse(t, PartialMatch(map[string]interface{}{"a": 1, "b": 2}), map[string]interface{}{"b": 2})

	// empty
	Assert(t, PartialMatch(map[string]interface{}{}), map[string]interface{}{})
	Assert(t, PartialMatch(map[string]interface{}{}), map[string]interface{}{"a": 1})
	AssertFalse(t, PartialMatch(map[string]interface{}{"a": 1}), map[string]interface{}{})
}
func TestCompareMap_inSlice(t *testing.T) {

	// simple
	Assert(t, []interface{}{map[string]interface{}{"a": 1}}, []interface{}{map[string]interface{}{"a": 1}})
	Assert(t, []interface{}{map[string]interface{}{"a": 1, "b": 2}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}, []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}})

	AssertFalse(t, []interface{}{map[string]interface{}{"a": 1}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 2, "b": 2}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 2, "c": 3}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 2, "c": 3}}, []interface{}{map[string]interface{}{"a": 1}})
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})

	// order
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}, []interface{}{map[string]interface{}{"b": 2}, map[string]interface{}{"a": 1}})

	// partial
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1, "b": 2}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}), []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}, map[string]interface{}{"c": 3}})

	AssertFalse(t, PartialMatch([]interface{}{map[string]interface{}{"a": 2}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	AssertFalse(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1, "b": 2}}), []interface{}{map[string]interface{}{"a": 1}})

	// partial order
	AssertFalse(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}).SetOrdered(true), []interface{}{map[string]interface{}{"b": 2}, map[string]interface{}{"a": 1}})

	// partial unordered
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}), []interface{}{map[string]interface{}{"b": 2}, map[string]interface{}{"a": 1}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}).SetOrdered(false), []interface{}{map[string]interface{}{"b": 2}, map[string]interface{}{"a": 1}})

	Assert(t, []interface{}{map[string]interface{}{"a": 1, "b": 1}, PartialMatch(map[string]interface{}{"a": 2})}, []interface{}{map[string]interface{}{"a": 1, "b": 1}, map[string]interface{}{"a": 2, "b": 2}})
}

func TestCompareUUID(t *testing.T) {

	// simple
	Assert(t, IsUUID(), "4e9e5bc2-9b11-4143-9aa1-75c10e7a193a")
	AssertFalse(t, IsUUID(), "4")
	AssertFalse(t, IsUUID(), "*")
	AssertFalse(t, IsUUID(), nil)
}

func TestCompareNumbers(t *testing.T) {

	// simple
	Assert(t, 1, 1)
	Assert(t, 1, 1.0)
	Assert(t, 1.0, 1)
	Assert(t, 1.0, 1.0)

	AssertFalse(t, 1, 2)
	AssertFalse(t, 1, 2.0)
	AssertFalse(t, 1.0, 2)
	AssertFalse(t, 1.0, 2.0)

	// precision
	AssertPrecision(t, 1, 1.4, 0.5)
	AssertPrecision(t, 1.0, 1.4, 0.5)

	AssertPrecisionFalse(t, 1, 2, 0.5)
	AssertPrecisionFalse(t, 1, 1.6, 0.5)
	AssertPrecisionFalse(t, 1.0, 2, 0.5)
	AssertPrecisionFalse(t, 1.0, 1.6, 0.5)
}
<commit_msg>Fix failing test<commit_after>package compare

import "testing"

func TestCompareString(t *testing.T) {

	// simple
	Assert(t, "a", "a")
	Assert(t, "á", "á")
	Assert(t, "something longer\nwith two lines", "something longer\nwith two lines")

	AssertFalse(t, "a", "b")
	AssertFalse(t, "a", 1)
	AssertFalse(t, "a", []interface{}{})
	AssertFalse(t, "a", nil)
	AssertFalse(t, "a", []interface{}{"a"})
	AssertFalse(t, "a", map[string]interface{}{"a": 1})
}
func TestCompareArray(t *testing.T) {

	// simple pass
	Assert(t, []interface{}{1, 2, 3}, []interface{}{1, 2, 3})

	// out of order
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 3, 2})

	// totally mistmatched lists
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{3, 4, 5})

	// missing items
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 2})
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 3})

	// extra items
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 2, 3, 4})

	// empty array
	Assert(t, []interface{}{}, []interface{}{})
	AssertFalse(t, []interface{}{1}, []interface{}{})
	AssertFalse(t, []interface{}{}, []interface{}{1})
	AssertFalse(t, []interface{}{}, nil)

	// strings
	Assert(t, []interface{}{"a", "b"}, []interface{}{"a", "b"})
	AssertFalse(t, []interface{}{"a", "c"}, []interface{}{"a", "b"})

	// multiple of a single value
	Assert(t, []interface{}{1, 2, 2, 3, 3, 3}, []interface{}{1, 2, 2, 3, 3, 3})
	AssertFalse(t, []interface{}{1, 2, 2, 3, 3, 3}, []interface{}{1, 2, 3})
	AssertFalse(t, []interface{}{1, 2, 3}, []interface{}{1, 2, 2, 3, 3, 3})
}
func TestCompareArray_PartialMatch(t *testing.T) {
	// note that these are all in-order

	// simple
	Assert(t, PartialMatch([]interface{}{1}), []interface{}{1, 2, 3})
	Assert(t, PartialMatch([]interface{}{2}), []interface{}{1, 2, 3})
	Assert(t, PartialMatch([]interface{}{3}), []interface{}{1, 2, 3})

	Assert(t, PartialMatch([]interface{}{1, 2}), []interface{}{1, 2, 3})
	Assert(t, PartialMatch([]interface{}{1, 3}), []interface{}{1, 2, 3})

	Assert(t, PartialMatch([]interface{}{1, 2, 3}), []interface{}{1, 2, 3})

	AssertFalse(t, PartialMatch([]interface{}{4}), []interface{}{1, 2, 3})

	// ordered
	AssertFalse(t, PartialMatch([]interface{}{3, 2, 1}).SetOrdered(true), []interface{}{1, 2, 3})
	AssertFalse(t, PartialMatch([]interface{}{1, 3, 2}).SetOrdered(true), []interface{}{1, 2, 3})

	// empty array
	Assert(t, PartialMatch([]interface{}{}), []interface{}{1, 2, 3})

	// multiple of a single items
	Assert(t, PartialMatch([]interface{}{1, 2, 2}), []interface{}{1, 2, 2, 3, 3, 3})
	AssertFalse(t, PartialMatch([]interface{}{1, 2, 2, 2}), []interface{}{1, 2, 2, 3, 3, 3})
}
func TestCompareArray_unordered(t *testing.T) {

	// simple
	Assert(t, UnorderedMatch([]interface{}{1, 2}), []interface{}{1, 2})
	Assert(t, UnorderedMatch([]interface{}{2, 1}), []interface{}{1, 2})

	AssertFalse(t, UnorderedMatch([]interface{}{1, 2}), []interface{}{1, 2, 3})
	AssertFalse(t, UnorderedMatch([]interface{}{1, 3}), []interface{}{1, 2, 3})
	AssertFalse(t, UnorderedMatch([]interface{}{3, 1}), []interface{}{1, 2, 3})

	// empty array
	Assert(t, UnorderedMatch([]interface{}{}), []interface{}{})
}
func TestCompareMap(t *testing.T) {

	// simple
	Assert(t, map[string]interface{}{"a": 1, "b": 2, "c": 3}, map[string]interface{}{"a": 1, "b": 2, "c": 3})
	Assert(t, map[string]interface{}{"a": 1, "b": 2, "c": 3}, map[string]interface{}{"c": 3, "a": 1, "b": 2})

	AssertFalse(t, map[string]interface{}{"a": 1, "b": 2, "c": 3}, map[string]interface{}{"a": 1})
	AssertFalse(t, map[string]interface{}{"a": 1}, map[string]interface{}{"a": 1, "b": 2, "c": 3})

	// empty
	Assert(t, map[string]interface{}{}, map[string]interface{}{})
	AssertFalse(t, map[string]interface{}{}, map[string]interface{}{"a": 1})
	AssertFalse(t, map[string]interface{}{"a": 1}, map[string]interface{}{})

	Assert(t, map[interface{}]interface{}{1: 1225, 2: 1250, 3: 1275, 0: 1200}, map[string]interface{}{"2": 1250, "3": 1275, "0": 1200, "1": 1225})
	Assert(t, map[interface{}]interface{}{0: 22, 20: 22, 30: 23}, map[string]interface{}{"30": 23, "0": 22, "20": 22})
}
func TestCompareMap_PartialMatch(t *testing.T) {

	// simple
	Assert(t, PartialMatch(map[string]interface{}{"a": 1}), map[string]interface{}{"a": 1})
	Assert(t, PartialMatch(map[string]interface{}{"a": 1}), map[string]interface{}{"a": 1, "b": 2})

	AssertFalse(t, PartialMatch(map[string]interface{}{"a": 2}), map[string]interface{}{"a": 1, "b": 2})
	AssertFalse(t, PartialMatch(map[string]interface{}{"c": 1}), map[string]interface{}{"a": 1, "b": 2})
	AssertFalse(t, PartialMatch(map[string]interface{}{"a": 1, "b": 2}), map[string]interface{}{"b": 2})

	// empty
	Assert(t, PartialMatch(map[string]interface{}{}), map[string]interface{}{})
	Assert(t, PartialMatch(map[string]interface{}{}), map[string]interface{}{"a": 1})
	AssertFalse(t, PartialMatch(map[string]interface{}{"a": 1}), map[string]interface{}{})
}
func TestCompareMap_inSlice(t *testing.T) {

	// simple
	Assert(t, []interface{}{map[string]interface{}{"a": 1}}, []interface{}{map[string]interface{}{"a": 1}})
	Assert(t, []interface{}{map[string]interface{}{"a": 1, "b": 2}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}, []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}})

	AssertFalse(t, []interface{}{map[string]interface{}{"a": 1}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 2, "b": 2}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 2, "c": 3}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 2, "c": 3}}, []interface{}{map[string]interface{}{"a": 1}})
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}, []interface{}{map[string]interface{}{"a": 1, "b": 2}})

	// order
	AssertFalse(t, []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}, []interface{}{map[string]interface{}{"b": 2}, map[string]interface{}{"a": 1}})

	// partial
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1, "b": 2}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}), []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}, map[string]interface{}{"c": 3}})

	AssertFalse(t, PartialMatch([]interface{}{map[string]interface{}{"a": 2}}), []interface{}{map[string]interface{}{"a": 1, "b": 2}})
	AssertFalse(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1, "b": 2}}), []interface{}{map[string]interface{}{"a": 1}})

	// partial order
	AssertFalse(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}).SetOrdered(true), []interface{}{map[string]interface{}{"b": 2}, map[string]interface{}{"a": 1}})

	// partial unordered
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}), []interface{}{map[string]interface{}{"b": 2}, map[string]interface{}{"a": 1}})
	Assert(t, PartialMatch([]interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"b": 2}}).SetOrdered(false), []interface{}{map[string]interface{}{"b": 2}, map[string]interface{}{"a": 1}})

	Assert(t, []interface{}{map[string]interface{}{"a": 1, "b": 1}, PartialMatch(map[string]interface{}{"a": 2})}, []interface{}{map[string]interface{}{"a": 1, "b": 1}, map[string]interface{}{"a": 2, "b": 2}})
}

func TestCompareUUID(t *testing.T) {

	// simple
	Assert(t, IsUUID(), "4e9e5bc2-9b11-4143-9aa1-75c10e7a193a")
	AssertFalse(t, IsUUID(), "4")
	AssertFalse(t, IsUUID(), "*")
	AssertFalse(t, IsUUID(), nil)
}

func TestCompareNumbers(t *testing.T) {

	// simple
	Assert(t, 1, 1)
	Assert(t, 1, 1.0)
	Assert(t, 1.0, 1)
	Assert(t, 1.0, 1.0)

	AssertFalse(t, 1, 2)
	AssertFalse(t, 1, 2.0)
	AssertFalse(t, 1.0, 2)
	AssertFalse(t, 1.0, 2.0)

	// precision
	AssertPrecision(t, 1, 1.4, 0.5)
	AssertPrecision(t, 1.0, 1.4, 0.5)

	AssertPrecisionFalse(t, 1, 2, 0.5)
	AssertPrecisionFalse(t, 1, 1.6, 0.5)
	AssertPrecisionFalse(t, 1.0, 2, 0.5)
	AssertPrecisionFalse(t, 1.0, 1.6, 0.5)
}
<|endoftext|>


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

package codec

import (
	"bytes"
	"errors"
	"fmt"
	"go/format"
	"io"
	"reflect"
	"sort"
	"strings"
	"text/template"
)

// Generate write a Go file to w with definitions for encoding values using
// this package. It generates code for the type of each value in vs, as well
// as any types they depend on.
// packageName is the name following the file's package declaration.

func Generate(w io.Writer, packageName string, vs ...interface{}) error {
	g := &generator{
		pkg:  packageName,
		done: map[reflect.Type]bool{},
	}
	funcs := template.FuncMap{
		"funcName":   g.funcName,
		"goName":     g.goName,
		"encodeStmt": g.encodeStatement,
		"decodeStmt": g.decodeStatement,
	}

	newTemplate := func(name, body string) *template.Template {
		return template.Must(template.New(name).Funcs(funcs).Parse(body))
	}
	g.initialTemplate = newTemplate("initial", initial)
	g.sliceTemplate = newTemplate("slice", slice)
	g.mapTemplate = newTemplate("map", mapBody)

	for _, v := range vs {
		g.todo = append(g.todo, reflect.TypeOf(v))
	}

	// Mark the types we already know about as done.
	for t := range typeInfosByType {
		g.done[t] = true
	}
	// The empty interface doesn't need any additional code. It's tricky to get
	// its reflect.Type: we need to dereference the pointer type.
	var iface interface{}
	g.done[reflect.TypeOf(&iface).Elem()] = true

	src, err := g.generate()
	if err != nil {
		return err
	}
	src, err = format.Source(src)
	if err != nil {
		return fmt.Errorf("format.Source: %v", err)
	}
	_, err = w.Write(src)
	return err
}

type generator struct {
	pkg             string
	todo            []reflect.Type
	done            map[reflect.Type]bool
	initialTemplate *template.Template
	sliceTemplate   *template.Template
	mapTemplate     *template.Template
}

func (g *generator) generate() ([]byte, error) {
	importMap := map[string]bool{}
	var pieces [][]byte
	for len(g.todo) > 0 {
		t := g.todo[0]
		g.todo = g.todo[1:]
		if !g.done[t] {
			if t.PkgPath() != "" {
				importMap[t.PkgPath()] = true
			}
			code, err := g.gen(t)
			if err != nil {
				return nil, err
			}
			pieces = append(pieces, code)
			// We use the same code for T and *T, so both are done.
			g.done[t] = true
			g.done[reflect.PtrTo(t)] = true
		}
	}

	var imports []string
	for i := range importMap {
		imports = append(imports, i)
	}
	sort.Strings(imports)
	result, err := execute(g.initialTemplate, struct {
		Package string
		Imports []string
	}{
		Package: g.pkg,
		Imports: imports,
	})
	if err != nil {
		return nil, err
	}
	for _, p := range pieces {
		result = append(result, p...)
	}
	return result, nil
}

func (g *generator) gen(t reflect.Type) ([]byte, error) {
	switch t.Kind() {
	case reflect.Slice:
		return g.genSlice(t)
	case reflect.Map:
		return g.genMap(t)
	default:
		return nil, errors.New("unimplemented")
	}
}

func (g *generator) genSlice(t reflect.Type) ([]byte, error) {
	et := t.Elem()
	g.todo = append(g.todo, et)
	return execute(g.sliceTemplate, struct {
		Type, ElType reflect.Type
	}{
		Type:   t,
		ElType: et,
	})
}

func (g *generator) genMap(t reflect.Type) ([]byte, error) {
	et := t.Elem()
	kt := t.Key()
	g.todo = append(g.todo, kt, et)
	return execute(g.mapTemplate, struct {
		Type, ElType, KeyType reflect.Type
	}{
		Type:    t,
		ElType:  et,
		KeyType: kt,
	})
}

func execute(tmpl *template.Template, data interface{}) ([]byte, error) {
	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, data); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// encodeStatement returns a Go statement that encodes a value denoted by arg, of type t.
func (g *generator) encodeStatement(t reflect.Type, arg string) string {
	bn, native := builtinName(t)
	if bn != "" {
		// t can be handled by an Encoder method.
		if t != native {
			// t is not the Encoder method's argument type, so we must cast.
			arg = fmt.Sprintf("%s(%s)", native, arg)
		}
		return fmt.Sprintf("e.Encode%s(%s)", bn, arg)
	}
	if t.Kind() == reflect.Interface {
		return fmt.Sprintf("e.EncodeAny(%s)", arg)
	}
	return fmt.Sprintf("encode_%s(e, %s)", g.funcName(t), arg)
}

func (g *generator) decodeStatement(t reflect.Type, arg string) string {
	bn, native := builtinName(t)
	if bn != "" {
		// t can be handled by a Decoder method.
		if t != native {
			// t is not the Decoder method's return type, so we must cast.
			return fmt.Sprintf("%s = %s(d.Decode%s())", arg, g.goName(t), bn)
		}
		return fmt.Sprintf("%s = d.Decode%s()", arg, bn)
	}
	if t.Kind() == reflect.Interface {
		// t is an interface, so use DecodeAny, possibly with a type assertion.
		if t.NumMethod() == 0 {
			return fmt.Sprintf("%s = d.DecodeAny()", arg)
		}
		return fmt.Sprintf("%s = d.DecodeAny().(%s)", arg, g.goName(t))
	}
	// Assume we will generate a decode method for t.
	return fmt.Sprintf("decode_%s(d, &%s)", g.funcName(t), arg)
}

// builtinName returns the suffix to append to "encode" or "decode" to get the
// Encoder/Decoder method name for t. If t cannot be encoded by an Encoder
// method, the suffix is "". The second return value is the "native" type of the
// method: the argument to the Encoder method, and the return value of the
// Decoder method.
func builtinName(t reflect.Type) (suffix string, native reflect.Type) {
	switch t.Kind() {
	case reflect.String:
		return "String", reflect.TypeOf("")
	case reflect.Bool:
		return "Bool", reflect.TypeOf(true)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return "Int", reflect.TypeOf(int64(0))
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return "Uint", reflect.TypeOf(uint64(0))
	case reflect.Float32, reflect.Float64:
		return "Float64", reflect.TypeOf(0.0)
	case reflect.Slice:
		if t.Elem() == reflect.TypeOf(byte(0)) {
			return "Bytes", reflect.TypeOf([]byte(nil))
		}
	}
	return "", nil
}

// goName returns the name of t as it should appear in a Go program.
// E.g. "go/ast.File" => ast.File
// It assumes all package paths are represented in the file by their last element.
func (g *generator) goName(t reflect.Type) string {
	switch t.Kind() {
	case reflect.Slice:
		return fmt.Sprintf("[]%s", g.goName(t.Elem()))
	case reflect.Map:
		return fmt.Sprintf("map[%s]%s", g.goName(t.Key()), g.goName(t.Elem()))
	case reflect.Ptr:
		return fmt.Sprintf("*%s", g.goName(t.Elem()))
	default:
		s := t.String()
		if strings.HasPrefix(s, g.pkg+".") {
			s = s[len(g.pkg)+1:]
		}
		return s
	}
}

var funcNameReplacer = strings.NewReplacer("[]", "slice_", "[", "_", "]", "_", ".", "_", "*", "")

// funcName returns the name for t that is used as part of the encode/decode function name.
// E.g. "ast.File" => "ast_File".
func (g *generator) funcName(t reflect.Type) string {
	return funcNameReplacer.Replace(g.goName(t))
}

// Template body for the beginning of the file.
const initial = `
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// DO NOT MODIFY. Generated code.

package {{.Package}}

import (
  "reflect"
  "unsafe"

  {{range .Imports}}
  {{.}}
  {{end}}

  "golang.org/x/pkgsite/internal/godoc/codec"
)

`

// Template body for a slice type.
const slice = `
func encode_{{funcName .Type}}(e *codec.Encoder, s {{goName .Type}}) {
	if s == nil {
		e.EncodeUint(0)
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		{{encodeStmt .ElType "x"}}
	}
}

func decode_{{funcName .Type}}(d *codec.Decoder, p *{{goName .Type}}) {
	n := d.StartList()
	if n < 0 { return }
	s := make([]{{goName .ElType}}, n)
	for i := 0; i < n; i++ {
		{{decodeStmt .ElType "s[i]"}}
	}
	*p = s
}

func init() {
  codec.Register({{goName .Type}}(nil),
    func(e *codec.Encoder, x interface{}) { encode_{{funcName .Type}}(e, x.({{goName .Type}})) },
    func(d *codec.Decoder) interface{} { var x {{goName .Type}}; decode_{{funcName .Type}}(d, &x); return x })
}
`

// Template body for a map type.
// A map of size N is encoded as a list of length 2N, containing alternating
// keys and values.
//
// In the decode function, we declare a variable v to hold the decoded map value
// rather than decoding directly into m[v]. This is necessary for decode
// functions that take pointers: you can't take a pointer to a map element.
const mapBody = `
func encode_{{funcName .Type}}(e *codec.Encoder, m {{goName .Type}}) {
	if m == nil {
		e.EncodeUint(0)
		return
	}
	e.StartList(2*len(m))
	for k, v := range m {
		{{encodeStmt .KeyType "k"}}
		{{encodeStmt .ElType "v"}}
	}
}

func decode_{{funcName .Type}}(d *codec.Decoder, p *{{goName .Type}}) {
	n2 := d.StartList()
	if n2 < 0 { return }
	n := n2/2
	m := make({{goName .Type}}, n)
	var k {{goName .KeyType}}
	var v {{goName .ElType}}
	for i := 0; i < n; i++ {
		{{decodeStmt .KeyType "k"}}
		{{decodeStmt .ElType "v"}}
		m[k] = v
	}
	*p = m
}

func init() {
	codec.Register({{goName .Type}}(nil),
	func(e *codec.Encoder, x interface{}) { encode_{{funcName .Type}}(e, x.({{goName .Type}})) },
	func(d *codec.Decoder) interface{} { var x {{goName .Type}}; decode_{{funcName .Type}}(d, &x); return x })
}
`
<commit_msg>internal/godoc/codec: replace braces in templates<commit_after>// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package codec

import (
	"bytes"
	"errors"
	"fmt"
	"go/format"
	"io"
	"reflect"
	"sort"
	"strings"
	"text/template"
)

// Generate write a Go file to w with definitions for encoding values using
// this package. It generates code for the type of each value in vs, as well
// as any types they depend on.
// packageName is the name following the file's package declaration.

func Generate(w io.Writer, packageName string, vs ...interface{}) error {
	g := &generator{
		pkg:  packageName,
		done: map[reflect.Type]bool{},
	}
	funcs := template.FuncMap{
		"funcName":   g.funcName,
		"goName":     g.goName,
		"encodeStmt": g.encodeStatement,
		"decodeStmt": g.decodeStatement,
	}

	newTemplate := func(name, body string) *template.Template {
		return template.Must(template.New(name).Delims("«", "»").Funcs(funcs).Parse(body))
	}

	g.initialTemplate = newTemplate("initial", initial)
	g.sliceTemplate = newTemplate("slice", slice)
	g.mapTemplate = newTemplate("map", mapBody)

	for _, v := range vs {
		g.todo = append(g.todo, reflect.TypeOf(v))
	}

	// Mark the types we already know about as done.
	for t := range typeInfosByType {
		g.done[t] = true
	}
	// The empty interface doesn't need any additional code. It's tricky to get
	// its reflect.Type: we need to dereference the pointer type.
	var iface interface{}
	g.done[reflect.TypeOf(&iface).Elem()] = true

	src, err := g.generate()
	if err != nil {
		return err
	}
	src, err = format.Source(src)
	if err != nil {
		return fmt.Errorf("format.Source: %v", err)
	}
	_, err = w.Write(src)
	return err
}

type generator struct {
	pkg             string
	todo            []reflect.Type
	done            map[reflect.Type]bool
	initialTemplate *template.Template
	sliceTemplate   *template.Template
	mapTemplate     *template.Template
}

func (g *generator) generate() ([]byte, error) {
	importMap := map[string]bool{}
	var pieces [][]byte
	for len(g.todo) > 0 {
		t := g.todo[0]
		g.todo = g.todo[1:]
		if !g.done[t] {
			if t.PkgPath() != "" {
				importMap[t.PkgPath()] = true
			}
			code, err := g.gen(t)
			if err != nil {
				return nil, err
			}
			pieces = append(pieces, code)
			// We use the same code for T and *T, so both are done.
			g.done[t] = true
			g.done[reflect.PtrTo(t)] = true
		}
	}

	var imports []string
	for i := range importMap {
		imports = append(imports, i)
	}
	sort.Strings(imports)
	result, err := execute(g.initialTemplate, struct {
		Package string
		Imports []string
	}{
		Package: g.pkg,
		Imports: imports,
	})
	if err != nil {
		return nil, err
	}
	for _, p := range pieces {
		result = append(result, p...)
	}
	return result, nil
}

func (g *generator) gen(t reflect.Type) ([]byte, error) {
	switch t.Kind() {
	case reflect.Slice:
		return g.genSlice(t)
	case reflect.Map:
		return g.genMap(t)
	default:
		return nil, errors.New("unimplemented")
	}
}

func (g *generator) genSlice(t reflect.Type) ([]byte, error) {
	et := t.Elem()
	g.todo = append(g.todo, et)
	return execute(g.sliceTemplate, struct {
		Type, ElType reflect.Type
	}{
		Type:   t,
		ElType: et,
	})
}

func (g *generator) genMap(t reflect.Type) ([]byte, error) {
	et := t.Elem()
	kt := t.Key()
	g.todo = append(g.todo, kt, et)
	return execute(g.mapTemplate, struct {
		Type, ElType, KeyType reflect.Type
	}{
		Type:    t,
		ElType:  et,
		KeyType: kt,
	})
}

func execute(tmpl *template.Template, data interface{}) ([]byte, error) {
	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, data); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// encodeStatement returns a Go statement that encodes a value denoted by arg, of type t.
func (g *generator) encodeStatement(t reflect.Type, arg string) string {
	bn, native := builtinName(t)
	if bn != "" {
		// t can be handled by an Encoder method.
		if t != native {
			// t is not the Encoder method's argument type, so we must cast.
			arg = fmt.Sprintf("%s(%s)", native, arg)
		}
		return fmt.Sprintf("e.Encode%s(%s)", bn, arg)
	}
	if t.Kind() == reflect.Interface {
		return fmt.Sprintf("e.EncodeAny(%s)", arg)
	}
	return fmt.Sprintf("encode_%s(e, %s)", g.funcName(t), arg)
}

func (g *generator) decodeStatement(t reflect.Type, arg string) string {
	bn, native := builtinName(t)
	if bn != "" {
		// t can be handled by a Decoder method.
		if t != native {
			// t is not the Decoder method's return type, so we must cast.
			return fmt.Sprintf("%s = %s(d.Decode%s())", arg, g.goName(t), bn)
		}
		return fmt.Sprintf("%s = d.Decode%s()", arg, bn)
	}
	if t.Kind() == reflect.Interface {
		// t is an interface, so use DecodeAny, possibly with a type assertion.
		if t.NumMethod() == 0 {
			return fmt.Sprintf("%s = d.DecodeAny()", arg)
		}
		return fmt.Sprintf("%s = d.DecodeAny().(%s)", arg, g.goName(t))
	}
	// Assume we will generate a decode method for t.
	return fmt.Sprintf("decode_%s(d, &%s)", g.funcName(t), arg)
}

// builtinName returns the suffix to append to "encode" or "decode" to get the
// Encoder/Decoder method name for t. If t cannot be encoded by an Encoder
// method, the suffix is "". The second return value is the "native" type of the
// method: the argument to the Encoder method, and the return value of the
// Decoder method.
func builtinName(t reflect.Type) (suffix string, native reflect.Type) {
	switch t.Kind() {
	case reflect.String:
		return "String", reflect.TypeOf("")
	case reflect.Bool:
		return "Bool", reflect.TypeOf(true)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return "Int", reflect.TypeOf(int64(0))
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return "Uint", reflect.TypeOf(uint64(0))
	case reflect.Float32, reflect.Float64:
		return "Float64", reflect.TypeOf(0.0)
	case reflect.Slice:
		if t.Elem() == reflect.TypeOf(byte(0)) {
			return "Bytes", reflect.TypeOf([]byte(nil))
		}
	}
	return "", nil
}

// goName returns the name of t as it should appear in a Go program.
// E.g. "go/ast.File" => ast.File
// It assumes all package paths are represented in the file by their last element.
func (g *generator) goName(t reflect.Type) string {
	switch t.Kind() {
	case reflect.Slice:
		return fmt.Sprintf("[]%s", g.goName(t.Elem()))
	case reflect.Map:
		return fmt.Sprintf("map[%s]%s", g.goName(t.Key()), g.goName(t.Elem()))
	case reflect.Ptr:
		return fmt.Sprintf("*%s", g.goName(t.Elem()))
	default:
		s := t.String()
		if strings.HasPrefix(s, g.pkg+".") {
			s = s[len(g.pkg)+1:]
		}
		return s
	}
}

var funcNameReplacer = strings.NewReplacer("[]", "slice_", "[", "_", "]", "_", ".", "_", "*", "")

// funcName returns the name for t that is used as part of the encode/decode function name.
// E.g. "ast.File" => "ast_File".
func (g *generator) funcName(t reflect.Type) string {
	return funcNameReplacer.Replace(g.goName(t))
}

// Template body for the beginning of the file.
const initial = `
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// DO NOT MODIFY. Generated code.

package «.Package»

import (
  "reflect"
  "unsafe"

  «range .Imports»
  «.»
  «end»

  "golang.org/x/pkgsite/internal/godoc/codec"
)

`

// Template body for a slice type.
const slice = `
func encode_«funcName .Type»(e *codec.Encoder, s «goName .Type») {
	if s == nil {
		e.EncodeUint(0)
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		«encodeStmt .ElType "x"»
	}
}

func decode_«funcName .Type»(d *codec.Decoder, p *«goName .Type») {
	n := d.StartList()
	if n < 0 { return }
	s := make([]«goName .ElType», n)
	for i := 0; i < n; i++ {
		«decodeStmt .ElType "s[i]"»
	}
	*p = s
}

func init() {
  codec.Register(«goName .Type»(nil),
    func(e *codec.Encoder, x interface{}) { encode_«funcName .Type»(e, x.(«goName .Type»)) },
    func(d *codec.Decoder) interface{} { var x «goName .Type»; decode_«funcName .Type»(d, &x); return x })
}
`

// Template body for a map type.
// A map of size N is encoded as a list of length 2N, containing alternating
// keys and values.
//
// In the decode function, we declare a variable v to hold the decoded map value
// rather than decoding directly into m[v]. This is necessary for decode
// functions that take pointers: you can't take a pointer to a map element.
const mapBody = `
func encode_«funcName .Type»(e *codec.Encoder, m «goName .Type») {
	if m == nil {
		e.EncodeUint(0)
		return
	}
	e.StartList(2*len(m))
	for k, v := range m {
		«encodeStmt .KeyType "k"»
		«encodeStmt .ElType "v"»
	}
}

func decode_«funcName .Type»(d *codec.Decoder, p *«goName .Type») {
	n2 := d.StartList()
	if n2 < 0 { return }
	n := n2/2
	m := make(«goName .Type», n)
	var k «goName .KeyType»
	var v «goName .ElType»
	for i := 0; i < n; i++ {
		«decodeStmt .KeyType "k"»
		«decodeStmt .ElType "v"»
		m[k] = v
	}
	*p = m
}

func init() {
	codec.Register(«goName .Type»(nil),
	func(e *codec.Encoder, x interface{}) { encode_«funcName .Type»(e, x.(«goName .Type»)) },
	func(d *codec.Decoder) interface{} { var x «goName .Type»; decode_«funcName .Type»(d, &x); return x })
}
`
<|endoftext|>


<commit_before>package main

import (
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
	"github.com/labstack/echo/engine/standard"
	"github.com/thoas/stats"
)

type Data struct {
	Id int
	Name string
	Tags []string
}

func main() {

	demoData := Data{
		Id: 5,
		Name: "User name",
		Tags: []string{"people", "customer", "developer"},
	}

	e := echo.New()
	e.SetDebug(true)
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	s := stats.New()
	e.Use(standard.WrapMiddleware(s.Handler))

	e.GET("/xml", func (c echo.Context) error {
		return c.XML(200, demoData)
	})

	e.GET("/json", func (c echo.Context) error {
		return c.JSON(200, demoData)
	})

	e.Run(standard.New(":8888"))

}<commit_msg>generate error<commit_after>package main

import (
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
	"github.com/labstack/echo/engine/standard"
	"github.com/thoas/stats"
)

type Data struct {
	Id int
	Name string
	Tags []string
}

func main() {

	demoData := Data{
		Id: 5,
		Name: "User name",
		Tags: []string{"people", "customer", "developer"},
	}

	e := echo.New()
	e.SetDebug(true)
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	s := stats.New()
	e.Use(standard.WrapMiddleware(s.Handler))

	e.GET("/xml", func (c echo.Context) error {
		return c.XML(200, demoData)
	})

	e.GET("/json", func (c echo.Context) error {
		return c.JSON(200, demoData)
	})

	e.GET("/error", func (c echo.Context) error {
		return echo.NewHTTPError(500, "Error here")
	})

	e.Run(standard.New(":8888"))

}<|endoftext|>


<commit_before>package main

import (
	"appengine"
	"appengine/datastore"
	"appengine/search"
	"math/rand"
	"sort"
	"strconv"
	"strings"
	"time"
)

type DB struct {
	Context appengine.Context
}

func (db *DB) FetchUser(userId string) {
    //Step 1. Get Vine user's data from the Vine API
	vineApi := VineRequest{db.Context}
	vineUser, err := vineApi.GetUser(userId)

	if err != nil {
		if err.Error() == ErrUserDoesntExist {
			db.UnqueueUser(userId)
		} else {
		    db.Context.Errorf("got error getting user %s from vine: %v", userId, err)
		}
		return
	} else if vineUser == nil {
		db.Context.Errorf("failed fetch on user %v. got err %v", userId, err)
		return
	} else if vineUser.Private == 1 {
	    db.Context.Infof("user %s is private", userId)
		return
	}

	recordKey := datastore.NewKey(db.Context, "UserRecord", "", vineUser.UserId, nil)

    //Step 2. Add user to user search index.
    userIndex := &UserIndex{
		Username:    vineUser.Username,
		Location:    vineUser.Location,
		Description: vineUser.Description,
	}

	if len(vineUser.VanityUrls) != 0 {
		userIndex.VanityUrl = strings.ToLower(vineUser.VanityUrls[0])
	}

	index, err := search.Open("users")
	if err != nil {
		db.Context.Errorf(err.Error())
	} else {
		index.Put(db.Context, vineUser.UserIdStr, userIndex)
	}

    //Step 3. Write records (user {meta, record, data}).
    if userRecord, err := db.GetUserRecord(vineUser.UserId); err == nil {
        var userMeta []*UserMeta

        if vineUser.Username != userRecord.Username {
            userMeta = append(userMeta, &UserMeta{vineUser.UserId, "username", userRecord.Username, time.Now()})
        }

        if vineUser.Location != userRecord.Location {
            userMeta = append(userMeta, &UserMeta{vineUser.UserId, "location", userRecord.Location, time.Now()})
        }

        if vineUser.Description != userRecord.Description {
            userMeta = append(userMeta, &UserMeta{vineUser.UserId, "description", userRecord.Description, time.Now()})
        }

        if vineUser.Location != userRecord.Location {
            userMeta = append(userMeta, &UserMeta{vineUser.UserId, "location", userRecord.Location, time.Now()})
        }

        if (vineUser.Verified != 0) != userRecord.Verified {
            userMeta = append(userMeta, &UserMeta{vineUser.UserId, "verified", strconv.FormatBool(userRecord.Verified), time.Now()})
        }

        var metaKey *datastore.Key
        for _, m := range userMeta {
            metaKey = datastore.NewIncompleteKey(db.Context, "UserMeta", recordKey)
            if key, err := datastore.Put(db.Context, metaKey, m); err != nil {
                db.Context.Errorf("got error storing user meta %s - %v: %v", userId, key, err)
            }
        }
    }

    userRecord := UserRecord{
        UserId: vineUser.UserIdStr,
        Username: vineUser.Username,
        Description: vineUser.Description,
        Location: vineUser.Location,
        ProfileBackground: vineUser.ProfileBackground,
        AvatarUrl: vineUser.AvatarUrl,
        FollowerCount: vineUser.FollowerCount,
        FollowingCount: vineUser.FollowingCount,
        LoopCount: vineUser.LoopCount,
        PostCount: vineUser.AuthoredPostCount,
        RevineCount: (vineUser.PostCount - vineUser.AuthoredPostCount),
        LikeCount: vineUser.LikeCount,
        Private: (vineUser.Private != 0),
        Verified: (vineUser.Verified != 0),
        Explicit: (vineUser.ExplicitContent != 0),
    }
    if len(vineUser.VanityUrls) != 0 {
        userRecord.Vanity = strings.ToLower(vineUser.VanityUrls[0])
    }
    if _, err := datastore.Put(db.Context, recordKey, &userRecord); err != nil {
        db.Context.Errorf("got error storing user record %s: %v", userId, err)
    }

    dataKey := datastore.NewIncompleteKey(db.Context, "UserData", recordKey)
    userData := UserData{
        UserId: vineUser.UserId,
        Recorded: time.Now(),
        Followers: vineUser.FollowerCount,
        Following: vineUser.FollowingCount,
        Loops: vineUser.LoopCount,
        Posts: vineUser.AuthoredPostCount,
        Revines: (vineUser.PostCount - vineUser.AuthoredPostCount),
        Likes: vineUser.LikeCount,
    }
    if key, err := datastore.Put(db.Context, dataKey, &userData); err != nil {
        db.Context.Errorf("got error storing user data %s - %v: %v", userId, key, err)
    }
}

func (db *DB) GetUser(userId int64) (user *UserRecord, err error) {
    user, err = db.GetUserRecord(userId)
    if err != nil {
        db.Context.Infof("error with userRecord")
        return
    }
    user.UserData, err = db.GetUserData(userId)

    if err != nil {
        db.Context.Infof("error with userData")
        return
    }

    user.UserMeta, err = db.GetUserMeta(userId)
    if err != nil {
        db.Context.Infof("error with userMeta")
    }
    return
}

func (db *DB) GetUserRecord(userId int64) (*UserRecord, error) {

    user := UserRecord{}

    recordKey := datastore.NewKey(db.Context, "UserRecord", "", userId, nil)
    err := datastore.Get(db.Context, recordKey, &user)

    if err != nil {
        return nil, err
    } else {
        return &user, nil
    }
}

func (db *DB) GetUserData(userId int64) (userData []*UserData, err error) {

	dataQuery := datastore.NewQuery("UserData").Filter("UserId =", userId).Order("Recorded")

	_, err = dataQuery.GetAll(db.Context, &userData)
	return
}

func (db *DB) GetUserMeta(userId int64) (userMeta []*UserMeta, err error) {

	dataQuery := datastore.NewQuery("UserMeta").Filter("UserId =", userId).Order("Updated")

	_, err = dataQuery.GetAll(db.Context, &userMeta)
	return
}

func (db *DB) GetTotalUsers() (int, error) {

	var metaStats MetaStats

	key := datastore.NewKey(db.Context, "__Stat_Kind_IsRootEntity__", "UserMeta", 0, nil)
	err := datastore.Get(db.Context, key, &metaStats)

	return metaStats.Count, err
}

func (db *DB) GetTop() (data map[string]interface{}) {

	var topOverall, topFollowed, topLooped, topPosts, topRevines []UserRecord

	//top overall
	q := datastore.NewQuery("UserMeta").Order("-Current.Followers").Limit(10)
	q.GetAll(db.Context, &topOverall)

	sort.Sort(ByOverall(topOverall))

	//top followed
	q = datastore.NewQuery("UserMeta").Order("-Current.Followers").Limit(10)
	q.GetAll(db.Context, &topFollowed)

	//top looped
	q = datastore.NewQuery("UserMeta").Order("-Current.Loops").Limit(10)
	q.GetAll(db.Context, &topLooped)

	//top posts
	q = datastore.NewQuery("UserMeta").Order("-Current.AuthoredPosts").Limit(5)
	q.GetAll(db.Context, &topPosts)

	//top Revines
	q = datastore.NewQuery("UserMeta").Order("-Current.Revines").Limit(5)
	q.GetAll(db.Context, &topRevines)

	lastUpdated := db.GetLastUpdated()

	data = map[string]interface{}{
		"topOverall":  topOverall,
		"topFollowed": topFollowed,
		"topLooped":   topLooped,
		"topPosts":    topPosts,
		"topRevines":  topRevines,
		"lastUpdated": lastUpdated,
	}
	return
}

func (a ByOverall) Len() int      { return len(a) }
func (a ByOverall) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByOverall) Less(i, j int) bool {
	return a[i].FollowerCount > a[j].FollowerCount && a[i].LoopCount > a[j].LoopCount && a[i].FollowingCount < a[j].FollowingCount
}

func (a ByFollowers) Len() int      { return len(a) }
func (a ByFollowers) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByFollowers) Less(i, j int) bool {
	return a[i].FollowerCount > a[j].FollowerCount
}

func (a ByLoops) Len() int      { return len(a) }
func (a ByLoops) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByLoops) Less(i, j int) bool {
	return a[i].LoopCount > a[j].LoopCount
}

func (a ByPosts) Len() int      { return len(a) }
func (a ByPosts) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByPosts) Less(i, j int) bool {
	return a[i].PostCount > a[j].PostCount
}

func (a ByRevines) Len() int      { return len(a) }
func (a ByRevines) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByRevines) Less(i, j int) bool {
	return a[i].RevineCount > a[j].RevineCount
}

func (db *DB) GetLastUpdatedUser() *StoredUserData {
	var lastUpdatedUser []*StoredUserData
	q := datastore.NewQuery("UserData").Order("-LastUpdated").Limit(1)
	q.GetAll(db.Context, &lastUpdatedUser)
	if len(lastUpdatedUser) == 0 {
		return nil
	} else {
		return lastUpdatedUser[0]
	}
}

func (db *DB) GetLastUpdated() time.Time {
	lastUpdatedUser := db.GetLastUpdatedUser()
	if lastUpdatedUser == nil {
		return time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
	} else {
		return lastUpdatedUser.LastUpdated
	}
}

func (db *DB) UnqueueUser(user string) {
	var key *datastore.Key
	vineApi := VineRequest{db.Context}
	if vineApi.IsVanity(user) {
		q := datastore.NewQuery("Queue").Filter("UserID =", user).KeysOnly()
		keys, err := q.GetAll(db.Context, nil)
		if err == nil {
			key = keys[0]
		} else {
			db.Context.Errorf("error removing %v from queue: %v", user, err)
		}
	} else {
		userId, _ := strconv.ParseInt(user, 10, 64)
		key = datastore.NewKey(db.Context, "Queue", "", userId, nil)
	}

	datastore.Delete(db.Context, key)
	db.Context.Infof("%v removed from queue.", user)
}

func RandomKey(a []*datastore.Key) *datastore.Key {
	rand.Seed(time.Now().UTC().UnixNano())
	return a[rand.Intn(len(a))]
}

func RemoveDuplicates(a []string) []string {
	found := make(map[string]bool)
	j := 0
	for i, x := range a {
		if !found[x] {
			found[x] = true
			a[j] = a[i]
			j++
		}
	}
	return a[:j]
}
<commit_msg>Removed extra location during userMeta store<commit_after>package main

import (
	"appengine"
	"appengine/datastore"
	"appengine/search"
	"math/rand"
	"sort"
	"strconv"
	"strings"
	"time"
)

type DB struct {
	Context appengine.Context
}

func (db *DB) FetchUser(userId string) {
    //Step 1. Get Vine user's data from the Vine API
	vineApi := VineRequest{db.Context}
	vineUser, err := vineApi.GetUser(userId)

	if err != nil {
		if err.Error() == ErrUserDoesntExist {
			db.UnqueueUser(userId)
		} else {
		    db.Context.Errorf("got error getting user %s from vine: %v", userId, err)
		}
		return
	} else if vineUser == nil {
		db.Context.Errorf("failed fetch on user %v. got err %v", userId, err)
		return
	} else if vineUser.Private == 1 {
	    db.Context.Infof("user %s is private", userId)
		return
	}

	recordKey := datastore.NewKey(db.Context, "UserRecord", "", vineUser.UserId, nil)

    //Step 2. Add user to user search index.
    userIndex := &UserIndex{
		Username:    vineUser.Username,
		Location:    vineUser.Location,
		Description: vineUser.Description,
	}

	if len(vineUser.VanityUrls) != 0 {
		userIndex.VanityUrl = strings.ToLower(vineUser.VanityUrls[0])
	}

	index, err := search.Open("users")
	if err != nil {
		db.Context.Errorf(err.Error())
	} else {
		index.Put(db.Context, vineUser.UserIdStr, userIndex)
	}

    //Step 3. Write records (user {meta, record, data}).
    if userRecord, err := db.GetUserRecord(vineUser.UserId); err == nil {
        var userMeta []*UserMeta

        if vineUser.Username != userRecord.Username {
            userMeta = append(userMeta, &UserMeta{vineUser.UserId, "username", userRecord.Username, time.Now()})
        }

        if vineUser.Location != userRecord.Location {
            userMeta = append(userMeta, &UserMeta{vineUser.UserId, "location", userRecord.Location, time.Now()})
        }

        if vineUser.Description != userRecord.Description {
            userMeta = append(userMeta, &UserMeta{vineUser.UserId, "description", userRecord.Description, time.Now()})
        }

        if (vineUser.Verified != 0) != userRecord.Verified {
            userMeta = append(userMeta, &UserMeta{vineUser.UserId, "verified", strconv.FormatBool(userRecord.Verified), time.Now()})
        }

        var metaKey *datastore.Key
        for _, m := range userMeta {
            metaKey = datastore.NewIncompleteKey(db.Context, "UserMeta", recordKey)
            if key, err := datastore.Put(db.Context, metaKey, m); err != nil {
                db.Context.Errorf("got error storing user meta %s - %v: %v", userId, key, err)
            }
        }
    }

    userRecord := UserRecord{
        UserId: vineUser.UserIdStr,
        Username: vineUser.Username,
        Description: vineUser.Description,
        Location: vineUser.Location,
        ProfileBackground: vineUser.ProfileBackground,
        AvatarUrl: vineUser.AvatarUrl,
        FollowerCount: vineUser.FollowerCount,
        FollowingCount: vineUser.FollowingCount,
        LoopCount: vineUser.LoopCount,
        PostCount: vineUser.AuthoredPostCount,
        RevineCount: (vineUser.PostCount - vineUser.AuthoredPostCount),
        LikeCount: vineUser.LikeCount,
        Private: (vineUser.Private != 0),
        Verified: (vineUser.Verified != 0),
        Explicit: (vineUser.ExplicitContent != 0),
    }
    if len(vineUser.VanityUrls) != 0 {
        userRecord.Vanity = strings.ToLower(vineUser.VanityUrls[0])
    }
    if _, err := datastore.Put(db.Context, recordKey, &userRecord); err != nil {
        db.Context.Errorf("got error storing user record %s: %v", userId, err)
    }

    dataKey := datastore.NewIncompleteKey(db.Context, "UserData", recordKey)
    userData := UserData{
        UserId: vineUser.UserId,
        Recorded: time.Now(),
        Followers: vineUser.FollowerCount,
        Following: vineUser.FollowingCount,
        Loops: vineUser.LoopCount,
        Posts: vineUser.AuthoredPostCount,
        Revines: (vineUser.PostCount - vineUser.AuthoredPostCount),
        Likes: vineUser.LikeCount,
    }
    if key, err := datastore.Put(db.Context, dataKey, &userData); err != nil {
        db.Context.Errorf("got error storing user data %s - %v: %v", userId, key, err)
    }
}

func (db *DB) GetUser(userId int64) (user *UserRecord, err error) {
    user, err = db.GetUserRecord(userId)
    if err != nil {
        db.Context.Infof("error with userRecord")
        return
    }
    user.UserData, err = db.GetUserData(userId)

    if err != nil {
        db.Context.Infof("error with userData")
        return
    }

    user.UserMeta, err = db.GetUserMeta(userId)
    if err != nil {
        db.Context.Infof("error with userMeta")
    }
    return
}

func (db *DB) GetUserRecord(userId int64) (*UserRecord, error) {

    user := UserRecord{}

    recordKey := datastore.NewKey(db.Context, "UserRecord", "", userId, nil)
    err := datastore.Get(db.Context, recordKey, &user)

    if err != nil {
        return nil, err
    } else {
        return &user, nil
    }
}

func (db *DB) GetUserData(userId int64) (userData []*UserData, err error) {

	dataQuery := datastore.NewQuery("UserData").Filter("UserId =", userId).Order("Recorded")

	_, err = dataQuery.GetAll(db.Context, &userData)
	return
}

func (db *DB) GetUserMeta(userId int64) (userMeta []*UserMeta, err error) {

	dataQuery := datastore.NewQuery("UserMeta").Filter("UserId =", userId).Order("Updated")

	_, err = dataQuery.GetAll(db.Context, &userMeta)
	return
}

func (db *DB) GetTotalUsers() (int, error) {

	var metaStats MetaStats

	key := datastore.NewKey(db.Context, "__Stat_Kind_IsRootEntity__", "UserMeta", 0, nil)
	err := datastore.Get(db.Context, key, &metaStats)

	return metaStats.Count, err
}

func (db *DB) GetTop() (data map[string]interface{}) {

	var topOverall, topFollowed, topLooped, topPosts, topRevines []UserRecord

	//top overall
	q := datastore.NewQuery("UserMeta").Order("-Current.Followers").Limit(10)
	q.GetAll(db.Context, &topOverall)

	sort.Sort(ByOverall(topOverall))

	//top followed
	q = datastore.NewQuery("UserMeta").Order("-Current.Followers").Limit(10)
	q.GetAll(db.Context, &topFollowed)

	//top looped
	q = datastore.NewQuery("UserMeta").Order("-Current.Loops").Limit(10)
	q.GetAll(db.Context, &topLooped)

	//top posts
	q = datastore.NewQuery("UserMeta").Order("-Current.AuthoredPosts").Limit(5)
	q.GetAll(db.Context, &topPosts)

	//top Revines
	q = datastore.NewQuery("UserMeta").Order("-Current.Revines").Limit(5)
	q.GetAll(db.Context, &topRevines)

	lastUpdated := db.GetLastUpdated()

	data = map[string]interface{}{
		"topOverall":  topOverall,
		"topFollowed": topFollowed,
		"topLooped":   topLooped,
		"topPosts":    topPosts,
		"topRevines":  topRevines,
		"lastUpdated": lastUpdated,
	}
	return
}

func (a ByOverall) Len() int      { return len(a) }
func (a ByOverall) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByOverall) Less(i, j int) bool {
	return a[i].FollowerCount > a[j].FollowerCount && a[i].LoopCount > a[j].LoopCount && a[i].FollowingCount < a[j].FollowingCount
}

func (a ByFollowers) Len() int      { return len(a) }
func (a ByFollowers) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByFollowers) Less(i, j int) bool {
	return a[i].FollowerCount > a[j].FollowerCount
}

func (a ByLoops) Len() int      { return len(a) }
func (a ByLoops) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByLoops) Less(i, j int) bool {
	return a[i].LoopCount > a[j].LoopCount
}

func (a ByPosts) Len() int      { return len(a) }
func (a ByPosts) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByPosts) Less(i, j int) bool {
	return a[i].PostCount > a[j].PostCount
}

func (a ByRevines) Len() int      { return len(a) }
func (a ByRevines) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByRevines) Less(i, j int) bool {
	return a[i].RevineCount > a[j].RevineCount
}

func (db *DB) GetLastUpdatedUser() *StoredUserData {
	var lastUpdatedUser []*StoredUserData
	q := datastore.NewQuery("UserData").Order("-LastUpdated").Limit(1)
	q.GetAll(db.Context, &lastUpdatedUser)
	if len(lastUpdatedUser) == 0 {
		return nil
	} else {
		return lastUpdatedUser[0]
	}
}

func (db *DB) GetLastUpdated() time.Time {
	lastUpdatedUser := db.GetLastUpdatedUser()
	if lastUpdatedUser == nil {
		return time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
	} else {
		return lastUpdatedUser.LastUpdated
	}
}

func (db *DB) UnqueueUser(user string) {
	var key *datastore.Key
	vineApi := VineRequest{db.Context}
	if vineApi.IsVanity(user) {
		q := datastore.NewQuery("Queue").Filter("UserID =", user).KeysOnly()
		keys, err := q.GetAll(db.Context, nil)
		if err == nil {
			key = keys[0]
		} else {
			db.Context.Errorf("error removing %v from queue: %v", user, err)
		}
	} else {
		userId, _ := strconv.ParseInt(user, 10, 64)
		key = datastore.NewKey(db.Context, "Queue", "", userId, nil)
	}

	datastore.Delete(db.Context, key)
	db.Context.Infof("%v removed from queue.", user)
}

func RandomKey(a []*datastore.Key) *datastore.Key {
	rand.Seed(time.Now().UTC().UnixNano())
	return a[rand.Intn(len(a))]
}

func RemoveDuplicates(a []string) []string {
	found := make(map[string]bool)
	j := 0
	for i, x := range a {
		if !found[x] {
			found[x] = true
			a[j] = a[i]
			j++
		}
	}
	return a[:j]
}
<|endoftext|>