<commit_before>package app

import (
	"fmt"
	"os"
	"os/signal"
	"sync"
	"syscall"

	log "github.com/Sirupsen/logrus"
	"github.com/google/uuid"

	"github.com/ubclaunchpad/cumulus/blockchain"
	"github.com/ubclaunchpad/cumulus/conf"
	"github.com/ubclaunchpad/cumulus/conn"
	"github.com/ubclaunchpad/cumulus/miner"
	"github.com/ubclaunchpad/cumulus/msg"
	"github.com/ubclaunchpad/cumulus/peer"
	"github.com/ubclaunchpad/cumulus/pool"
)

var (
	logFile = os.Stdout
)

const (
	blockQueueSize       = 100
	transactionQueueSize = 100
)

// App contains information about a running instance of a Cumulus node
type App struct {
	CurrentUser *User
	PeerStore   *peer.PeerStore
	Chain       *blockchain.BlockChain
	Pool        *pool.Pool
}

// Responder is used to handle requests who require a response.
type Responder interface {
	Send(ok bool)
	Lock()
	Unlock()
}

// BlockWorkQueue is a queue of blocks to process.
var blockQueue = make(chan *blockchain.Block, blockQueueSize)

// TransactionWorkQueue is a queue of transactions to process.
var transactionQueue = make(chan *blockchain.Transaction, transactionQueueSize)

// QuitChan kills the app worker.
var quitChan = make(chan bool)

// Run sets up and starts a new Cumulus node with the
// given configuration. This should only be called once (except in tests)
func Run(cfg conf.Config) {
	log.Info("Starting Cumulus node")
	config := &cfg

	addr := fmt.Sprintf("%s:%d", config.Interface, config.Port)
	a := App{
		PeerStore:   peer.NewPeerStore(addr),
		CurrentUser: getCurrentUser(),
		Chain:       getLocalChain(),
		Pool:        getLocalPool(),
	}

	// Set logging level
	if cfg.Verbose {
		log.SetLevel(log.DebugLevel)
	}

	// We'll need to wait on at least 2 goroutines (Listen and
	// MaintainConnections) to start before returning
	wg := &sync.WaitGroup{}
	wg.Add(2)

	// Start a goroutine that waits for program termination. Before the program
	// exits it will flush logs and save the blockchain.
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-c
		log.Info("Saving blockchain and flushing logs...")
		// TODO
		logFile.Sync()
		logFile.Close()
		os.Exit(0)
	}()

	// Below we'll connect to peers. After which, requests could begin to
	// stream in. Kick off a worker to handle requests and pushes.
	go a.HandleWork()

	// Set Peer default Push and Request handlers. These functions will handle
	// request and push messages from all peers we connect to unless overridden
	// for specific peers by calls like p.SetRequestHandler(someHandler)
	a.PeerStore.SetDefaultPushHandler(a.PushHandler)
	a.PeerStore.SetDefaultRequestHandler(a.RequestHandler)

	// Start listening on the given interface and port so we can receive
	// conenctions from other peers
	log.Infof("Starting listener on %s:%d", cfg.Interface, cfg.Port)
	a.PeerStore.ListenAddr = addr
	go func() {
		err := conn.Listen(addr, a.PeerStore.ConnectionHandler, wg)
		if err != nil {
			log.WithError(err).Fatalf("Failed to listen on %s", addr)
		}
	}()

	// Try maintain as close to peer.MaxPeers connections as possible while this
	// peer is running
	go a.PeerStore.MaintainConnections(wg)

	// Wait for goroutines to start
	wg.Wait()

	// If the console flag was passed, redirect logs to a file and run the console
	// NOTE: if the log file already exists we will exit with a fatal error here!
	// This should stop people from running multiple Cumulus nodes that will try
	// to log to the same file.
	if cfg.Console {
		logFile, err := os.OpenFile("logfile", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
		if err != nil {
			log.WithError(err).Fatal("Failed to redirect logs to file")
		}
		log.Info("Redirecting logs to logfile")
		log.SetOutput(logFile)
		go RunConsole(a.PeerStore, &a)
	}

	if len(config.Target) > 0 {
		// Connect to the target and discover its peers.
		a.ConnectAndDiscover(cfg.Target)
	}
}

// ConnectAndDiscover tries to connect to a target and discover its peers.
func (a *App) ConnectAndDiscover(target string) {
	peerInfoRequest := msg.Request{
		ID:           uuid.New().String(),
		ResourceType: msg.ResourcePeerInfo,
	}

	log.Infof("Dialing target %s", target)
	p, err := peer.Connect(target, a.PeerStore)
	if err != nil {
		log.WithError(err).Fatal("Failed to dial target")
	}
	p.Request(peerInfoRequest, a.PeerStore.PeerInfoHandler)
}

// RequestHandler is called every time a peer sends us a request message expect
// on peers whos PushHandlers have been overridden.
func (a *App) RequestHandler(req *msg.Request) msg.Response {
	res := msg.Response{ID: req.ID}

	// Build some error types.
	typeErr := msg.NewProtocolError(msg.InvalidResourceType,
		"Invalid resource type")
	notFoundErr := msg.NewProtocolError(msg.ResourceNotFound,
		"Resource not found.")

	switch req.ResourceType {
	case msg.ResourcePeerInfo:
		res.Resource = a.PeerStore.Addrs()
	case msg.ResourceBlock:
		// Block is requested by number.
		blockNumber, ok := req.Params["blockNumber"].(uint32)
		if ok {
			// If its ok, we make try to a copy of it.
			// TODO: Make this CopyBlockByHash.
			blk, err := a.Chain.CopyBlockByIndex(blockNumber)
			if err != nil {
				// Bad index parameter.
				res.Error = notFoundErr
			} else {
				res.Resource = blk
			}
		} else {
			// No index parameter.
			res.Error = notFoundErr
		}
	default:
		// Return err by default.
		res.Error = typeErr
	}

	return res
}

// PushHandler is called every time a peer sends us a Push message except on
// peers whos PushHandlers have been overridden.
func (a *App) PushHandler(push *msg.Push) {
	switch push.ResourceType {
	case msg.ResourceBlock:
		blk, ok := push.Resource.(*blockchain.Block)
		if ok {
			log.Info("Adding block to work queue.")
			blockQueue <- blk
		} else {
			log.Error("Could not cast resource to block.")
		}
	case msg.ResourceTransaction:
		txn, ok := push.Resource.(*blockchain.Transaction)
		if ok {
			log.Info("Adding transaction to work queue.")
			transactionQueue <- txn
		} else {
			log.Error("Could not cast resource to transaction.")
		}
	default:
		// Invalid resource type. Ignore
	}
}

// getLocalChain returns an instance of the blockchain.
func getLocalChain() *blockchain.BlockChain {
	// TODO: Look for local chain on disk. If doesn't exist, go rummaging
	// around on the internets for one.
	bc, _ := blockchain.NewValidTestChainAndBlock()
	return bc
}

// getLocalPool returns an instance of the pool.
func getLocalPool() *pool.Pool {
	// TODO: Look for local pool on disk. If doesn't exist,  make a new one.
	return pool.New()
}

// HandleWork continually collects new work from existing work channels.
func (a *App) HandleWork() {
	log.Debug("Worker waiting for work.")
	for {
		select {
		case work := <-transactionQueue:
			a.HandleTransaction(work)
		case work := <-blockQueue:
			a.HandleBlock(work)
		case <-quitChan:
			return
		}
	}
}

// HandleTransaction handles new instance of TransactionWork.
func (a *App) HandleTransaction(txn *blockchain.Transaction) {
	validTransaction := a.Pool.Set(txn, a.Chain)
	if validTransaction {
		log.Debug("added transaction to pool from address: " + txn.Sender.Repr())
	} else {
		log.Debug("bad transaction rejected from sender: " + txn.Sender.Repr())
	}
}

// HandleBlock handles new instance of BlockWork.
func (a *App) HandleBlock(blk *blockchain.Block) {
	validBlock := a.Pool.Update(blk, a.Chain)

	if validBlock {
		// Append to the chain before requesting
		// the next block so that the block
		// numbers make sense.
		a.Chain.AppendBlock(blk)
		address := a.CurrentUser.Wallet.Public()
		blk := a.Pool.NextBlock(a.Chain, address, a.CurrentUser.BlockSize)
		if miner.IsMining() {
			miner.RestartMiner(a.Chain, blk)
		}
		log.Debug("added blk number %d to chain", blk.BlockNumber)
	}
}
<commit_msg>remove responder<commit_after>package app

import (
	"fmt"
	"os"
	"os/signal"
	"sync"
	"syscall"

	log "github.com/Sirupsen/logrus"
	"github.com/google/uuid"

	"github.com/ubclaunchpad/cumulus/blockchain"
	"github.com/ubclaunchpad/cumulus/conf"
	"github.com/ubclaunchpad/cumulus/conn"
	"github.com/ubclaunchpad/cumulus/miner"
	"github.com/ubclaunchpad/cumulus/msg"
	"github.com/ubclaunchpad/cumulus/peer"
	"github.com/ubclaunchpad/cumulus/pool"
)

var (
	logFile = os.Stdout
)

const (
	blockQueueSize       = 100
	transactionQueueSize = 100
)

// App contains information about a running instance of a Cumulus node
type App struct {
	CurrentUser *User
	PeerStore   *peer.PeerStore
	Chain       *blockchain.BlockChain
	Pool        *pool.Pool
}

// BlockWorkQueue is a queue of blocks to process.
var blockQueue = make(chan *blockchain.Block, blockQueueSize)

// TransactionWorkQueue is a queue of transactions to process.
var transactionQueue = make(chan *blockchain.Transaction, transactionQueueSize)

// QuitChan kills the app worker.
var quitChan = make(chan bool)

// Run sets up and starts a new Cumulus node with the
// given configuration. This should only be called once (except in tests)
func Run(cfg conf.Config) {
	log.Info("Starting Cumulus node")
	config := &cfg

	addr := fmt.Sprintf("%s:%d", config.Interface, config.Port)
	a := App{
		PeerStore:   peer.NewPeerStore(addr),
		CurrentUser: getCurrentUser(),
		Chain:       getLocalChain(),
		Pool:        getLocalPool(),
	}

	// Set logging level
	if cfg.Verbose {
		log.SetLevel(log.DebugLevel)
	}

	// We'll need to wait on at least 2 goroutines (Listen and
	// MaintainConnections) to start before returning
	wg := &sync.WaitGroup{}
	wg.Add(2)

	// Start a goroutine that waits for program termination. Before the program
	// exits it will flush logs and save the blockchain.
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-c
		log.Info("Saving blockchain and flushing logs...")
		// TODO
		logFile.Sync()
		logFile.Close()
		os.Exit(0)
	}()

	// Below we'll connect to peers. After which, requests could begin to
	// stream in. Kick off a worker to handle requests and pushes.
	go a.HandleWork()

	// Set Peer default Push and Request handlers. These functions will handle
	// request and push messages from all peers we connect to unless overridden
	// for specific peers by calls like p.SetRequestHandler(someHandler)
	a.PeerStore.SetDefaultPushHandler(a.PushHandler)
	a.PeerStore.SetDefaultRequestHandler(a.RequestHandler)

	// Start listening on the given interface and port so we can receive
	// conenctions from other peers
	log.Infof("Starting listener on %s:%d", cfg.Interface, cfg.Port)
	a.PeerStore.ListenAddr = addr
	go func() {
		err := conn.Listen(addr, a.PeerStore.ConnectionHandler, wg)
		if err != nil {
			log.WithError(err).Fatalf("Failed to listen on %s", addr)
		}
	}()

	// Try maintain as close to peer.MaxPeers connections as possible while this
	// peer is running
	go a.PeerStore.MaintainConnections(wg)

	// Wait for goroutines to start
	wg.Wait()

	// If the console flag was passed, redirect logs to a file and run the console
	// NOTE: if the log file already exists we will exit with a fatal error here!
	// This should stop people from running multiple Cumulus nodes that will try
	// to log to the same file.
	if cfg.Console {
		logFile, err := os.OpenFile("logfile", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
		if err != nil {
			log.WithError(err).Fatal("Failed to redirect logs to file")
		}
		log.Info("Redirecting logs to logfile")
		log.SetOutput(logFile)
		go RunConsole(a.PeerStore, &a)
	}

	if len(config.Target) > 0 {
		// Connect to the target and discover its peers.
		a.ConnectAndDiscover(cfg.Target)
	}
}

// ConnectAndDiscover tries to connect to a target and discover its peers.
func (a *App) ConnectAndDiscover(target string) {
	peerInfoRequest := msg.Request{
		ID:           uuid.New().String(),
		ResourceType: msg.ResourcePeerInfo,
	}

	log.Infof("Dialing target %s", target)
	p, err := peer.Connect(target, a.PeerStore)
	if err != nil {
		log.WithError(err).Fatal("Failed to dial target")
	}
	p.Request(peerInfoRequest, a.PeerStore.PeerInfoHandler)
}

// RequestHandler is called every time a peer sends us a request message expect
// on peers whos PushHandlers have been overridden.
func (a *App) RequestHandler(req *msg.Request) msg.Response {
	res := msg.Response{ID: req.ID}

	// Build some error types.
	typeErr := msg.NewProtocolError(msg.InvalidResourceType,
		"Invalid resource type")
	notFoundErr := msg.NewProtocolError(msg.ResourceNotFound,
		"Resource not found.")

	switch req.ResourceType {
	case msg.ResourcePeerInfo:
		res.Resource = a.PeerStore.Addrs()
	case msg.ResourceBlock:
		// Block is requested by number.
		blockNumber, ok := req.Params["blockNumber"].(uint32)
		if ok {
			// If its ok, we make try to a copy of it.
			// TODO: Make this CopyBlockByHash.
			blk, err := a.Chain.CopyBlockByIndex(blockNumber)
			if err != nil {
				// Bad index parameter.
				res.Error = notFoundErr
			} else {
				res.Resource = blk
			}
		} else {
			// No index parameter.
			res.Error = notFoundErr
		}
	default:
		// Return err by default.
		res.Error = typeErr
	}

	return res
}

// PushHandler is called every time a peer sends us a Push message except on
// peers whos PushHandlers have been overridden.
func (a *App) PushHandler(push *msg.Push) {
	switch push.ResourceType {
	case msg.ResourceBlock:
		blk, ok := push.Resource.(*blockchain.Block)
		if ok {
			log.Info("Adding block to work queue.")
			blockQueue <- blk
		} else {
			log.Error("Could not cast resource to block.")
		}
	case msg.ResourceTransaction:
		txn, ok := push.Resource.(*blockchain.Transaction)
		if ok {
			log.Info("Adding transaction to work queue.")
			transactionQueue <- txn
		} else {
			log.Error("Could not cast resource to transaction.")
		}
	default:
		// Invalid resource type. Ignore
	}
}

// getLocalChain returns an instance of the blockchain.
func getLocalChain() *blockchain.BlockChain {
	// TODO: Look for local chain on disk. If doesn't exist, go rummaging
	// around on the internets for one.
	bc, _ := blockchain.NewValidTestChainAndBlock()
	return bc
}

// getLocalPool returns an instance of the pool.
func getLocalPool() *pool.Pool {
	// TODO: Look for local pool on disk. If doesn't exist,  make a new one.
	return pool.New()
}

// HandleWork continually collects new work from existing work channels.
func (a *App) HandleWork() {
	log.Debug("Worker waiting for work.")
	for {
		select {
		case work := <-transactionQueue:
			a.HandleTransaction(work)
		case work := <-blockQueue:
			a.HandleBlock(work)
		case <-quitChan:
			return
		}
	}
}

// HandleTransaction handles new instance of TransactionWork.
func (a *App) HandleTransaction(txn *blockchain.Transaction) {
	validTransaction := a.Pool.Set(txn, a.Chain)
	if validTransaction {
		log.Debug("added transaction to pool from address: " + txn.Sender.Repr())
	} else {
		log.Debug("bad transaction rejected from sender: " + txn.Sender.Repr())
	}
}

// HandleBlock handles new instance of BlockWork.
func (a *App) HandleBlock(blk *blockchain.Block) {
	validBlock := a.Pool.Update(blk, a.Chain)

	if validBlock {
		// Append to the chain before requesting
		// the next block so that the block
		// numbers make sense.
		a.Chain.AppendBlock(blk)
		address := a.CurrentUser.Wallet.Public()
		blk := a.Pool.NextBlock(a.Chain, address, a.CurrentUser.BlockSize)
		if miner.IsMining() {
			miner.RestartMiner(a.Chain, blk)
		}
		log.Debug("added blk number %d to chain", blk.BlockNumber)
	}
}
<|endoftext|>


<commit_before>package app

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

//Run function
func Run() {
	http.HandleFunc("/", resquestHandler)
	err := http.ListenAndServe(":8123", nil)
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
	fmt.Println("begin run")

}

func resquestHandler(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path == "/favicon.ico" {
		return
	}
	r.ParseForm()
	data := r.Form["data"]
	if len(data) == 0 {
		return
	}
	var trList []TextRequest
	textRequestJSON := data[0]
	err := json.Unmarshal([]byte(textRequestJSON), &trList)
	if err != nil {
		fmt.Fprintln(w, err)
		return
	}
	for _, tr := range trList {
		log.Printf("%#v", tr)
		InitTextRequest(&tr, r)
		hr, _ := BuildHttpRequest(&tr)
		response, err := SendRequest(hr)
		if err != nil {
			fmt.Fprintln(w, err)
			return
		}
		fmt.Fprintf(w, "%s-------------------------\n", response.Body)
	}
	// tr, err := createTextRequest(textRequestJSON, r)
	// hr, _ := BuildHttpRequest(tr)
	// response, err := SendRequest(hr)
	// if err != nil {
	// 	fmt.Fprintln(w, err)
	// 	return
	// }
	//fmt.Fprintf(w, response.Body)
}

func loadConfig() {

}

func parseParams() {

}
<commit_msg>add multi goruntime request<commit_after>package app

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

//Run function
func Run() {
	http.HandleFunc("/", resquestHandler)
	err := http.ListenAndServe(":8123", nil)
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
	fmt.Println("begin run")

}

func resquestHandler(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path == "/favicon.ico" {
		return
	}
	r.ParseForm()
	data := r.Form["data"]
	if len(data) == 0 {
		return
	}
	var trList []TextRequest
	textRequestJSON := data[0]
	err := json.Unmarshal([]byte(textRequestJSON), &trList)
	if err != nil {
		fmt.Fprintln(w, err)
		return
	}
	chs := []chan int{}
	responses := make([]*TextResponse, len(trList))
	for i, tr := range trList {
		log.Printf("%#v", tr)
		InitTextRequest(&tr, r)
		hr, _ := BuildHttpRequest(&tr)
		ch := make(chan int)
		chs = append(chs, ch)
		go func(i int) {
			response, err := SendRequest(hr)
			log.Printf("get response %d\n", i)
			responses[i] = response
			if err != nil {
				fmt.Fprintln(w, err)
			}
			ch <- 0
		}(i)
	}
	for _, ch := range chs {
		<-ch
	}
	log.Println("get all response")
	for _, response := range responses {
		fmt.Fprintf(w, "%s-------------------------\n", response.Body)

	}

	// tr, err := createTextRequest(textRequestJSON, r)
	// hr, _ := BuildHttpRequest(tr)
	// response, err := SendRequest(hr)
	// if err != nil {
	// 	fmt.Fprintln(w, err)
	// 	return
	// }
	//fmt.Fprintf(w, response.Body)
}

func loadConfig() {

}

func parseParams() {

}
<|endoftext|>


<commit_before>package parse

import "./comb"

const (
	commentChar  = ';'
	invalidChars = "\x00"
	quoteString  = "quote"
	spaceChars   = " \t\n\r"
	specialChars = "()[]{}\"'`$"
)

func Parse(source string) []interface{} {
	m, err := newState(source).module()()

	if err != nil {
		panic(err.Error())
	}

	return m.([]interface{})
}

func (s *state) module() comb.Parser {
	return s.Exhaust(s.Wrap(s.blank(), s.expressions(), s.None()))
}

func (s *state) expressions() comb.Parser {
	return s.Lazy(s.strictExpressions)
}

func (s *state) strictExpressions() comb.Parser {
	return s.Many(s.expression())
}

func (s *state) expression() comb.Parser {
	return s.strip(s.Or(
		s.firstOrderExpression(),
		s.Lazy(func() comb.Parser { return s.quote(s.expression()) })))
}

func (s *state) firstOrderExpression() comb.Parser {
	return s.Or(
		s.identifier(),
		s.stringLiteral(),
		s.sequence("(", ")"),
		s.prepend("list", s.sequence("[", "]")),
		s.prepend("dict", s.sequence("{", "}")),
		s.prepend("set", s.sequence("'{", "}")),
		s.prepend("lambda", s.sequence("'(", ")")))
}

func (s *state) quote(p comb.Parser) comb.Parser {
	return s.And(s.Replace(quoteString, s.Char('`')), p)
}

func (s *state) identifier() comb.Parser {
	return s.stringify(s.Many1(s.NotInString(
		string(commentChar) + invalidChars + spaceChars + specialChars)))
}

func (s *state) stringLiteral() comb.Parser {
	c := s.Char('"')
	f := func(x interface{}) interface{} {
		return []interface{}{quoteString, x}
	}

	return s.App(f, s.stringify(s.Wrap(
		c,
		s.Many(s.Or(s.NotInString("\"\\"), s.String("\\\""), s.String("\\\\"))),
		s.strip(c))))
}

func (s *state) sequence(l, r string) comb.Parser {
	return s.Wrap(s.strip(s.String(l)), s.expressions(), s.strip(s.String(r)))
}

func (s *state) prepend(x interface{}, p comb.Parser) comb.Parser {
	return s.App(func(any interface{}) interface{} {
		return append([]interface{}{x}, any.([]interface{})...)
	}, p)
}

func (s *state) strip(p comb.Parser) comb.Parser {
	b := s.blank()
	return s.Wrap(s.None(), p, b)
}

func (s *state) blank() comb.Parser {
	return s.Void(s.Many(s.Or(s.InString(spaceChars), s.comment())))
}

func (s *state) comment() comb.Parser {
	return s.Void(s.And(
		s.Char(commentChar),
		s.Many(s.NotChar('\n')), s.Char('\n')))
}

func (s *state) stringify(p comb.Parser) comb.Parser {
	return s.App(func(any interface{}) interface{} {
		xs := any.([]interface{})
		rs := make([]rune, len(xs))

		for i, x := range xs {
			rs[i] = x.(rune)
		}

		return string(rs)
	}, p)
}
<commit_msg>Parse identifier more properly<commit_after>package parse

import "./comb"

const (
	commentChar  = ';'
	invalidChars = "\x00"
	quoteString  = "quote"
	spaceChars   = " \t\n\r"
	specialChars = "()[]{}\"'`$"
)

func Parse(source string) []interface{} {
	m, err := newState(source).module()()

	if err != nil {
		panic(err.Error())
	}

	return m.([]interface{})
}

func (s *state) module() comb.Parser {
	return s.Exhaust(s.Wrap(s.blank(), s.expressions(), s.None()))
}

func (s *state) expressions() comb.Parser {
	return s.Lazy(s.strictExpressions)
}

func (s *state) strictExpressions() comb.Parser {
	return s.Many(s.expression())
}

func (s *state) expression() comb.Parser {
	return s.strip(s.Or(
		s.firstOrderExpression(),
		s.Lazy(func() comb.Parser { return s.quote(s.expression()) })))
}

func (s *state) firstOrderExpression() comb.Parser {
	return s.Or(
		s.identifier(),
		s.stringify(s.String("..")),
		s.stringify(s.String(".")),
		s.stringLiteral(),
		s.sequence("(", ")"),
		s.prepend("list", s.sequence("[", "]")),
		s.prepend("dict", s.sequence("{", "}")),
		s.prepend("set", s.sequence("'{", "}")),
		s.prepend("lambda", s.sequence("'(", ")")))
}

func (s *state) quote(p comb.Parser) comb.Parser {
	return s.And(s.Replace(quoteString, s.Char('`')), p)
}

func (s *state) identifier() comb.Parser {
	cs := string(commentChar) + invalidChars + spaceChars + specialChars

	return s.App(func(x interface{}) interface{} {
		xs := x.([]interface{})
		return string(xs[0].(rune)) + xs[1].(string)
	}, s.And(s.NotInString(cs+"."), s.stringify(s.Many(s.NotInString(cs)))))
}

func (s *state) stringLiteral() comb.Parser {
	c := s.Char('"')
	f := func(x interface{}) interface{} {
		return []interface{}{quoteString, x}
	}

	return s.App(f, s.stringify(s.Wrap(
		c,
		s.Many(s.Or(s.NotInString("\"\\"), s.String("\\\""), s.String("\\\\"))),
		s.strip(c))))
}

func (s *state) sequence(l, r string) comb.Parser {
	return s.Wrap(s.strip(s.String(l)), s.expressions(), s.strip(s.String(r)))
}

func (s *state) prepend(x interface{}, p comb.Parser) comb.Parser {
	return s.App(func(any interface{}) interface{} {
		return append([]interface{}{x}, any.([]interface{})...)
	}, p)
}

func (s *state) strip(p comb.Parser) comb.Parser {
	b := s.blank()
	return s.Wrap(s.None(), p, b)
}

func (s *state) blank() comb.Parser {
	return s.Void(s.Many(s.Or(s.InString(spaceChars), s.comment())))
}

func (s *state) comment() comb.Parser {
	return s.Void(s.And(
		s.Char(commentChar),
		s.Many(s.NotChar('\n')), s.Char('\n')))
}

func (s *state) stringify(p comb.Parser) comb.Parser {
	return s.App(func(any interface{}) interface{} {
		xs := any.([]interface{})
		rs := make([]rune, len(xs))

		for i, x := range xs {
			rs[i] = x.(rune)
		}

		return string(rs)
	}, p)
}
<|endoftext|>


<commit_before>// Copyright 2011 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.

// Implementation of Server

package httptest

import (
	"bytes"
	"crypto/tls"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/http/internal"
	"os"
	"runtime"
	"sync"
	"time"
)

// A Server is an HTTP server listening on a system-chosen port on the
// local loopback interface, for use in end-to-end HTTP tests.
type Server struct {
	URL      string // base URL of form http://ipaddr:port with no trailing slash
	Listener net.Listener

	// TLS is the optional TLS configuration, populated with a new config
	// after TLS is started. If set on an unstarted server before StartTLS
	// is called, existing fields are copied into the new config.
	TLS *tls.Config

	// Config may be changed after calling NewUnstartedServer and
	// before Start or StartTLS.
	Config *http.Server

	// wg counts the number of outstanding HTTP requests on this server.
	// Close blocks until all requests are finished.
	wg sync.WaitGroup

	mu     sync.Mutex // guards closed and conns
	closed bool
	conns  map[net.Conn]http.ConnState // except terminal states
}

func newLocalListener() net.Listener {
	if *serve != "" {
		l, err := net.Listen("tcp", *serve)
		if err != nil {
			panic(fmt.Sprintf("httptest: failed to listen on %v: %v", *serve, err))
		}
		return l
	}
	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		if l, err = net.Listen("tcp6", "[::1]:0"); err != nil {
			panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err))
		}
	}
	return l
}

// When debugging a particular http server-based test,
// this flag lets you run
//	go test -run=BrokenTest -httptest.serve=127.0.0.1:8000
// to start the broken server so you can interact with it manually.
var serve = flag.String("httptest.serve", "", "if non-empty, httptest.NewServer serves on this address and blocks")

// NewServer starts and returns a new Server.
// The caller should call Close when finished, to shut it down.
func NewServer(handler http.Handler) *Server {
	ts := NewUnstartedServer(handler)
	ts.Start()
	return ts
}

// NewUnstartedServer returns a new Server but doesn't start it.
//
// After changing its configuration, the caller should call Start or
// StartTLS.
//
// The caller should call Close when finished, to shut it down.
func NewUnstartedServer(handler http.Handler) *Server {
	return &Server{
		Listener: newLocalListener(),
		Config:   &http.Server{Handler: handler},
	}
}

// Start starts a server from NewUnstartedServer.
func (s *Server) Start() {
	if s.URL != "" {
		panic("Server already started")
	}
	s.URL = "http://" + s.Listener.Addr().String()
	s.wrap()
	s.goServe()
	if *serve != "" {
		fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
		select {}
	}
}

// StartTLS starts TLS on a server from NewUnstartedServer.
func (s *Server) StartTLS() {
	if s.URL != "" {
		panic("Server already started")
	}
	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
	if err != nil {
		panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
	}

	existingConfig := s.TLS
	if existingConfig != nil {
		s.TLS = existingConfig.Clone()
	} else {
		s.TLS = new(tls.Config)
	}
	if s.TLS.NextProtos == nil {
		s.TLS.NextProtos = []string{"http/1.1"}
	}
	if len(s.TLS.Certificates) == 0 {
		s.TLS.Certificates = []tls.Certificate{cert}
	}
	s.Listener = tls.NewListener(s.Listener, s.TLS)
	s.URL = "https://" + s.Listener.Addr().String()
	s.wrap()
	s.goServe()
}

// NewTLSServer starts and returns a new Server using TLS.
// The caller should call Close when finished, to shut it down.
func NewTLSServer(handler http.Handler) *Server {
	ts := NewUnstartedServer(handler)
	ts.StartTLS()
	return ts
}

type closeIdleTransport interface {
	CloseIdleConnections()
}

// Close shuts down the server and blocks until all outstanding
// requests on this server have completed.
func (s *Server) Close() {
	s.mu.Lock()
	if !s.closed {
		s.closed = true
		s.Listener.Close()
		s.Config.SetKeepAlivesEnabled(false)
		for c, st := range s.conns {
			// Force-close any idle connections (those between
			// requests) and new connections (those which connected
			// but never sent a request). StateNew connections are
			// super rare and have only been seen (in
			// previously-flaky tests) in the case of
			// socket-late-binding races from the http Client
			// dialing this server and then getting an idle
			// connection before the dial completed. There is thus
			// a connected connection in StateNew with no
			// associated Request. We only close StateIdle and
			// StateNew because they're not doing anything. It's
			// possible StateNew is about to do something in a few
			// milliseconds, but a previous CL to check again in a
			// few milliseconds wasn't liked (early versions of
			// https://golang.org/cl/15151) so now we just
			// forcefully close StateNew. The docs for Server.Close say
			// we wait for "outstanding requests", so we don't close things
			// in StateActive.
			if st == http.StateIdle || st == http.StateNew {
				s.closeConn(c)
			}
		}
		// If this server doesn't shut down in 5 seconds, tell the user why.
		t := time.AfterFunc(5*time.Second, s.logCloseHangDebugInfo)
		defer t.Stop()
	}
	s.mu.Unlock()

	// Not part of httptest.Server's correctness, but assume most
	// users of httptest.Server will be using the standard
	// transport, so help them out and close any idle connections for them.
	if t, ok := http.DefaultTransport.(closeIdleTransport); ok {
		t.CloseIdleConnections()
	}

	s.wg.Wait()
}

func (s *Server) logCloseHangDebugInfo() {
	s.mu.Lock()
	defer s.mu.Unlock()
	var buf bytes.Buffer
	buf.WriteString("httptest.Server blocked in Close after 5 seconds, waiting for connections:\n")
	for c, st := range s.conns {
		fmt.Fprintf(&buf, "  %T %p %v in state %v\n", c, c, c.RemoteAddr(), st)
	}
	log.Print(buf.String())
}

// CloseClientConnections closes any open HTTP connections to the test Server.
func (s *Server) CloseClientConnections() {
	s.mu.Lock()
	nconn := len(s.conns)
	ch := make(chan struct{}, nconn)
	for c := range s.conns {
		s.closeConnChan(c, ch)
	}
	s.mu.Unlock()

	// Wait for outstanding closes to finish.
	//
	// Out of paranoia for making a late change in Go 1.6, we
	// bound how long this can wait, since golang.org/issue/14291
	// isn't fully understood yet. At least this should only be used
	// in tests.
	timer := time.NewTimer(5 * time.Second)
	defer timer.Stop()
	for i := 0; i < nconn; i++ {
		select {
		case <-ch:
		case <-timer.C:
			// Too slow. Give up.
			return
		}
	}
}

func (s *Server) goServe() {
	s.wg.Add(1)
	go func() {
		defer s.wg.Done()
		s.Config.Serve(s.Listener)
	}()
}

// wrap installs the connection state-tracking hook to know which
// connections are idle.
func (s *Server) wrap() {
	oldHook := s.Config.ConnState
	s.Config.ConnState = func(c net.Conn, cs http.ConnState) {
		s.mu.Lock()
		defer s.mu.Unlock()
		switch cs {
		case http.StateNew:
			s.wg.Add(1)
			if _, exists := s.conns[c]; exists {
				panic("invalid state transition")
			}
			if s.conns == nil {
				s.conns = make(map[net.Conn]http.ConnState)
			}
			s.conns[c] = cs
			if s.closed {
				// Probably just a socket-late-binding dial from
				// the default transport that lost the race (and
				// thus this connection is now idle and will
				// never be used).
				s.closeConn(c)
			}
		case http.StateActive:
			if oldState, ok := s.conns[c]; ok {
				if oldState != http.StateNew && oldState != http.StateIdle {
					panic("invalid state transition")
				}
				s.conns[c] = cs
			}
		case http.StateIdle:
			if oldState, ok := s.conns[c]; ok {
				if oldState != http.StateActive {
					panic("invalid state transition")
				}
				s.conns[c] = cs
			}
			if s.closed {
				s.closeConn(c)
			}
		case http.StateHijacked, http.StateClosed:
			s.forgetConn(c)
		}
		if oldHook != nil {
			oldHook(c, cs)
		}
	}
}

// closeConn closes c.
// s.mu must be held.
func (s *Server) closeConn(c net.Conn) { s.closeConnChan(c, nil) }

// closeConnChan is like closeConn, but takes an optional channel to receive a value
// when the goroutine closing c is done.
func (s *Server) closeConnChan(c net.Conn, done chan<- struct{}) {
	if runtime.GOOS == "plan9" {
		// Go's Plan 9 net package isn't great at unblocking reads when
		// their underlying TCP connections are closed. Don't trust
		// that that the ConnState state machine will get to
		// StateClosed. Instead, just go there directly. Plan 9 may leak
		// resources if the syscall doesn't end up returning. Oh well.
		s.forgetConn(c)
	}

	c.Close()
	if done != nil {
		done <- struct{}{}
	}
}

// forgetConn removes c from the set of tracked conns and decrements it from the
// waitgroup, unless it was previously removed.
// s.mu must be held.
func (s *Server) forgetConn(c net.Conn) {
	if _, ok := s.conns[c]; ok {
		delete(s.conns, c)
		s.wg.Done()
	}
}
<commit_msg>net/http/httptest: remove workaround on Plan 9<commit_after>// Copyright 2011 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.

// Implementation of Server

package httptest

import (
	"bytes"
	"crypto/tls"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/http/internal"
	"os"
	"sync"
	"time"
)

// A Server is an HTTP server listening on a system-chosen port on the
// local loopback interface, for use in end-to-end HTTP tests.
type Server struct {
	URL      string // base URL of form http://ipaddr:port with no trailing slash
	Listener net.Listener

	// TLS is the optional TLS configuration, populated with a new config
	// after TLS is started. If set on an unstarted server before StartTLS
	// is called, existing fields are copied into the new config.
	TLS *tls.Config

	// Config may be changed after calling NewUnstartedServer and
	// before Start or StartTLS.
	Config *http.Server

	// wg counts the number of outstanding HTTP requests on this server.
	// Close blocks until all requests are finished.
	wg sync.WaitGroup

	mu     sync.Mutex // guards closed and conns
	closed bool
	conns  map[net.Conn]http.ConnState // except terminal states
}

func newLocalListener() net.Listener {
	if *serve != "" {
		l, err := net.Listen("tcp", *serve)
		if err != nil {
			panic(fmt.Sprintf("httptest: failed to listen on %v: %v", *serve, err))
		}
		return l
	}
	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		if l, err = net.Listen("tcp6", "[::1]:0"); err != nil {
			panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err))
		}
	}
	return l
}

// When debugging a particular http server-based test,
// this flag lets you run
//	go test -run=BrokenTest -httptest.serve=127.0.0.1:8000
// to start the broken server so you can interact with it manually.
var serve = flag.String("httptest.serve", "", "if non-empty, httptest.NewServer serves on this address and blocks")

// NewServer starts and returns a new Server.
// The caller should call Close when finished, to shut it down.
func NewServer(handler http.Handler) *Server {
	ts := NewUnstartedServer(handler)
	ts.Start()
	return ts
}

// NewUnstartedServer returns a new Server but doesn't start it.
//
// After changing its configuration, the caller should call Start or
// StartTLS.
//
// The caller should call Close when finished, to shut it down.
func NewUnstartedServer(handler http.Handler) *Server {
	return &Server{
		Listener: newLocalListener(),
		Config:   &http.Server{Handler: handler},
	}
}

// Start starts a server from NewUnstartedServer.
func (s *Server) Start() {
	if s.URL != "" {
		panic("Server already started")
	}
	s.URL = "http://" + s.Listener.Addr().String()
	s.wrap()
	s.goServe()
	if *serve != "" {
		fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
		select {}
	}
}

// StartTLS starts TLS on a server from NewUnstartedServer.
func (s *Server) StartTLS() {
	if s.URL != "" {
		panic("Server already started")
	}
	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
	if err != nil {
		panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
	}

	existingConfig := s.TLS
	if existingConfig != nil {
		s.TLS = existingConfig.Clone()
	} else {
		s.TLS = new(tls.Config)
	}
	if s.TLS.NextProtos == nil {
		s.TLS.NextProtos = []string{"http/1.1"}
	}
	if len(s.TLS.Certificates) == 0 {
		s.TLS.Certificates = []tls.Certificate{cert}
	}
	s.Listener = tls.NewListener(s.Listener, s.TLS)
	s.URL = "https://" + s.Listener.Addr().String()
	s.wrap()
	s.goServe()
}

// NewTLSServer starts and returns a new Server using TLS.
// The caller should call Close when finished, to shut it down.
func NewTLSServer(handler http.Handler) *Server {
	ts := NewUnstartedServer(handler)
	ts.StartTLS()
	return ts
}

type closeIdleTransport interface {
	CloseIdleConnections()
}

// Close shuts down the server and blocks until all outstanding
// requests on this server have completed.
func (s *Server) Close() {
	s.mu.Lock()
	if !s.closed {
		s.closed = true
		s.Listener.Close()
		s.Config.SetKeepAlivesEnabled(false)
		for c, st := range s.conns {
			// Force-close any idle connections (those between
			// requests) and new connections (those which connected
			// but never sent a request). StateNew connections are
			// super rare and have only been seen (in
			// previously-flaky tests) in the case of
			// socket-late-binding races from the http Client
			// dialing this server and then getting an idle
			// connection before the dial completed. There is thus
			// a connected connection in StateNew with no
			// associated Request. We only close StateIdle and
			// StateNew because they're not doing anything. It's
			// possible StateNew is about to do something in a few
			// milliseconds, but a previous CL to check again in a
			// few milliseconds wasn't liked (early versions of
			// https://golang.org/cl/15151) so now we just
			// forcefully close StateNew. The docs for Server.Close say
			// we wait for "outstanding requests", so we don't close things
			// in StateActive.
			if st == http.StateIdle || st == http.StateNew {
				s.closeConn(c)
			}
		}
		// If this server doesn't shut down in 5 seconds, tell the user why.
		t := time.AfterFunc(5*time.Second, s.logCloseHangDebugInfo)
		defer t.Stop()
	}
	s.mu.Unlock()

	// Not part of httptest.Server's correctness, but assume most
	// users of httptest.Server will be using the standard
	// transport, so help them out and close any idle connections for them.
	if t, ok := http.DefaultTransport.(closeIdleTransport); ok {
		t.CloseIdleConnections()
	}

	s.wg.Wait()
}

func (s *Server) logCloseHangDebugInfo() {
	s.mu.Lock()
	defer s.mu.Unlock()
	var buf bytes.Buffer
	buf.WriteString("httptest.Server blocked in Close after 5 seconds, waiting for connections:\n")
	for c, st := range s.conns {
		fmt.Fprintf(&buf, "  %T %p %v in state %v\n", c, c, c.RemoteAddr(), st)
	}
	log.Print(buf.String())
}

// CloseClientConnections closes any open HTTP connections to the test Server.
func (s *Server) CloseClientConnections() {
	s.mu.Lock()
	nconn := len(s.conns)
	ch := make(chan struct{}, nconn)
	for c := range s.conns {
		s.closeConnChan(c, ch)
	}
	s.mu.Unlock()

	// Wait for outstanding closes to finish.
	//
	// Out of paranoia for making a late change in Go 1.6, we
	// bound how long this can wait, since golang.org/issue/14291
	// isn't fully understood yet. At least this should only be used
	// in tests.
	timer := time.NewTimer(5 * time.Second)
	defer timer.Stop()
	for i := 0; i < nconn; i++ {
		select {
		case <-ch:
		case <-timer.C:
			// Too slow. Give up.
			return
		}
	}
}

func (s *Server) goServe() {
	s.wg.Add(1)
	go func() {
		defer s.wg.Done()
		s.Config.Serve(s.Listener)
	}()
}

// wrap installs the connection state-tracking hook to know which
// connections are idle.
func (s *Server) wrap() {
	oldHook := s.Config.ConnState
	s.Config.ConnState = func(c net.Conn, cs http.ConnState) {
		s.mu.Lock()
		defer s.mu.Unlock()
		switch cs {
		case http.StateNew:
			s.wg.Add(1)
			if _, exists := s.conns[c]; exists {
				panic("invalid state transition")
			}
			if s.conns == nil {
				s.conns = make(map[net.Conn]http.ConnState)
			}
			s.conns[c] = cs
			if s.closed {
				// Probably just a socket-late-binding dial from
				// the default transport that lost the race (and
				// thus this connection is now idle and will
				// never be used).
				s.closeConn(c)
			}
		case http.StateActive:
			if oldState, ok := s.conns[c]; ok {
				if oldState != http.StateNew && oldState != http.StateIdle {
					panic("invalid state transition")
				}
				s.conns[c] = cs
			}
		case http.StateIdle:
			if oldState, ok := s.conns[c]; ok {
				if oldState != http.StateActive {
					panic("invalid state transition")
				}
				s.conns[c] = cs
			}
			if s.closed {
				s.closeConn(c)
			}
		case http.StateHijacked, http.StateClosed:
			s.forgetConn(c)
		}
		if oldHook != nil {
			oldHook(c, cs)
		}
	}
}

// closeConn closes c.
// s.mu must be held.
func (s *Server) closeConn(c net.Conn) { s.closeConnChan(c, nil) }

// closeConnChan is like closeConn, but takes an optional channel to receive a value
// when the goroutine closing c is done.
func (s *Server) closeConnChan(c net.Conn, done chan<- struct{}) {
	c.Close()
	if done != nil {
		done <- struct{}{}
	}
}

// forgetConn removes c from the set of tracked conns and decrements it from the
// waitgroup, unless it was previously removed.
// s.mu must be held.
func (s *Server) forgetConn(c net.Conn) {
	if _, ok := s.conns[c]; ok {
		delete(s.conns, c)
		s.wg.Done()
	}
}
<|endoftext|>


<commit_before>package mastodon

type Account struct {
	Id             string `json:"id"`
	Username       string `json:"username"`
	Acct           string `json:"acct"`
	DisplayName    string `json:"display_name"`
	Note           string `json:"note"`
	Url            string `json:"url"`
	Avatar         string `json:"avatar"`
	Header         string `json:"header"`
	Locked         bool   `json:"locked"`
	CreatedAt      string `json:"created_at"`
	FollowersCount int    `json:"followers_count"`
	FollowingCount int    `json:"following_count"`
	StatusesCount  int    `json:"statuses_count"`
}
<commit_msg>Better package name<commit_after>package toot

type Account struct {
	Id             string `json:"id"`
	Username       string `json:"username"`
	Acct           string `json:"acct"`
	DisplayName    string `json:"display_name"`
	Note           string `json:"note"`
	Url            string `json:"url"`
	Avatar         string `json:"avatar"`
	Header         string `json:"header"`
	Locked         bool   `json:"locked"`
	CreatedAt      string `json:"created_at"`
	FollowersCount int    `json:"followers_count"`
	FollowingCount int    `json:"following_count"`
	StatusesCount  int    `json:"statuses_count"`
}
<|endoftext|>


<commit_before>// Copyright 2014 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.

// +build linux,!android

package app

/*
Simple on-screen app debugging for X11. Not an officially supported
development target for apps, as screens with mice are very different
than screens with touch panels.

On Ubuntu 14.04 'Trusty', you may have to install these libraries:
sudo apt-get install libegl1-mesa-dev libgles2-mesa-dev libx11-dev
*/

/*
#cgo LDFLAGS: -lEGL -lGLESv2 -lX11

void createWindow(void);
void processEvents(void);
void swapBuffers(void);
*/
import "C"
import (
	"runtime"
	"time"

	"golang.org/x/mobile/event/lifecycle"
	"golang.org/x/mobile/event/paint"
	"golang.org/x/mobile/event/size"
	"golang.org/x/mobile/event/touch"
	"golang.org/x/mobile/geom"
	"golang.org/x/mobile/gl"
)

func init() {
	theApp.registerGLViewportFilter()
}

func main(f func(App)) {
	runtime.LockOSThread()

	var worker gl.Worker
	glctx, worker = gl.NewContext()
	workAvailable := worker.WorkAvailable()

	C.createWindow()

	// TODO: send lifecycle events when e.g. the X11 window is iconified or moved off-screen.
	theApp.sendLifecycle(lifecycle.StageFocused)

	// TODO: translate X11 expose events to shiny paint events, instead of
	// sending this synthetic paint event as a hack.
	theApp.eventsIn <- paint.Event{}

	donec := make(chan struct{})
	go func() {
		f(theApp)
		close(donec)
	}()

	// TODO: can we get the actual vsync signal?
	ticker := time.NewTicker(time.Second / 60)
	defer ticker.Stop()
	var tc <-chan time.Time

	for {
		select {
		case <-donec:
			return
		case <-workAvailable:
			worker.DoWork()
		case <-theApp.publish:
			C.swapBuffers()
			tc = ticker.C
		case <-tc:
			tc = nil
			theApp.publishResult <- PublishResult{}
		}
		C.processEvents()
	}
}

//export onResize
func onResize(w, h int) {
	// TODO(nigeltao): don't assume 72 DPI. DisplayWidth and DisplayWidthMM
	// is probably the best place to start looking.
	pixelsPerPt := float32(1)
	theApp.eventsIn <- size.Event{
		WidthPx:     w,
		HeightPx:    h,
		WidthPt:     geom.Pt(w),
		HeightPt:    geom.Pt(h),
		PixelsPerPt: pixelsPerPt,
	}
}

func sendTouch(t touch.Type, x, y float32) {
	theApp.eventsIn <- touch.Event{
		X:        x,
		Y:        y,
		Sequence: 0, // TODO: button??
		Type:     t,
	}
}

//export onTouchBegin
func onTouchBegin(x, y float32) { sendTouch(touch.TypeBegin, x, y) }

//export onTouchMove
func onTouchMove(x, y float32) { sendTouch(touch.TypeMove, x, y) }

//export onTouchEnd
func onTouchEnd(x, y float32) { sendTouch(touch.TypeEnd, x, y) }

var stopped bool

//export onStop
func onStop() {
	if stopped {
		return
	}
	stopped = true
	theApp.sendLifecycle(lifecycle.StageDead)
	theApp.eventsIn <- stopPumping{}
}
<commit_msg>app: fix x11.go broken after cl/15460.<commit_after>// Copyright 2014 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.

// +build linux,!android

package app

/*
Simple on-screen app debugging for X11. Not an officially supported
development target for apps, as screens with mice are very different
than screens with touch panels.

On Ubuntu 14.04 'Trusty', you may have to install these libraries:
sudo apt-get install libegl1-mesa-dev libgles2-mesa-dev libx11-dev
*/

/*
#cgo LDFLAGS: -lEGL -lGLESv2 -lX11

void createWindow(void);
void processEvents(void);
void swapBuffers(void);
*/
import "C"
import (
	"runtime"
	"time"

	"golang.org/x/mobile/event/lifecycle"
	"golang.org/x/mobile/event/paint"
	"golang.org/x/mobile/event/size"
	"golang.org/x/mobile/event/touch"
	"golang.org/x/mobile/geom"
)

func init() {
	theApp.registerGLViewportFilter()
}

func main(f func(App)) {
	runtime.LockOSThread()

	workAvailable := theApp.worker.WorkAvailable()

	C.createWindow()

	// TODO: send lifecycle events when e.g. the X11 window is iconified or moved off-screen.
	theApp.sendLifecycle(lifecycle.StageFocused)

	// TODO: translate X11 expose events to shiny paint events, instead of
	// sending this synthetic paint event as a hack.
	theApp.eventsIn <- paint.Event{}

	donec := make(chan struct{})
	go func() {
		f(theApp)
		close(donec)
	}()

	// TODO: can we get the actual vsync signal?
	ticker := time.NewTicker(time.Second / 60)
	defer ticker.Stop()
	var tc <-chan time.Time

	for {
		select {
		case <-donec:
			return
		case <-workAvailable:
			theApp.worker.DoWork()
		case <-theApp.publish:
			C.swapBuffers()
			tc = ticker.C
		case <-tc:
			tc = nil
			theApp.publishResult <- PublishResult{}
		}
		C.processEvents()
	}
}

//export onResize
func onResize(w, h int) {
	// TODO(nigeltao): don't assume 72 DPI. DisplayWidth and DisplayWidthMM
	// is probably the best place to start looking.
	pixelsPerPt := float32(1)
	theApp.eventsIn <- size.Event{
		WidthPx:     w,
		HeightPx:    h,
		WidthPt:     geom.Pt(w),
		HeightPt:    geom.Pt(h),
		PixelsPerPt: pixelsPerPt,
	}
}

func sendTouch(t touch.Type, x, y float32) {
	theApp.eventsIn <- touch.Event{
		X:        x,
		Y:        y,
		Sequence: 0, // TODO: button??
		Type:     t,
	}
}

//export onTouchBegin
func onTouchBegin(x, y float32) { sendTouch(touch.TypeBegin, x, y) }

//export onTouchMove
func onTouchMove(x, y float32) { sendTouch(touch.TypeMove, x, y) }

//export onTouchEnd
func onTouchEnd(x, y float32) { sendTouch(touch.TypeEnd, x, y) }

var stopped bool

//export onStop
func onStop() {
	if stopped {
		return
	}
	stopped = true
	theApp.sendLifecycle(lifecycle.StageDead)
	theApp.eventsIn <- stopPumping{}
}
<|endoftext|>


<commit_before>package main

// Applet imports
import (
    "./applets/cal"
	"./applets/cat"
	"./applets/chroot"
    "./applets/checksum"
    "./applets/date"
	"./applets/echo"
	"./applets/grep"
	"./applets/gzip"
	"./applets/head"
	"./applets/httpd"
	"./applets/kill"
	"./applets/ls"
	"./applets/mkdir"
	"./applets/mknod"
	"./applets/mount"
	"./applets/ps"
	"./applets/rm"
	"./applets/shell"
    "./applets/strings"
	"./applets/telnetd"
    "./applets/touch"
    "./applets/tar"
    "./applets/spipe"
	"./applets/umount"
    "./applets/wc"
	"./applets/wget"
)

// This map contains the mappings from callname
// to applet function.
var Applets map[string]Applet = map[string]Applet{
	"echo":      echo.Echo,
	"shell":     shell.Shell,
	"spipe":     spipe.Spipe,
	"spiped":    spipe.Spiped,
	"strings":   strings.Strings,
	"telnetd":   telnetd.Telnetd,
	"touch":     touch.Touch,
	"md5sum":    checksum.Hash,
	"sha1sum":   checksum.Hash,
	"sha256sum": checksum.Hash,
	"sha512sum": checksum.Hash,
	"crc32":     checksum.Hash,
	"ls":        ls.Ls,
	"rm":        rm.Rm,
	"httpd":     httpd.Httpd,
	"wget":      wget.Wget,
	"tar":       tar.Tar,
	"wc":        wc.Wc,
	"kill":      kill.Kill,
	"cat":       cat.Cat,
	"cal":       cal.Cal,
	"mknod":     mknod.Mknod,
	"mount":     mount.Mount,
	"umount":    umount.Umount,
	"chroot":    chroot.Chroot,
	"ps":        ps.Ps,
	"mkdir":     mkdir.Mkdir,
	"head":      head.Head,
	"grep":      grep.Grep,
	"gzip":      gzip.Gzip,
	"gunzip":    gzip.Gunzip,
	"zcat":      gzip.Zcat,
	"date":      date.Date,
}

// Signature of applet functions.
// call is like os.Argv, and therefore contains the
// name of the applet itself in call[0].
// If the returned error is not nil, it is printed
// to stdout.
type Applet func(call []string) error
<commit_msg>Add sh<commit_after>package main

// Applet imports
import (
    "./applets/cal"
	"./applets/cat"
	"./applets/chroot"
    "./applets/checksum"
    "./applets/date"
	"./applets/echo"
	"./applets/grep"
	"./applets/gzip"
	"./applets/head"
	"./applets/httpd"
	"./applets/kill"
	"./applets/ls"
	"./applets/mkdir"
	"./applets/mknod"
	"./applets/mount"
	"./applets/ps"
	"./applets/rm"
	"./applets/shell"
    "./applets/strings"
	"./applets/telnetd"
    "./applets/touch"
    "./applets/tar"
    "./applets/spipe"
	"./applets/umount"
    "./applets/wc"
	"./applets/wget"
)

// This map contains the mappings from callname
// to applet function.
var Applets map[string]Applet = map[string]Applet{
	"echo":      echo.Echo,
	"shell":     shell.Shell,
    "sh":        shell.Shell,
	"spipe":     spipe.Spipe,
	"spiped":    spipe.Spiped,
	"strings":   strings.Strings,
	"telnetd":   telnetd.Telnetd,
	"touch":     touch.Touch,
	"md5sum":    checksum.Hash,
	"sha1sum":   checksum.Hash,
	"sha256sum": checksum.Hash,
	"sha512sum": checksum.Hash,
	"crc32":     checksum.Hash,
	"ls":        ls.Ls,
	"rm":        rm.Rm,
	"httpd":     httpd.Httpd,
	"wget":      wget.Wget,
	"tar":       tar.Tar,
	"wc":        wc.Wc,
	"kill":      kill.Kill,
	"cat":       cat.Cat,
	"cal":       cal.Cal,
	"mknod":     mknod.Mknod,
	"mount":     mount.Mount,
	"umount":    umount.Umount,
	"chroot":    chroot.Chroot,
	"ps":        ps.Ps,
	"mkdir":     mkdir.Mkdir,
	"head":      head.Head,
	"grep":      grep.Grep,
	"gzip":      gzip.Gzip,
	"gunzip":    gzip.Gunzip,
	"zcat":      gzip.Zcat,
	"date":      date.Date,
}

// Signature of applet functions.
// call is like os.Argv, and therefore contains the
// name of the applet itself in call[0].
// If the returned error is not nil, it is printed
// to stdout.
type Applet func(call []string) error
<|endoftext|>


<commit_before>#!/bin/bash
#
# The "build" function below will later build a binary from a preprocessed
# source file. When "build" is called, these variables are set:
#
# - SOURCE:  the full path of the source file.
# - PREPROCESSED_SOURCE: the full path of the preprocessed source file,
#            i.e. without the leading #! line
# - BINARY:  the full path of the binary. The build function must generate
#            this file.
# - JITOS:   the host operating system
# - JITARCH: the host architecture.
#
function build() {
  # -- prepare go packages if needed.
  if [ -z "${GOPATH:-}" ]; then
    export GOPATH=$HOME/jit.golang
  fi

  local packages=$(
    < $SOURCE grep "// JIT_GO_PACKAGES="     | sed "sx// JIT_GO_PACKAGES=xx"
  )

  for package in "$packages" ; do
    go get $package
  done

  if [[ $JIT_DIST_BUILD = y ]]; then
    log "Building for distribution"
    local platforms=${JIT_GO_TARGET_PLATFORMS:-darwin.amd64 linux.amd64 linux.arm linux.386}
  else
    local platforms=$JITOS.$JITARCH
  fi

  local packages=$(
    < $SOURCE grep "// JIT_GO_PACKAGES="     | sed "sx// JIT_GO_PACKAGES=xx"
  )

  for package in "$packages" ; do
    go get $package
  done

  local binary_base=$(echo $BINARY | sed 's-[.][^.]*[.][^.]*$--')

  local platform
  for platform in $platforms ; do
    local goos=$(cut -d . -f 1 <<<$platform)
    local goarch=$(cut -d . -f 2 <<<$platform)
	if ! env GOARCH=$goarch GOOS=$goos go build -ldflags "-s" -o $binary_base.$goos.$goarch $PREPROCESSED_SOURCE ; then
		exit 1
	fi

	log Built $binary_base.$goos.$goarch
  done
}

JIT_EXT=go
JIT_DIST_SUPPORT=y
jit_inc=$(<<<"$0" sed 's-[.][^.]*$-.inc-')
. "$jit_inc"
<commit_msg>jit.go: improve logging<commit_after>#!/bin/bash
#
# The "build" function below will later build a binary from a preprocessed
# source file. When "build" is called, these variables are set:
#
# - SOURCE:  the full path of the source file.
# - PREPROCESSED_SOURCE: the full path of the preprocessed source file,
#            i.e. without the leading #! line
# - BINARY:  the full path of the binary. The build function must generate
#            this file.
# - JITOS:   the host operating system
# - JITARCH: the host architecture.
#
function build() {
  # -- prepare go packages if needed.
  if [ -z "${GOPATH:-}" ]; then
    export GOPATH=$HOME/jit.golang
  fi

  local packages=$(
    < $SOURCE grep "// JIT_GO_PACKAGES="     | sed "sx// JIT_GO_PACKAGES=xx"
  )

  for package in "$packages" ; do
    log env GOPATH=$GOPATH go get $package
    go get $package
  done

  if [[ $JIT_DIST_BUILD = y ]]; then
    log "Building for distribution"
    local platforms=${JIT_GO_TARGET_PLATFORMS:-darwin.amd64 linux.amd64 linux.arm linux.386}
  else
    local platforms=$JITOS.$JITARCH
  fi

  local packages=$(
    < $SOURCE grep "// JIT_GO_PACKAGES="     | sed "sx// JIT_GO_PACKAGES=xx"
  )

  for package in "$packages" ; do
    go get $package
  done

  local binary_base=$(echo $BINARY | sed 's-[.][^.]*[.][^.]*$--')

  local platform
  for platform in $platforms ; do
    local goos=$(cut -d . -f 1 <<<$platform)
    local goarch=$(cut -d . -f 2 <<<$platform)
	if ! env GOARCH=$goarch GOOS=$goos go build -ldflags "-s" -o $binary_base.$goos.$goarch $PREPROCESSED_SOURCE ; then
		exit 1
	fi

	log Built $binary_base.$goos.$goarch
  done
}

JIT_EXT=go
JIT_DIST_SUPPORT=y
jit_inc=$(<<<"$0" sed 's-[.][^.]*$-.inc-')
. "$jit_inc"
<|endoftext|>


<commit_before>// Code generated by go-bindata.
// sources:
// template/method.tmpl
// template/struct.tmpl
// DO NOT EDIT!

package main

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

func bindataRead(data []byte, name string) ([]byte, error) {
	gz, err := gzip.NewReader(bytes.NewBuffer(data))
	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}

	var buf bytes.Buffer
	_, err = io.Copy(&buf, gz)
	clErr := gz.Close()

	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}
	if clErr != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

type asset struct {
	bytes []byte
	info  os.FileInfo
}

type bindataFileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
}

func (fi bindataFileInfo) Name() string {
	return fi.name
}
func (fi bindataFileInfo) Size() int64 {
	return fi.size
}
func (fi bindataFileInfo) Mode() os.FileMode {
	return fi.mode
}
func (fi bindataFileInfo) ModTime() time.Time {
	return fi.modTime
}
func (fi bindataFileInfo) IsDir() bool {
	return false
}
func (fi bindataFileInfo) Sys() interface{} {
	return nil
}

var _templateMethodTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\x52\xc1\x4e\xe3\x30\x10\x3d\xd7\x5f\x31\xdb\xc3\x2a\x59\x65\xdd\xfb\x4a\x3d\x2c\x08\x2a\x24\x84\x5a\x82\xc4\x91\x3a\xc9\x44\x44\xa4\x0e\x1a\x3b\x40\x15\xf5\xdf\x19\x27\xa1\x35\x6d\x4a\xb9\x30\xa7\x2a\x7e\xf3\xe6\xf5\xbd\x37\x99\xc0\x39\xa1\xb2\x08\x85\x36\x48\xd6\x80\x7d\x44\x68\x1a\x90\xb1\xa5\x3a\xb5\xf2\x46\xad\x10\x36\x1b\xb0\x55\xfb\x92\x29\xab\x12\x65\x50\x8a\xbc\xd6\x29\x04\x04\x7f\x0e\xc1\x61\xcf\x19\x64\x09\x2c\x6a\xa4\x35\x52\x08\x48\x54\x11\x34\x02\x78\x9a\xe6\x2f\x14\xf9\x76\xed\x4e\x25\x25\xca\xff\xb5\xad\x66\xa8\xe7\x4f\xcc\xd0\xa2\xdc\xf0\x16\xfc\x9b\x42\x96\xc8\x96\xe8\xb6\x7a\x0d\xb6\x6f\x6e\x96\x7c\x3d\x6d\x8f\x5d\xb5\xfa\xe3\xc5\xf5\x07\x2d\xd3\x2c\xa3\x4f\xe0\x3d\xec\x5c\x91\x5a\x19\x0f\x1e\xca\x38\x55\x3a\xd8\xa7\xe4\x6f\x3e\x68\xfb\x0f\xb0\x34\xe8\x6b\x7d\x88\x3c\xb9\x17\x6f\x98\xfe\xa4\xd4\x9d\x0a\x9d\x39\x11\x23\xf6\xd3\x5d\xff\x35\x05\x5d\x94\xbd\xcf\x6e\x08\x6d\x4d\xba\xb3\xdf\xc8\x7b\x52\xcf\x01\xff\x8e\x60\x9c\xab\xa2\xc4\xcc\x05\xdb\x45\xef\xa7\xde\x25\xd2\xc7\x39\x0e\xc5\x88\x0f\xf4\x44\xcc\x2e\x36\x42\x70\x71\x66\x68\x0f\xb3\x3f\x5b\x73\x80\x06\x4b\x64\x99\x47\xaa\x94\x53\xb5\x1a\x2a\xd3\x51\x3e\xaf\x47\xd1\xce\x99\xb8\x3d\xe2\xde\x2f\x79\xfb\xd0\x21\x08\x06\xaa\x19\x75\x46\x84\xbd\x41\x2f\x8a\x80\x06\x34\x8a\x53\xdd\x5b\x0e\xc8\x38\x1a\xe8\x30\xf6\x64\xfd\x3c\xf4\x7e\x05\x4f\xa5\xcd\x1f\xa3\x2f\x23\xef\x13\xfa\x5e\xe4\xbf\x79\xb7\x8b\xfd\x3d\x00\x00\xff\xff\x73\x42\xea\x28\x2f\x04\x00\x00")

func templateMethodTmplBytes() ([]byte, error) {
	return bindataRead(
		_templateMethodTmpl,
		"template/method.tmpl",
	)
}

func templateMethodTmpl() (*asset, error) {
	bytes, err := templateMethodTmplBytes()
	if err != nil {
		return nil, err
	}

	info := bindataFileInfo{name: "template/method.tmpl", size: 1071, mode: os.FileMode(420), modTime: time.Unix(1470827139, 0)}
	a := &asset{bytes: bytes, info: info}
	return a, nil
}

var _templateStructTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd2\xd7\x57\xa8\xae\x56\xd0\x0b\x2e\x29\x2a\x4d\x2e\xd1\xf3\x4b\xcc\x4d\x55\xa8\xad\x55\x28\x4a\x2d\x28\x4a\x2d\x4e\xcd\x2b\x29\x46\x96\x0d\x49\x4c\xca\x49\xd5\x0b\x4e\xce\x48\xcd\x4d\x04\xaa\xd2\xc3\x90\x82\x6a\xe7\x2a\xa9\x2c\x48\xc5\x66\x6c\x31\x98\xab\x50\xcd\x55\x5d\xad\xab\x50\x94\x98\x97\x9e\x0a\x57\xe2\x96\x99\x9a\x93\x52\x0c\xd2\xcc\x09\xd2\x08\xd3\x01\x62\x87\x80\x4c\x03\xb2\xa1\x4e\x75\xce\xcf\x29\xcd\xcd\x83\xdb\x05\x32\x2a\x35\x2f\x05\xc4\xac\xe5\x02\x04\x00\x00\xff\xff\xc1\x7f\x9b\xb1\xce\x00\x00\x00")

func templateStructTmplBytes() ([]byte, error) {
	return bindataRead(
		_templateStructTmpl,
		"template/struct.tmpl",
	)
}

func templateStructTmpl() (*asset, error) {
	bytes, err := templateStructTmplBytes()
	if err != nil {
		return nil, err
	}

	info := bindataFileInfo{name: "template/struct.tmpl", size: 206, mode: os.FileMode(420), modTime: time.Unix(1470827139, 0)}
	a := &asset{bytes: bytes, info: info}
	return a, nil
}

// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
		}
		return a.bytes, nil
	}
	return nil, fmt.Errorf("Asset %s not found", name)
}

// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
func MustAsset(name string) []byte {
	a, err := Asset(name)
	if err != nil {
		panic("asset: Asset(" + name + "): " + err.Error())
	}

	return a
}

// AssetInfo loads and returns the asset info for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
		}
		return a.info, nil
	}
	return nil, fmt.Errorf("AssetInfo %s not found", name)
}

// AssetNames returns the names of the assets.
func AssetNames() []string {
	names := make([]string, 0, len(_bindata))
	for name := range _bindata {
		names = append(names, name)
	}
	return names
}

// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
	"template/method.tmpl": templateMethodTmpl,
	"template/struct.tmpl": templateStructTmpl,
}

// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
//     data/
//       foo.txt
//       img/
//         a.png
//         b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
	node := _bintree
	if len(name) != 0 {
		cannonicalName := strings.Replace(name, "\\", "/", -1)
		pathList := strings.Split(cannonicalName, "/")
		for _, p := range pathList {
			node = node.Children[p]
			if node == nil {
				return nil, fmt.Errorf("Asset %s not found", name)
			}
		}
	}
	if node.Func != nil {
		return nil, fmt.Errorf("Asset %s not found", name)
	}
	rv := make([]string, 0, len(node.Children))
	for childName := range node.Children {
		rv = append(rv, childName)
	}
	return rv, nil
}

type bintree struct {
	Func     func() (*asset, error)
	Children map[string]*bintree
}
var _bintree = &bintree{nil, map[string]*bintree{
	"template": &bintree{nil, map[string]*bintree{
		"method.tmpl": &bintree{templateMethodTmpl, map[string]*bintree{}},
		"struct.tmpl": &bintree{templateStructTmpl, map[string]*bintree{}},
	}},
}}

// RestoreAsset restores an asset under the given directory
func RestoreAsset(dir, name string) error {
	data, err := Asset(name)
	if err != nil {
		return err
	}
	info, err := AssetInfo(name)
	if err != nil {
		return err
	}
	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
	if err != nil {
		return err
	}
	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
	if err != nil {
		return err
	}
	return nil
}

// RestoreAssets restores an asset under the given directory recursively
func RestoreAssets(dir, name string) error {
	children, err := AssetDir(name)
	// File
	if err != nil {
		return RestoreAsset(dir, name)
	}
	// Dir
	for _, child := range children {
		err = RestoreAssets(dir, filepath.Join(name, child))
		if err != nil {
			return err
		}
	}
	return nil
}

func _filePath(dir, name string) string {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}

<commit_msg>Run 'go-bindata template/' to generate bindata.go<commit_after>package main

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"strings"
)

func bindata_read(data []byte, name string) ([]byte, error) {
	gz, err := gzip.NewReader(bytes.NewBuffer(data))
	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}

	var buf bytes.Buffer
	_, err = io.Copy(&buf, gz)
	gz.Close()

	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}

	return buf.Bytes(), nil
}

var _template_method_tmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x93\x4f\x8f\xd3\x30\x10\xc5\xcf\xf5\xa7\x18\xf6\x80\x12\x64\xdc\x3b\xd2\x1e\xd8\x15\xac\x90\x56\xa8\x25\x48\x1c\x59\xc7\x99\x40\xd4\xd4\x41\x13\x07\xba\x8a\xf2\xdd\x91\x1d\xb7\x38\x7f\x4a\x7a\x28\xf8\x52\xa9\x9e\x8c\x7f\xf3\xde\x9b\xf5\x1a\xee\x09\xa5\x41\x28\x74\x8d\x64\x6a\x30\xdf\x11\xda\x16\x44\x62\xa8\x51\x46\x7c\x94\x7b\x84\xae\x03\x53\xb9\x9b\x4c\x1a\x99\xca\x1a\x05\xcb\x1b\xad\x20\x22\x78\x35\x2d\x8e\x7d\xcf\x28\x4b\x61\xdb\x20\x3d\x23\xc5\x80\x44\x15\x41\xcb\x00\x08\x4d\x43\x1a\x48\xf4\x55\xf7\x95\x36\x78\x30\x91\xea\x7f\xc5\x9d\x54\xbb\x6f\x54\x35\x3a\x8b\x62\x0e\x59\x1a\xb3\x8e\xb1\xf5\x1a\x1e\xd0\x4c\x9f\xba\x7b\xde\xec\xa0\xc6\x12\x95\x39\x47\x9e\x53\xb5\x9f\x63\x3f\xdb\x2f\xc0\xe6\xb6\xa1\x72\x98\x89\x7b\xc4\xde\xbf\x6f\xb4\xda\x48\x92\xfb\xfa\xf8\xb5\x9b\x39\x9a\x51\x82\xf7\x63\xc7\xe1\xdc\x67\xdf\x5d\x12\x62\x16\x26\xd9\x3e\x4e\x59\xbc\x62\x03\x7d\xff\x85\xc1\x27\x62\x73\x80\x23\xb5\xff\xcf\x02\xcf\x99\x0f\xd0\xb6\xaf\xa1\xc8\x4f\x2d\x3f\xcb\xb4\x44\xf1\xb6\x31\xd5\x03\xea\xcd\x0e\xba\xce\x55\xd9\x83\x44\xf0\xe6\x16\xb2\x54\xb8\x46\x9f\xaa\x5f\xc1\x83\x1c\x4e\x75\xf6\x3c\x9d\xb4\xf9\xe0\xe6\x4c\xb6\x8f\x81\x22\x4f\x7c\x50\x3c\xaa\x9d\x0a\x28\x12\x25\x75\x34\x6e\xa9\xa4\x1e\xa8\x7c\x9c\x06\xcb\x1a\x43\xee\xaf\x3c\x40\x7f\x77\x40\xf5\xbf\xb0\xff\x10\xe9\xcc\x02\xad\x8a\xdc\x91\xbc\xb8\x05\x5d\x94\x5e\x7f\x7b\x7c\x14\x9d\x2d\xb5\xf8\x42\xf2\x47\x84\x44\x1c\x6e\x72\x59\x94\x98\xd9\x30\xf4\x71\x09\x93\xd2\x3b\xe5\x23\x70\x13\xb3\x55\xc7\x56\xbe\x91\x2e\xca\xa5\x2d\x3d\xc6\xf0\xca\xcb\x7a\x61\x04\xaf\xba\xc8\x00\x3f\x25\x01\xcd\xf0\xb3\xe5\xd8\xb2\xa9\xf5\x83\x6d\x9e\xb7\xff\xd2\xcd\x1f\x05\x37\xa8\x1e\x87\x77\x29\x1b\xba\x28\xf9\x5f\x03\xe2\x8d\xbc\x2c\x20\x2f\x89\xfb\x90\xfc\x0e\x00\x00\xff\xff\x8d\xa6\xc3\x96\x72\x06\x00\x00")

func template_method_tmpl() ([]byte, error) {
	return bindata_read(
		_template_method_tmpl,
		"template/method.tmpl",
	)
}

var _template_struct_tmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x8e\x41\x0a\xc2\x30\x10\x45\xd7\xe6\x14\xff\x02\xa6\x87\x10\x5c\xba\x69\x2f\x10\xdb\x8f\x0a\x49\x2c\x49\xba\x90\x61\xee\x2e\x23\xb5\x08\x76\xf7\x87\x3f\xef\xcd\x74\x1d\x44\xe0\xfb\x56\x96\xb1\xf9\x4b\x48\x84\x2a\x0a\xe7\xc2\xca\xdc\xea\x6f\x3b\x84\x6b\xa4\xef\xc7\x3b\x53\x80\xaa\xff\xab\x56\xdc\xb5\xd7\xcc\x3d\x6d\xfd\x8c\x10\x27\x72\x44\x09\xf9\xc6\x6d\xe5\xfc\x60\x9c\xaa\xc1\x07\x03\xbf\x84\xe5\xc1\x6c\xaa\x58\x5f\x3d\x3d\xe3\x92\xf2\x76\xcb\x54\xcc\x93\x45\x75\xef\x00\x00\x00\xff\xff\xc1\x7f\x9b\xb1\xce\x00\x00\x00")

func template_struct_tmpl() ([]byte, error) {
	return bindata_read(
		_template_struct_tmpl,
		"template/struct.tmpl",
	)
}

// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		return f()
	}
	return nil, fmt.Errorf("Asset %s not found", name)
}

// AssetNames returns the names of the assets.
func AssetNames() []string {
	names := make([]string, 0, len(_bindata))
	for name := range _bindata {
		names = append(names, name)
	}
	return names
}

// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() ([]byte, error){
	"template/method.tmpl": template_method_tmpl,
	"template/struct.tmpl": template_struct_tmpl,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
//     data/
//       foo.txt
//       img/
//         a.png
//         b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
	node := _bintree
	if len(name) != 0 {
		cannonicalName := strings.Replace(name, "\\", "/", -1)
		pathList := strings.Split(cannonicalName, "/")
		for _, p := range pathList {
			node = node.Children[p]
			if node == nil {
				return nil, fmt.Errorf("Asset %s not found", name)
			}
		}
	}
	if node.Func != nil {
		return nil, fmt.Errorf("Asset %s not found", name)
	}
	rv := make([]string, 0, len(node.Children))
	for name := range node.Children {
		rv = append(rv, name)
	}
	return rv, nil
}

type _bintree_t struct {
	Func func() ([]byte, error)
	Children map[string]*_bintree_t
}
var _bintree = &_bintree_t{nil, map[string]*_bintree_t{
	"template": &_bintree_t{nil, map[string]*_bintree_t{
		"method.tmpl": &_bintree_t{template_method_tmpl, map[string]*_bintree_t{
		}},
		"struct.tmpl": &_bintree_t{template_struct_tmpl, map[string]*_bintree_t{
		}},
	}},
}}
<|endoftext|>


<commit_before>package stripe

import (
	"encoding/json"
)

// ChargeFraudUserReport is the list of allowed values for reporting fraud.
type ChargeFraudUserReport string

// List of values that ChargeFraudUserReport can take.
const (
	ChargeFraudUserReportFraudulent ChargeFraudUserReport = "fraudulent"
	ChargeFraudUserReportSafe       ChargeFraudUserReport = "safe"
)

// ChargeFraudStripeReport is the list of allowed values for reporting fraud.
type ChargeFraudStripeReport string

// List of values that ChargeFraudStripeReport can take.
const (
	ChargeFraudStripeReportFraudulent ChargeFraudStripeReport = "fraudulent"
)

// ChargeLevel3LineItemsParams is the set of parameters that represent a line item on level III data.
type ChargeLevel3LineItemsParams struct {
	DiscountAmount     *int64  `form:"discount_amount"`
	ProductCode        *string `form:"product_code"`
	ProductDescription *string `form:"product_description"`
	Quantity           *int64  `form:"quantity"`
	TaxAmount          *int64  `form:"tax_amount"`
	UnitCost           *int64  `form:"unit_cost"`
}

// ChargeLevel3Params is the set of parameters that can be used for the Level III data.
type ChargeLevel3Params struct {
	CustomerReference  *string                        `form:"customer_reference"`
	LineItems          []*ChargeLevel3LineItemsParams `form:"line_items"`
	MerchantReference  *string                        `form:"merchant_reference"`
	ShippingAddressZip *string                        `form:"shipping_address_zip"`
	ShippingFromZip    *string                        `form:"shipping_from_zip"`
	ShippingAmount     *int64                         `form:"shipping_amount"`
}

// ChargeTransferDataParams is the set of parameters allowed for the transfer_data hash.
type ChargeTransferDataParams struct {
	Destination *string `form:"destination"`
}

// ChargeParams is the set of parameters that can be used when creating or updating a charge.
type ChargeParams struct {
	Params               `form:"*"`
	Amount               *int64                    `form:"amount"`
	ApplicationFeeAmount *int64                    `form:"application_fee_amount"`
	Capture              *bool                     `form:"capture"`
	Currency             *string                   `form:"currency"`
	Customer             *string                   `form:"customer"`
	Description          *string                   `form:"description"`
	Destination          *DestinationParams        `form:"destination"`
	ExchangeRate         *float64                  `form:"exchange_rate"`
	FraudDetails         *FraudDetailsParams       `form:"fraud_details"`
	Level3               *ChargeLevel3Params       `form:"level3"`
	OnBehalfOf           *string                   `form:"on_behalf_of"`
	ReceiptEmail         *string                   `form:"receipt_email"`
	Shipping             *ShippingDetailsParams    `form:"shipping"`
	Source               *SourceParams             `form:"*"` // SourceParams has custom encoding so brought to top level with "*"
	StatementDescriptor  *string                   `form:"statement_descriptor"`
	TransferData         *ChargeTransferDataParams `form:"transfer_data"`
	TransferGroup        *string                   `form:"transfer_group"`

	// This property is considered deprecated. Prefer using ApplicationFeeAmount
	ApplicationFee *int64 `form:"application_fee"`
}

// ShippingDetailsParams is the structure containing shipping information as parameters
type ShippingDetailsParams struct {
	Address        *AddressParams `form:"address"`
	Carrier        *string        `form:"carrier"`
	Name           *string        `form:"name"`
	Phone          *string        `form:"phone"`
	TrackingNumber *string        `form:"tracking_number"`
}

// SetSource adds valid sources to a ChargeParams object,
// returning an error for unsupported sources.
func (p *ChargeParams) SetSource(sp interface{}) error {
	source, err := SourceParamsFor(sp)
	p.Source = source
	return err
}

// DestinationParams describes the parameters available for the destination hash when creating a charge.
type DestinationParams struct {
	Account *string `form:"account"`
	Amount  *int64  `form:"amount"`
}

// FraudDetailsParams provides information on the fraud details for a charge.
type FraudDetailsParams struct {
	UserReport *string `form:"user_report"`
}

// ChargeListParams is the set of parameters that can be used when listing charges.
type ChargeListParams struct {
	ListParams    `form:"*"`
	Created       *int64            `form:"created"`
	CreatedRange  *RangeQueryParams `form:"created"`
	Customer      *string           `form:"customer"`
	TransferGroup *string           `form:"transfer_group"`
}

// CaptureParams is the set of parameters that can be used when capturing a charge.
type CaptureParams struct {
	Params               `form:"*"`
	Amount               *int64   `form:"amount"`
	ApplicationFeeAmount *int64   `form:"application_fee_amount"`
	ExchangeRate         *float64 `form:"exchange_rate"`
	ReceiptEmail         *string  `form:"receipt_email"`
	StatementDescriptor  *string  `form:"statement_descriptor"`

	// This property is considered deprecated. Prefer using ApplicationFeeAmount
	ApplicationFee *int64 `form:"application_fee"`
}

// ChargeLevel3LineItem represents a line item on level III data.
// This is in private beta and would be empty for most integrations
type ChargeLevel3LineItem struct {
	DiscountAmount     int64  `json:"discount_amount"`
	ProductCode        string `json:"product_code"`
	ProductDescription string `json:"product_description"`
	Quantity           int64  `json:"quantity"`
	TaxAmount          int64  `json:"tax_amount"`
	UnitCost           int64  `json:"unit_cost"`
}

// ChargeLevel3 represents the Level III data.
// This is in private beta and would be empty for most integrations
type ChargeLevel3 struct {
	CustomerReference  string                  `json:"customer_reference"`
	LineItems          []*ChargeLevel3LineItem `json:"line_items"`
	MerchantReference  string                  `json:"merchant_reference"`
	ShippingAddressZip string                  `json:"shipping_address_zip"`
	ShippingFromZip    string                  `json:"shipping_from_zip"`
	ShippingAmount     int64                   `json:"shipping_amount"`
}

// ChargeTransferData represents the information for the transfer_data associated with a charge.
type ChargeTransferData struct {
	Destination *Account `json:"destination"`
}

// Charge is the resource representing a Stripe charge.
// For more details see https://stripe.com/docs/api#charges.
type Charge struct {
	Amount               int64               `json:"amount"`
	AmountRefunded       int64               `json:"amount_refunded"`
	Application          *Application        `json:"application"`
	ApplicationFee       *ApplicationFee     `json:"application_fee"`
	ApplicationFeeAmount int64               `json:"application_fee_amount"`
	AuthorizationCode    string              `json:"authorization_code"`
	BalanceTransaction   *BalanceTransaction `json:"balance_transaction"`
	Captured             bool                `json:"captured"`
	Created              int64               `json:"created"`
	Currency             Currency            `json:"currency"`
	Customer             *Customer           `json:"customer"`
	Description          string              `json:"description"`
	Destination          *Account            `json:"destination"`
	Dispute              *Dispute            `json:"dispute"`
	FailureCode          string              `json:"failure_code"`
	FailureMessage       string              `json:"failure_message"`
	FraudDetails         *FraudDetails       `json:"fraud_details"`
	ID                   string              `json:"id"`
	Invoice              *Invoice            `json:"invoice"`
	Level3               ChargeLevel3        `json:"level3"`
	Livemode             bool                `json:"livemode"`
	Metadata             map[string]string   `json:"metadata"`
	OnBehalfOf           *Account            `json:"on_behalf_of"`
	Outcome              *ChargeOutcome      `json:"outcome"`
	Paid                 bool                `json:"paid"`
	ReceiptEmail         string              `json:"receipt_email"`
	ReceiptNumber        string              `json:"receipt_number"`
	ReceiptURL           string              `json:"receipt_url"`
	Refunded             bool                `json:"refunded"`
	Refunds              *RefundList         `json:"refunds"`
	Review               *Review             `json:"review"`
	Shipping             *ShippingDetails    `json:"shipping"`
	Source               *PaymentSource      `json:"source"`
	SourceTransfer       *Transfer           `json:"source_transfer"`
	StatementDescriptor  string              `json:"statement_descriptor"`
	Status               string              `json:"status"`
	Transfer             *Transfer           `json:"transfer"`
	TransferData         *ChargeTransferData `json:"transfer_data"`
	TransferGroup        string              `json:"transfer_group"`
}

// UnmarshalJSON handles deserialization of a charge.
// This custom unmarshaling is needed because the resulting
// property may be an ID or the full struct if it was expanded.
func (c *Charge) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		c.ID = id
		return nil
	}

	type charge Charge
	var v charge
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*c = Charge(v)
	return nil
}

// ChargeList is a list of charges as retrieved from a list endpoint.
type ChargeList struct {
	ListMeta
	Data []*Charge `json:"data"`
}

// FraudDetails is the structure detailing fraud status.
type FraudDetails struct {
	UserReport   ChargeFraudUserReport   `json:"user_report"`
	StripeReport ChargeFraudStripeReport `json:"stripe_report"`
}

// ChargeOutcomeRule tells you the Radar rule that blocked the charge, if any.
type ChargeOutcomeRule struct {
	Action    string `json:"action"`
	ID        string `json:"id"`
	Predicate string `json:"predicate"`
}

// ChargeOutcome is the charge's outcome that details whether a payment
// was accepted and why.
type ChargeOutcome struct {
	NetworkStatus string             `json:"network_status"`
	Reason        string             `json:"reason"`
	RiskLevel     string             `json:"risk_level"`
	RiskScore     int64              `json:"risk_score"`
	Rule          *ChargeOutcomeRule `json:"rule"`
	SellerMessage string             `json:"seller_message"`
	Type          string             `json:"type"`
}

// ShippingDetails is the structure containing shipping information.
type ShippingDetails struct {
	Address        *Address `json:"address"`
	Carrier        string   `json:"carrier"`
	Name           string   `json:"name"`
	Phone          string   `json:"phone"`
	TrackingNumber string   `json:"tracking_number"`
}

var depth = -1

// UnmarshalJSON handles deserialization of a ChargeOutcomeRule.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (c *ChargeOutcomeRule) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		c.ID = id
		return nil
	}

	type chargeOutcomeRule ChargeOutcomeRule
	var v chargeOutcomeRule
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*c = ChargeOutcomeRule(v)
	return nil
}
<commit_msg>Add support for `transfer_data[amount]` on Charge<commit_after>package stripe

import (
	"encoding/json"
)

// ChargeFraudUserReport is the list of allowed values for reporting fraud.
type ChargeFraudUserReport string

// List of values that ChargeFraudUserReport can take.
const (
	ChargeFraudUserReportFraudulent ChargeFraudUserReport = "fraudulent"
	ChargeFraudUserReportSafe       ChargeFraudUserReport = "safe"
)

// ChargeFraudStripeReport is the list of allowed values for reporting fraud.
type ChargeFraudStripeReport string

// List of values that ChargeFraudStripeReport can take.
const (
	ChargeFraudStripeReportFraudulent ChargeFraudStripeReport = "fraudulent"
)

// ChargeLevel3LineItemsParams is the set of parameters that represent a line item on level III data.
type ChargeLevel3LineItemsParams struct {
	DiscountAmount     *int64  `form:"discount_amount"`
	ProductCode        *string `form:"product_code"`
	ProductDescription *string `form:"product_description"`
	Quantity           *int64  `form:"quantity"`
	TaxAmount          *int64  `form:"tax_amount"`
	UnitCost           *int64  `form:"unit_cost"`
}

// ChargeLevel3Params is the set of parameters that can be used for the Level III data.
type ChargeLevel3Params struct {
	CustomerReference  *string                        `form:"customer_reference"`
	LineItems          []*ChargeLevel3LineItemsParams `form:"line_items"`
	MerchantReference  *string                        `form:"merchant_reference"`
	ShippingAddressZip *string                        `form:"shipping_address_zip"`
	ShippingFromZip    *string                        `form:"shipping_from_zip"`
	ShippingAmount     *int64                         `form:"shipping_amount"`
}

// ChargeTransferDataParams is the set of parameters allowed for the transfer_data hash.
type ChargeTransferDataParams struct {
	Amount      *int64  `form:"amount"`
	Destination *string `form:"destination"`
}

// ChargeParams is the set of parameters that can be used when creating or updating a charge.
type ChargeParams struct {
	Params               `form:"*"`
	Amount               *int64                    `form:"amount"`
	ApplicationFeeAmount *int64                    `form:"application_fee_amount"`
	Capture              *bool                     `form:"capture"`
	Currency             *string                   `form:"currency"`
	Customer             *string                   `form:"customer"`
	Description          *string                   `form:"description"`
	Destination          *DestinationParams        `form:"destination"`
	ExchangeRate         *float64                  `form:"exchange_rate"`
	FraudDetails         *FraudDetailsParams       `form:"fraud_details"`
	Level3               *ChargeLevel3Params       `form:"level3"`
	OnBehalfOf           *string                   `form:"on_behalf_of"`
	ReceiptEmail         *string                   `form:"receipt_email"`
	Shipping             *ShippingDetailsParams    `form:"shipping"`
	Source               *SourceParams             `form:"*"` // SourceParams has custom encoding so brought to top level with "*"
	StatementDescriptor  *string                   `form:"statement_descriptor"`
	TransferData         *ChargeTransferDataParams `form:"transfer_data"`
	TransferGroup        *string                   `form:"transfer_group"`

	// This property is considered deprecated. Prefer using ApplicationFeeAmount
	ApplicationFee *int64 `form:"application_fee"`
}

// ShippingDetailsParams is the structure containing shipping information as parameters
type ShippingDetailsParams struct {
	Address        *AddressParams `form:"address"`
	Carrier        *string        `form:"carrier"`
	Name           *string        `form:"name"`
	Phone          *string        `form:"phone"`
	TrackingNumber *string        `form:"tracking_number"`
}

// SetSource adds valid sources to a ChargeParams object,
// returning an error for unsupported sources.
func (p *ChargeParams) SetSource(sp interface{}) error {
	source, err := SourceParamsFor(sp)
	p.Source = source
	return err
}

// DestinationParams describes the parameters available for the destination hash when creating a charge.
type DestinationParams struct {
	Account *string `form:"account"`
	Amount  *int64  `form:"amount"`
}

// FraudDetailsParams provides information on the fraud details for a charge.
type FraudDetailsParams struct {
	UserReport *string `form:"user_report"`
}

// ChargeListParams is the set of parameters that can be used when listing charges.
type ChargeListParams struct {
	ListParams    `form:"*"`
	Created       *int64            `form:"created"`
	CreatedRange  *RangeQueryParams `form:"created"`
	Customer      *string           `form:"customer"`
	TransferGroup *string           `form:"transfer_group"`
}

// CaptureParams is the set of parameters that can be used when capturing a charge.
type CaptureParams struct {
	Params               `form:"*"`
	Amount               *int64   `form:"amount"`
	ApplicationFeeAmount *int64   `form:"application_fee_amount"`
	ExchangeRate         *float64 `form:"exchange_rate"`
	ReceiptEmail         *string  `form:"receipt_email"`
	StatementDescriptor  *string  `form:"statement_descriptor"`

	// This property is considered deprecated. Prefer using ApplicationFeeAmount
	ApplicationFee *int64 `form:"application_fee"`
}

// ChargeLevel3LineItem represents a line item on level III data.
// This is in private beta and would be empty for most integrations
type ChargeLevel3LineItem struct {
	DiscountAmount     int64  `json:"discount_amount"`
	ProductCode        string `json:"product_code"`
	ProductDescription string `json:"product_description"`
	Quantity           int64  `json:"quantity"`
	TaxAmount          int64  `json:"tax_amount"`
	UnitCost           int64  `json:"unit_cost"`
}

// ChargeLevel3 represents the Level III data.
// This is in private beta and would be empty for most integrations
type ChargeLevel3 struct {
	CustomerReference  string                  `json:"customer_reference"`
	LineItems          []*ChargeLevel3LineItem `json:"line_items"`
	MerchantReference  string                  `json:"merchant_reference"`
	ShippingAddressZip string                  `json:"shipping_address_zip"`
	ShippingFromZip    string                  `json:"shipping_from_zip"`
	ShippingAmount     int64                   `json:"shipping_amount"`
}

// ChargeTransferData represents the information for the transfer_data associated with a charge.
type ChargeTransferData struct {
	Amount      int64    `form:"amount"`
	Destination *Account `json:"destination"`
}

// Charge is the resource representing a Stripe charge.
// For more details see https://stripe.com/docs/api#charges.
type Charge struct {
	Amount               int64               `json:"amount"`
	AmountRefunded       int64               `json:"amount_refunded"`
	Application          *Application        `json:"application"`
	ApplicationFee       *ApplicationFee     `json:"application_fee"`
	ApplicationFeeAmount int64               `json:"application_fee_amount"`
	AuthorizationCode    string              `json:"authorization_code"`
	BalanceTransaction   *BalanceTransaction `json:"balance_transaction"`
	Captured             bool                `json:"captured"`
	Created              int64               `json:"created"`
	Currency             Currency            `json:"currency"`
	Customer             *Customer           `json:"customer"`
	Description          string              `json:"description"`
	Destination          *Account            `json:"destination"`
	Dispute              *Dispute            `json:"dispute"`
	FailureCode          string              `json:"failure_code"`
	FailureMessage       string              `json:"failure_message"`
	FraudDetails         *FraudDetails       `json:"fraud_details"`
	ID                   string              `json:"id"`
	Invoice              *Invoice            `json:"invoice"`
	Level3               ChargeLevel3        `json:"level3"`
	Livemode             bool                `json:"livemode"`
	Metadata             map[string]string   `json:"metadata"`
	OnBehalfOf           *Account            `json:"on_behalf_of"`
	Outcome              *ChargeOutcome      `json:"outcome"`
	Paid                 bool                `json:"paid"`
	ReceiptEmail         string              `json:"receipt_email"`
	ReceiptNumber        string              `json:"receipt_number"`
	ReceiptURL           string              `json:"receipt_url"`
	Refunded             bool                `json:"refunded"`
	Refunds              *RefundList         `json:"refunds"`
	Review               *Review             `json:"review"`
	Shipping             *ShippingDetails    `json:"shipping"`
	Source               *PaymentSource      `json:"source"`
	SourceTransfer       *Transfer           `json:"source_transfer"`
	StatementDescriptor  string              `json:"statement_descriptor"`
	Status               string              `json:"status"`
	Transfer             *Transfer           `json:"transfer"`
	TransferData         *ChargeTransferData `json:"transfer_data"`
	TransferGroup        string              `json:"transfer_group"`
}

// UnmarshalJSON handles deserialization of a charge.
// This custom unmarshaling is needed because the resulting
// property may be an ID or the full struct if it was expanded.
func (c *Charge) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		c.ID = id
		return nil
	}

	type charge Charge
	var v charge
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*c = Charge(v)
	return nil
}

// ChargeList is a list of charges as retrieved from a list endpoint.
type ChargeList struct {
	ListMeta
	Data []*Charge `json:"data"`
}

// FraudDetails is the structure detailing fraud status.
type FraudDetails struct {
	UserReport   ChargeFraudUserReport   `json:"user_report"`
	StripeReport ChargeFraudStripeReport `json:"stripe_report"`
}

// ChargeOutcomeRule tells you the Radar rule that blocked the charge, if any.
type ChargeOutcomeRule struct {
	Action    string `json:"action"`
	ID        string `json:"id"`
	Predicate string `json:"predicate"`
}

// ChargeOutcome is the charge's outcome that details whether a payment
// was accepted and why.
type ChargeOutcome struct {
	NetworkStatus string             `json:"network_status"`
	Reason        string             `json:"reason"`
	RiskLevel     string             `json:"risk_level"`
	RiskScore     int64              `json:"risk_score"`
	Rule          *ChargeOutcomeRule `json:"rule"`
	SellerMessage string             `json:"seller_message"`
	Type          string             `json:"type"`
}

// ShippingDetails is the structure containing shipping information.
type ShippingDetails struct {
	Address        *Address `json:"address"`
	Carrier        string   `json:"carrier"`
	Name           string   `json:"name"`
	Phone          string   `json:"phone"`
	TrackingNumber string   `json:"tracking_number"`
}

var depth = -1

// UnmarshalJSON handles deserialization of a ChargeOutcomeRule.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (c *ChargeOutcomeRule) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		c.ID = id
		return nil
	}

	type chargeOutcomeRule ChargeOutcomeRule
	var v chargeOutcomeRule
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*c = ChargeOutcomeRule(v)
	return nil
}
<|endoftext|>