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

package tcp

import (
	"os"
	"strings"
	"time"
	"unsafe"
)

// A CAState represents a state of congestion avoidance.
type CAState int

var caStates = map[CAState]string{
	CAOpen:     "open",
	CADisorder: "disorder",
	CACWR:      "congestion window reduced",
	CARecovery: "recovery",
	CALoss:     "loss",
}

func (st CAState) String() string {
	s, ok := caStates[st]
	if !ok {
		return "<nil>"
	}
	return s
}

// A SysInfo represents platform-specific information.
type SysInfo struct {
	PathMTU         uint       `json:"path mtu"`     // path maximum transmission unit
	AdvertisedMSS   MaxSegSize `json:"adv mss"`      // advertised maximum segment size
	CAState         CAState    `json:"ca state"`     // state of congestion avoidance
	KeepAliveProbes uint       `json:"ka probes"`    // # of keep alive probes sent
	UnackSegs       uint       `json:"unack segs"`   // # of unack'd segments in transmission queue
	SackSegs        uint       `json:"sack segs"`    // # of sack'd segments in tranmission queue
	LostSegs        uint       `json:"lost segs"`    // # of lost segments in transmission queue
	RetransSegs     uint       `json:"retrans segs"` // # of retransmitting segments in transmission queue
	ForwardAckSegs  uint       `json:"fack segs"`    // # of forward ack'd segments in transmission queue
}

func info(s int) (*Info, error) {
	var sti sysTCPInfo
	l := uint32(sysSizeofTCPInfo)
	if err := getsockopt(s, ianaProtocolTCP, sysTCP_INFO, unsafe.Pointer(&sti), &l); err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	var stcci sysTCPCCInfo
	l = uint32(sysSizeofTCPCCInfo)
	if err := getsockopt(s, ianaProtocolTCP, sysTCP_CC_INFO, unsafe.Pointer(&stcci), &l); err != nil {
		return parseInfo(&sti), nil
	}
	b := make([]byte, 16) // see TCP_CA_NAME_MAX
	l = uint32(16)
	if err := getsockopt(s, ianaProtocolTCP, sysTCP_CONGESTION, unsafe.Pointer(&b[0]), &l); err != nil {
		return parseInfo(&sti), nil
	}
	ti := parseInfo(&sti)
	i := 0
	for i = 0; i < 16; i++ {
		if b[i] == 0 {
			break
		}
	}
	scc := parseSysCC(string(b[:i]), &stcci)
	if ti != nil && ti.CongestionControl != nil && scc != nil {
		ti.CongestionControl.Sys = scc
	}
	return ti, nil
}

var sysStates = [12]State{Unknown, Established, SynSent, SynReceived, FinWait1, FinWait2, TimeWait, Closed, CloseWait, LastAck, Listen, Closing}

func parseInfo(sti *sysTCPInfo) *Info {
	ti := &Info{State: sysStates[sti.State]}
	if sti.Options&sysTCPI_OPT_WSCALE != 0 {
		ti.Options = append(ti.Options, WindowScale(sti.Pad_cgo_0[0]>>4))
		ti.PeerOptions = append(ti.PeerOptions, WindowScale(sti.Pad_cgo_0[0]&0x0f))
	}
	if sti.Options&sysTCPI_OPT_TIMESTAMPS != 0 {
		ti.Options = append(ti.Options, Timestamps(true))
		ti.PeerOptions = append(ti.PeerOptions, Timestamps(true))
	}
	ti.SenderMSS = MaxSegSize(sti.Snd_mss)
	ti.ReceiverMSS = MaxSegSize(sti.Rcv_mss)
	ti.RTT = time.Duration(sti.Rtt) * time.Microsecond
	ti.RTTVar = time.Duration(sti.Rttvar) * time.Microsecond
	ti.RTO = time.Duration(sti.Rto) * time.Microsecond
	ti.ATO = time.Duration(sti.Ato) * time.Microsecond
	ti.LastDataSent = time.Duration(sti.Last_data_sent) * time.Millisecond
	ti.LastDataReceived = time.Duration(sti.Last_data_recv) * time.Millisecond
	ti.LastAckReceived = time.Duration(sti.Last_ack_recv) * time.Millisecond
	ti.FlowControl = &FlowControl{
		ReceiverWindow: uint(sti.Rcv_space),
	}
	ti.CongestionControl = &CongestionControl{
		SenderSSThreshold:   uint(sti.Snd_ssthresh),
		ReceiverSSThreshold: uint(sti.Rcv_ssthresh),
		SenderWindow:        uint(sti.Snd_cwnd),
	}
	ti.Sys = &SysInfo{
		PathMTU:         uint(sti.Pmtu),
		AdvertisedMSS:   MaxSegSize(sti.Advmss),
		CAState:         CAState(sti.Ca_state),
		KeepAliveProbes: uint(sti.Probes),
		UnackSegs:       uint(sti.Unacked),
		SackSegs:        uint(sti.Sacked),
		LostSegs:        uint(sti.Lost),
		RetransSegs:     uint(sti.Retrans),
		ForwardAckSegs:  uint(sti.Fackets),
	}
	return ti
}

// A SysCongestionControl represents platform-specific congestion
// control information.
type SysCongestionControl struct {
	Algo string                   `json:"algo"` // congestion control algorithm name
	Info SysCongestionControlInfo `json:"info,omitempty"`
}

// A SysCongestionControlInfo represents congestion control
// algorithm-specific information.
type SysCongestionControlInfo interface {
	String() string
}

// A VegasInfo represents TCP Vegas congestion control information.
type VegasInfo struct {
	Enabled    bool          `json:"enabled"`
	RoundTrips uint          `json:"rnd trips"` // # of round-trips
	RTT        time.Duration `json:"rtt"`       // round-trip time
	MinRTT     time.Duration `json:"min rtt"`   // minimum round-trip time
}

// Len implements the Len method of SysCongestionControlInfo interface.
func (vi *VegasInfo) String() string { return "vegas" }

// A CEState represents a state of ECN congestion encountered (CE)
// codepoint.
type CEState int

// A DCTCPInfo represents Datacenter TCP congestion control
// information.
type DCTCPInfo struct {
	Enabled         bool    `json:"enabled"`
	CEState         CEState `json:"ce state"`    // state of ECN CE codepoint
	Alpha           uint    `json:"alpha"`       // fraction of bytes sent
	ECNAckedBytes   uint    `json:"ecn acked"`   // # of acked bytes with ECN
	TotalAckedBytes uint    `json:"total acked"` // total # of acked bytes
}

// Len implements the Len method of SysCongestionControlInfo interface.
func (di *DCTCPInfo) String() string { return "dctcp" }

func parseSysCC(name string, stcci *sysTCPCCInfo) *SysCongestionControl {
	scc := SysCongestionControl{Algo: name}
	if strings.HasPrefix(name, "dctcp") {
		stdi := (*sysTCPDCTCPInfo)(unsafe.Pointer(stcci))
		if stdi.Enabled == 0 {
			return &scc
		}
		scc.Info = &DCTCPInfo{
			Enabled: true,
			Alpha:   uint(stdi.Alpha),
		}
		return &scc
	}
	stvi := (*sysTCPVegasInfo)(unsafe.Pointer(stcci))
	if stvi.Enabled == 0 {
		return &scc
	}
	scc.Info = &VegasInfo{
		Enabled:    true,
		RoundTrips: uint(stvi.Rttcnt),
		RTT:        time.Duration(stvi.Rtt) * time.Microsecond,
		MinRTT:     time.Duration(stvi.Minrtt) * time.Microsecond,
	}
	return &scc
}
<commit_msg>tcp: fix typos<commit_after>// Copyright 2014 Mikio Hara. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tcp

import (
	"os"
	"strings"
	"time"
	"unsafe"
)

// A CAState represents a state of congestion avoidance.
type CAState int

var caStates = map[CAState]string{
	CAOpen:     "open",
	CADisorder: "disorder",
	CACWR:      "congestion window reduced",
	CARecovery: "recovery",
	CALoss:     "loss",
}

func (st CAState) String() string {
	s, ok := caStates[st]
	if !ok {
		return "<nil>"
	}
	return s
}

// A SysInfo represents platform-specific information.
type SysInfo struct {
	PathMTU         uint       `json:"path mtu"`     // path maximum transmission unit
	AdvertisedMSS   MaxSegSize `json:"adv mss"`      // advertised maximum segment size
	CAState         CAState    `json:"ca state"`     // state of congestion avoidance
	KeepAliveProbes uint       `json:"ka probes"`    // # of keep alive probes sent
	UnackSegs       uint       `json:"unack segs"`   // # of unack'd segments in transmission queue
	SackSegs        uint       `json:"sack segs"`    // # of sack'd segments in tranmission queue
	LostSegs        uint       `json:"lost segs"`    // # of lost segments in transmission queue
	RetransSegs     uint       `json:"retrans segs"` // # of retransmitting segments in transmission queue
	ForwardAckSegs  uint       `json:"fack segs"`    // # of forward ack'd segments in transmission queue
}

func info(s int) (*Info, error) {
	var sti sysTCPInfo
	l := uint32(sysSizeofTCPInfo)
	if err := getsockopt(s, ianaProtocolTCP, sysTCP_INFO, unsafe.Pointer(&sti), &l); err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	var stcci sysTCPCCInfo
	l = uint32(sysSizeofTCPCCInfo)
	if err := getsockopt(s, ianaProtocolTCP, sysTCP_CC_INFO, unsafe.Pointer(&stcci), &l); err != nil {
		return parseInfo(&sti), nil
	}
	b := make([]byte, 16) // see TCP_CA_NAME_MAX
	l = uint32(16)
	if err := getsockopt(s, ianaProtocolTCP, sysTCP_CONGESTION, unsafe.Pointer(&b[0]), &l); err != nil {
		return parseInfo(&sti), nil
	}
	ti := parseInfo(&sti)
	i := 0
	for i = 0; i < 16; i++ {
		if b[i] == 0 {
			break
		}
	}
	scc := parseSysCC(string(b[:i]), &stcci)
	if ti != nil && ti.CongestionControl != nil && scc != nil {
		ti.CongestionControl.Sys = scc
	}
	return ti, nil
}

var sysStates = [12]State{Unknown, Established, SynSent, SynReceived, FinWait1, FinWait2, TimeWait, Closed, CloseWait, LastAck, Listen, Closing}

func parseInfo(sti *sysTCPInfo) *Info {
	ti := &Info{State: sysStates[sti.State]}
	if sti.Options&sysTCPI_OPT_WSCALE != 0 {
		ti.Options = append(ti.Options, WindowScale(sti.Pad_cgo_0[0]>>4))
		ti.PeerOptions = append(ti.PeerOptions, WindowScale(sti.Pad_cgo_0[0]&0x0f))
	}
	if sti.Options&sysTCPI_OPT_TIMESTAMPS != 0 {
		ti.Options = append(ti.Options, Timestamps(true))
		ti.PeerOptions = append(ti.PeerOptions, Timestamps(true))
	}
	ti.SenderMSS = MaxSegSize(sti.Snd_mss)
	ti.ReceiverMSS = MaxSegSize(sti.Rcv_mss)
	ti.RTT = time.Duration(sti.Rtt) * time.Microsecond
	ti.RTTVar = time.Duration(sti.Rttvar) * time.Microsecond
	ti.RTO = time.Duration(sti.Rto) * time.Microsecond
	ti.ATO = time.Duration(sti.Ato) * time.Microsecond
	ti.LastDataSent = time.Duration(sti.Last_data_sent) * time.Millisecond
	ti.LastDataReceived = time.Duration(sti.Last_data_recv) * time.Millisecond
	ti.LastAckReceived = time.Duration(sti.Last_ack_recv) * time.Millisecond
	ti.FlowControl = &FlowControl{
		ReceiverWindow: uint(sti.Rcv_space),
	}
	ti.CongestionControl = &CongestionControl{
		SenderSSThreshold:   uint(sti.Snd_ssthresh),
		ReceiverSSThreshold: uint(sti.Rcv_ssthresh),
		SenderWindow:        uint(sti.Snd_cwnd),
	}
	ti.Sys = &SysInfo{
		PathMTU:         uint(sti.Pmtu),
		AdvertisedMSS:   MaxSegSize(sti.Advmss),
		CAState:         CAState(sti.Ca_state),
		KeepAliveProbes: uint(sti.Probes),
		UnackSegs:       uint(sti.Unacked),
		SackSegs:        uint(sti.Sacked),
		LostSegs:        uint(sti.Lost),
		RetransSegs:     uint(sti.Retrans),
		ForwardAckSegs:  uint(sti.Fackets),
	}
	return ti
}

// A SysCongestionControl represents platform-specific congestion
// control information.
type SysCongestionControl struct {
	Algo string                   `json:"algo"` // congestion control algorithm name
	Info SysCongestionControlInfo `json:"info,omitempty"`
}

// A SysCongestionControlInfo represents congestion control
// algorithm-specific information.
type SysCongestionControlInfo interface {
	String() string
}

// A VegasInfo represents TCP Vegas congestion control information.
type VegasInfo struct {
	Enabled    bool          `json:"enabled"`
	RoundTrips uint          `json:"rnd trips"` // # of round-trips
	RTT        time.Duration `json:"rtt"`       // round-trip time
	MinRTT     time.Duration `json:"min rtt"`   // minimum round-trip time
}

// String implements the String method of SysCongestionControlInfo
// interface.
func (vi *VegasInfo) String() string { return "vegas" }

// A CEState represents a state of ECN congestion encountered (CE)
// codepoint.
type CEState int

// A DCTCPInfo represents Datacenter TCP congestion control
// information.
type DCTCPInfo struct {
	Enabled         bool    `json:"enabled"`
	CEState         CEState `json:"ce state"`    // state of ECN CE codepoint
	Alpha           uint    `json:"alpha"`       // fraction of bytes sent
	ECNAckedBytes   uint    `json:"ecn acked"`   // # of acked bytes with ECN
	TotalAckedBytes uint    `json:"total acked"` // total # of acked bytes
}

// String implements the String method of SysCongestionControlInfo
// interface.
func (di *DCTCPInfo) String() string { return "dctcp" }

func parseSysCC(name string, stcci *sysTCPCCInfo) *SysCongestionControl {
	scc := SysCongestionControl{Algo: name}
	if strings.HasPrefix(name, "dctcp") {
		stdi := (*sysTCPDCTCPInfo)(unsafe.Pointer(stcci))
		if stdi.Enabled == 0 {
			return &scc
		}
		scc.Info = &DCTCPInfo{
			Enabled: true,
			Alpha:   uint(stdi.Alpha),
		}
		return &scc
	}
	stvi := (*sysTCPVegasInfo)(unsafe.Pointer(stcci))
	if stvi.Enabled == 0 {
		return &scc
	}
	scc.Info = &VegasInfo{
		Enabled:    true,
		RoundTrips: uint(stvi.Rttcnt),
		RTT:        time.Duration(stvi.Rtt) * time.Microsecond,
		MinRTT:     time.Duration(stvi.Minrtt) * time.Microsecond,
	}
	return &scc
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"time"

	"github.com/jh-bate/fantail-bot/Godeps/_workspace/src/github.com/tucnak/telebot"
	"github.com/jh-bate/fantail-bot/lib"
)

type (
	fantailBot struct {
		bot   *telebot.Bot
		store *lib.Storage
	}
)

func newFantailBot() *fantailBot {
	botToken := os.Getenv("BOT_TOKEN")

	if botToken == "" {
		log.Fatal("$BOT_TOKEN must be set")
	}

	bot, err := telebot.NewBot(botToken)
	if err != nil {
		return nil
	}

	return &fantailBot{bot: bot, store: lib.NewStorage()}
}

func main() {

	fBot := newFantailBot()
	messages := make(chan telebot.Message)
	fBot.bot.Listen(messages, 1*time.Second)

	q := lib.NewQProcess(fBot.bot, fBot.store)
	go q.Run(messages)
	go q.DoFollowUp()

}
<commit_msg>logging<commit_after>package main

import (
	"log"
	"os"
	"time"

	"github.com/jh-bate/fantail-bot/Godeps/_workspace/src/github.com/tucnak/telebot"
	"github.com/jh-bate/fantail-bot/lib"
)

type (
	fantailBot struct {
		bot   *telebot.Bot
		store *lib.Storage
	}
)

func newFantailBot() *fantailBot {
	botToken := os.Getenv("BOT_TOKEN")

	if botToken == "" {
		log.Fatal("$BOT_TOKEN must be set")
	}

	bot, err := telebot.NewBot(botToken)
	if err != nil {
		return nil
	}

	return &fantailBot{bot: bot, store: lib.NewStorage()}
}

func main() {

	fBot := newFantailBot()
	messages := make(chan telebot.Message)
	fBot.bot.Listen(messages, 1*time.Second)

	q := lib.NewQProcess(fBot.bot, fBot.store)
	log.Println("start message process ....")
	q.Run(messages)
	log.Println("start followup process ....")
	q.DoFollowUp()

}
<|endoftext|>


<commit_before>package consensus

import (
	"errors"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/encoding"
)

var (
	ErrMissingSignatures = errors.New("transaction has inputs with missing signatures")
)

// Each input has a list of public keys and a required number of signatures.
// inputSignatures keeps track of which public keys have been used and how many
// more signatures are needed.
type inputSignatures struct {
	remainingSignatures uint64
	possibleKeys        []SiaPublicKey
	usedKeys            map[uint64]struct{}
	index               int
}

// sortedUnique checks that 'elems' is sorted, contains no repeats, and that no
// element is an invalid index of 'elems'.
func sortedUnique(elems []uint64) bool {
	if len(elems) == 0 {
		return true
	}

	biggest := elems[0]
	for _, elem := range elems[1:] {
		if elem <= biggest {
			return false
		}
	}
	if biggest >= uint64(len(elems)) {
		return false
	}
	return true
}

// validCoveredFields makes sure that all covered fields objects in the
// signatures follow the rules. This means that if 'WholeTransaction' is set to
// true, all fields except for 'Signatures' must be empty. All fields must be
// sorted numerically, and there can be no repeats.
func (t Transaction) validCoveredFields() error {
	for _, sig := range t.Signatures {
		// convenience variables
		cf := sig.CoveredFields
		fields := [][]uint64{
			cf.SiacoinInputs,
			cf.MinerFees,
			cf.FileContracts,
			cf.FileContractTerminations,
			cf.StorageProofs,
			cf.SiafundInputs,
			cf.SiafundOutputs,
			cf.ArbitraryData,
		}

		// Check that all fields are empty if 'WholeTransaction' is set.
		if cf.WholeTransaction {
			for _, field := range fields {
				if len(field) != 0 {
					return errors.New("whole transaction flag is set, but not all fields besides signatures are empty")
				}
			}
		}

		// Check that all fields are sorted, and without repeat values, and
		// that all elements point to objects that exists within the
		// transaction.
		for _, field := range fields {
			if !sortedUnique(field) {
				return errors.New("field does not satisfy 'sorted and unique' requirement")
			}
		}
	}

	return nil
}

// validSignatures checks the validaty of all signatures in a transaction.
func (s *State) validSignatures(t Transaction) error {
	// Check that all covered fields objects follow the rules.
	err := t.validCoveredFields()
	if err != nil {
		return err
	}

	// Create the inputSignatures object for each input.
	sigMap := make(map[crypto.Hash]*inputSignatures)
	for i, input := range t.SiacoinInputs {
		id := crypto.Hash(input.ParentID)
		_, exists := sigMap[id]
		if exists {
			return errors.New("siacoin output spent twice in the same transaction")
		}

		sigMap[id] = &inputSignatures{
			remainingSignatures: input.UnlockConditions.NumSignatures,
			possibleKeys:        input.UnlockConditions.PublicKeys,
			index:               i,
		}
	}
	for i, termination := range t.FileContractTerminations {
		id := crypto.Hash(termination.ParentID)
		_, exists := sigMap[id]
		if exists {
			return errors.New("file contract terminated twice in the same transaction")
		}

		sigMap[id] = &inputSignatures{
			remainingSignatures: termination.TerminationConditions.NumSignatures,
			possibleKeys:        termination.TerminationConditions.PublicKeys,
			index:               i,
		}
	}
	for i, input := range t.SiafundInputs {
		id := crypto.Hash(input.ParentID)
		_, exists := sigMap[id]
		if exists {
			return errors.New("siafund output spent twice in the same transaction")
		}

		sigMap[id] = &inputSignatures{
			remainingSignatures: input.UnlockConditions.NumSignatures,
			possibleKeys:        input.UnlockConditions.PublicKeys,
			index:               i,
		}
	}

	// Check all of the signatures for validity.
	for i, sig := range t.Signatures {
		// check that sig corresponds to an entry in sigMap
		inSig, exists := sigMap[crypto.Hash(sig.ParentID)]
		if !exists || inSig.remainingSignatures == 0 {
			return errors.New("frivolous signature in transaction")
		}
		// check that sig's key hasn't already been used
		_, exists = inSig.usedKeys[sig.PublicKeyIndex]
		if exists {
			return errors.New("one public key was used twice while signing an input")
		}
		// Check that the timelock has expired.
		if sig.Timelock > s.height() {
			return errors.New("signature used before timelock expiration")
		}

		// Check that the signature verifies. Multiple signature schemes are
		// supported.
		publicKey := inSig.possibleKeys[sig.PublicKeyIndex]
		switch publicKey.Algorithm {
		case SignatureEntropy:
			return crypto.ErrInvalidSignature

		case SignatureEd25519:
			// Decode the public key and signature.
			var edPK crypto.PublicKey
			err := encoding.Unmarshal([]byte(publicKey.Key), &edPK)
			if err != nil {
				return err
			}
			var edSig [crypto.SignatureSize]byte
			err = encoding.Unmarshal([]byte(sig.Signature), &edSig)
			if err != nil {
				return err
			}
			cryptoSig := crypto.Signature(&edSig)

			sigHash := t.SigHash(i)
			err = crypto.VerifyHash(sigHash, edPK, cryptoSig)
			if err != nil {
				return err
			}

		default:
			// If we don't recognize the identifier, assume that the signature
			// is valid. This allows more signature types to be added via soft
			// forking.
		}

		inSig.remainingSignatures--
	}

	// Check that all inputs have been sufficiently signed.
	for _, reqSigs := range sigMap {
		if reqSigs.remainingSignatures != 0 {
			return ErrMissingSignatures
		}
	}

	return nil
}
<commit_msg>check signatures in validCoveredFields<commit_after>package consensus

import (
	"errors"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/encoding"
)

var (
	ErrMissingSignatures = errors.New("transaction has inputs with missing signatures")
)

// Each input has a list of public keys and a required number of signatures.
// inputSignatures keeps track of which public keys have been used and how many
// more signatures are needed.
type inputSignatures struct {
	remainingSignatures uint64
	possibleKeys        []SiaPublicKey
	usedKeys            map[uint64]struct{}
	index               int
}

// sortedUnique checks that 'elems' is sorted, contains no repeats, and that no
// element is an invalid index of 'elems'.
func sortedUnique(elems []uint64) bool {
	if len(elems) == 0 {
		return true
	}

	biggest := elems[0]
	for _, elem := range elems[1:] {
		if elem <= biggest {
			return false
		}
	}
	if biggest >= uint64(len(elems)) {
		return false
	}
	return true
}

// validCoveredFields makes sure that all covered fields objects in the
// signatures follow the rules. This means that if 'WholeTransaction' is set to
// true, all fields except for 'Signatures' must be empty. All fields must be
// sorted numerically, and there can be no repeats.
func (t Transaction) validCoveredFields() error {
	for _, sig := range t.Signatures {
		// convenience variables
		cf := sig.CoveredFields
		fields := [][]uint64{
			cf.SiacoinInputs,
			cf.MinerFees,
			cf.FileContracts,
			cf.FileContractTerminations,
			cf.StorageProofs,
			cf.SiafundInputs,
			cf.SiafundOutputs,
			cf.ArbitraryData,
			cf.Signatures,
		}

		// Check that all fields are empty if 'WholeTransaction' is set.
		if cf.WholeTransaction {
			// 'WholeTransaction' does not check signatures.
			for _, field := range fields[:len(fields)-1] {
				if len(field) != 0 {
					return errors.New("whole transaction flag is set, but not all fields besides signatures are empty")
				}
			}
		}

		// Check that all fields are sorted, and without repeat values, and
		// that all elements point to objects that exists within the
		// transaction.
		for _, field := range fields {
			if !sortedUnique(field) {
				return errors.New("field does not satisfy 'sorted and unique' requirement")
			}
		}
	}

	return nil
}

// validSignatures checks the validaty of all signatures in a transaction.
func (s *State) validSignatures(t Transaction) error {
	// Check that all covered fields objects follow the rules.
	err := t.validCoveredFields()
	if err != nil {
		return err
	}

	// Create the inputSignatures object for each input.
	sigMap := make(map[crypto.Hash]*inputSignatures)
	for i, input := range t.SiacoinInputs {
		id := crypto.Hash(input.ParentID)
		_, exists := sigMap[id]
		if exists {
			return errors.New("siacoin output spent twice in the same transaction")
		}

		sigMap[id] = &inputSignatures{
			remainingSignatures: input.UnlockConditions.NumSignatures,
			possibleKeys:        input.UnlockConditions.PublicKeys,
			index:               i,
		}
	}
	for i, termination := range t.FileContractTerminations {
		id := crypto.Hash(termination.ParentID)
		_, exists := sigMap[id]
		if exists {
			return errors.New("file contract terminated twice in the same transaction")
		}

		sigMap[id] = &inputSignatures{
			remainingSignatures: termination.TerminationConditions.NumSignatures,
			possibleKeys:        termination.TerminationConditions.PublicKeys,
			index:               i,
		}
	}
	for i, input := range t.SiafundInputs {
		id := crypto.Hash(input.ParentID)
		_, exists := sigMap[id]
		if exists {
			return errors.New("siafund output spent twice in the same transaction")
		}

		sigMap[id] = &inputSignatures{
			remainingSignatures: input.UnlockConditions.NumSignatures,
			possibleKeys:        input.UnlockConditions.PublicKeys,
			index:               i,
		}
	}

	// Check all of the signatures for validity.
	for i, sig := range t.Signatures {
		// check that sig corresponds to an entry in sigMap
		inSig, exists := sigMap[crypto.Hash(sig.ParentID)]
		if !exists || inSig.remainingSignatures == 0 {
			return errors.New("frivolous signature in transaction")
		}
		// check that sig's key hasn't already been used
		_, exists = inSig.usedKeys[sig.PublicKeyIndex]
		if exists {
			return errors.New("one public key was used twice while signing an input")
		}
		// Check that the timelock has expired.
		if sig.Timelock > s.height() {
			return errors.New("signature used before timelock expiration")
		}

		// Check that the signature verifies. Multiple signature schemes are
		// supported.
		publicKey := inSig.possibleKeys[sig.PublicKeyIndex]
		switch publicKey.Algorithm {
		case SignatureEntropy:
			return crypto.ErrInvalidSignature

		case SignatureEd25519:
			// Decode the public key and signature.
			var edPK crypto.PublicKey
			err := encoding.Unmarshal([]byte(publicKey.Key), &edPK)
			if err != nil {
				return err
			}
			var edSig [crypto.SignatureSize]byte
			err = encoding.Unmarshal([]byte(sig.Signature), &edSig)
			if err != nil {
				return err
			}
			cryptoSig := crypto.Signature(&edSig)

			sigHash := t.SigHash(i)
			err = crypto.VerifyHash(sigHash, edPK, cryptoSig)
			if err != nil {
				return err
			}

		default:
			// If we don't recognize the identifier, assume that the signature
			// is valid. This allows more signature types to be added via soft
			// forking.
		}

		inSig.remainingSignatures--
	}

	// Check that all inputs have been sufficiently signed.
	for _, reqSigs := range sigMap {
		if reqSigs.remainingSignatures != 0 {
			return ErrMissingSignatures
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package pongo2

import (
	"io/ioutil"
)

// Helper function which panics, if a Template couldn't
// successfully parsed. This is how you would use it:
//     var baseTemplate = pongo2.Must(pongo2.FromFile("templates/base.html"))
func Must(tpl *Template, err error) *Template {
	if err != nil {
		panic(err)
	}
	return tpl
}

// Loads  a template from string and returns a Template instance.
func FromString(tpl string) (*Template, error) {
	t, err := newTemplateString(tpl)
	return t, err
}

// Loads  a template from a filename and returns a Template instance.
// The filename must either be relative to the application's directory
// or be an absolute path.
func FromFile(filename string) (*Template, error) {
	buf, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	t, err := newTemplate(filename, string(buf))
	return t, err
}

// Shortcut; renders a template string directly. Panics when providing a
// malformed template or an error occurs during execution.
func RenderTemplateString(s string, ctx Context) string {
	tpl := Must(FromString(s))
	result, err := tpl.Execute(ctx)
	if err != nil {
		panic(err)
	}
	return result
}
<commit_msg>Added a new shortcut API function: RenderTemplateFile().<commit_after>package pongo2

import (
	"io/ioutil"
)

// Helper function which panics, if a Template couldn't
// successfully parsed. This is how you would use it:
//     var baseTemplate = pongo2.Must(pongo2.FromFile("templates/base.html"))
func Must(tpl *Template, err error) *Template {
	if err != nil {
		panic(err)
	}
	return tpl
}

// Loads  a template from string and returns a Template instance.
func FromString(tpl string) (*Template, error) {
	t, err := newTemplateString(tpl)
	return t, err
}

// Loads  a template from a filename and returns a Template instance.
// The filename must either be relative to the application's directory
// or be an absolute path.
func FromFile(filename string) (*Template, error) {
	buf, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	t, err := newTemplate(filename, string(buf))
	return t, err
}

// Shortcut; renders a template string directly. Panics when providing a
// malformed template or an error occurs during execution.
func RenderTemplateString(s string, ctx Context) string {
	tpl := Must(FromString(s))
	result, err := tpl.Execute(ctx)
	if err != nil {
		panic(err)
	}
	return result
}

// Shortcut; renders a template file directly. Panics when providing a
// malformed template or an error occurs during execution.
func RenderTemplateFile(fn string, ctx Context) string {
	tpl := Must(FromFile(fn))
	result, err := tpl.Execute(ctx)
	if err != nil {
		panic(err)
	}
	return result
}
<|endoftext|>


<commit_before>/*
 Pretty-print Go data structures
*/
package pretty

import (
	"bytes"
	"fmt"
	"io"
	"os"
	r "reflect"
	"strconv"
	"strings"
)

const (
	DEFAULT_INDENT = "  "
	DEFAULT_NIL    = "nil"
)

// The context for printing
type Pretty struct {
	// indent string
	Indent string
	// output recipient
	Out io.Writer
	// string for nil
	NilString string
}

// pretty print the input value (to stdout)
func PrettyPrint(i interface{}) {
	PrettyPrintTo(os.Stdout, i)
}

// pretty print the input value (to a string)
func PrettyFormat(i interface{}) string {
	var out bytes.Buffer
	PrettyPrintTo(&out, i)
	return out.String()
}

// pretty print the input value (to specified writer)
func PrettyPrintTo(out io.Writer, i interface{}) {
	p := &Pretty{DEFAULT_INDENT, out, DEFAULT_NIL}
	p.Print(i)
}

// pretty print the input value
func (p *Pretty) Print(i interface{}) {
	p.PrintValue(r.ValueOf(i), 0)
	io.WriteString(p.Out, "\n")
}

// recursively print the input value
func (p *Pretty) PrintValue(val r.Value, level int) {
	if !val.IsValid() {
		io.WriteString(p.Out, p.NilString)
		return
	}

	cur := strings.Repeat(p.Indent, level)
	next := strings.Repeat(p.Indent, level+1)

	switch val.Kind() {
	case r.Int, r.Int8, r.Int16, r.Int32, r.Int64:
		io.WriteString(p.Out, strconv.FormatInt(val.Int(), 10))

	case r.Uint, r.Uint8, r.Uint16, r.Uint32, r.Uint64:
		io.WriteString(p.Out, strconv.FormatUint(val.Uint(), 10))

	case r.Float32, r.Float64:
		io.WriteString(p.Out, strconv.FormatFloat(val.Float(), 'f', -1, 64))

	case r.String:
		io.WriteString(p.Out, strconv.Quote(val.String()))

	case r.Bool:
		io.WriteString(p.Out, strconv.FormatBool(val.Bool()))

	case r.Map:
		l := val.Len()

		io.WriteString(p.Out, "{\n")
		for i, k := range val.MapKeys() {
			io.WriteString(p.Out, next)
			io.WriteString(p.Out, strconv.Quote(k.String()))
			io.WriteString(p.Out, ": ")
			p.PrintValue(val.MapIndex(k), level+1)
			if i < l-1 {
				io.WriteString(p.Out, ",\n")
			} else {
				io.WriteString(p.Out, "\n")
			}
		}
		io.WriteString(p.Out, cur)
		io.WriteString(p.Out, "}")

	case r.Array, r.Slice:
		l := val.Len()

		io.WriteString(p.Out, "[\n")
		for i := 0; i < l; i++ {
			io.WriteString(p.Out, next)
			p.PrintValue(val.Index(i), level+1)
			if i < l-1 {
				io.WriteString(p.Out, ",\n")
			} else {
				io.WriteString(p.Out, "\n")
			}
		}
		io.WriteString(p.Out, cur)
		io.WriteString(p.Out, "]")

	case r.Interface, r.Ptr:
		p.PrintValue(val.Elem(), level)

	case r.Struct:
		i := val.Interface()
		if i, ok := i.(fmt.Stringer); ok {
			io.WriteString(p.Out, i.String())
		} else {
			l := val.NumField()

			io.WriteString(p.Out, "struct {\n")
			for i := 0; i < l; i++ {
				io.WriteString(p.Out, next)
				io.WriteString(p.Out, val.Type().Field(i).Name)
				io.WriteString(p.Out, ": ")
				p.PrintValue(val.Field(i), level+1)
				if i < l-1 {
					io.WriteString(p.Out, ",\n")
				} else {
					io.WriteString(p.Out, "\n")
				}
			}
			io.WriteString(p.Out, cur)
			io.WriteString(p.Out, "}")
		}

	default:
		io.WriteString(p.Out, "unsupported:")
		io.WriteString(p.Out, val.String())
	}
}
<commit_msg>PrettyFormat shouldn't add a new line. Also added Println (print with new line) and made Print don't add the newline.<commit_after>/*
 Pretty-print Go data structures
*/
package pretty

import (
	"bytes"
	"fmt"
	"io"
	"os"
	r "reflect"
	"strconv"
	"strings"
)

const (
	DEFAULT_INDENT = "  "
	DEFAULT_NIL    = "nil"
)

// The context for printing
type Pretty struct {
	// indent string
	Indent string
	// output recipient
	Out io.Writer
	// string for nil
	NilString string
}

// pretty print the input value (to stdout)
func PrettyPrint(i interface{}) {
	PrettyPrintTo(os.Stdout, i, true)
}

// pretty print the input value (to a string)
func PrettyFormat(i interface{}) string {
	var out bytes.Buffer
	PrettyPrintTo(&out, i, false)
	return out.String()
}

// pretty print the input value (to specified writer)
func PrettyPrintTo(out io.Writer, i interface{}, nl bool) {
	p := &Pretty{DEFAULT_INDENT, out, DEFAULT_NIL}
	if nl {
		p.Println(i)
	} else {
		p.Print(i)
	}
}

// pretty print the input value (no newline)
func (p *Pretty) Print(i interface{}) {
	p.PrintValue(r.ValueOf(i), 0)
}

// pretty print the input value (newline)
func (p *Pretty) Println(i interface{}) {
	p.PrintValue(r.ValueOf(i), 0)
	io.WriteString(p.Out, "\n")
}

// recursively print the input value
func (p *Pretty) PrintValue(val r.Value, level int) {
	if !val.IsValid() {
		io.WriteString(p.Out, p.NilString)
		return
	}

	cur := strings.Repeat(p.Indent, level)
	next := strings.Repeat(p.Indent, level+1)

	switch val.Kind() {
	case r.Int, r.Int8, r.Int16, r.Int32, r.Int64:
		io.WriteString(p.Out, strconv.FormatInt(val.Int(), 10))

	case r.Uint, r.Uint8, r.Uint16, r.Uint32, r.Uint64:
		io.WriteString(p.Out, strconv.FormatUint(val.Uint(), 10))

	case r.Float32, r.Float64:
		io.WriteString(p.Out, strconv.FormatFloat(val.Float(), 'f', -1, 64))

	case r.String:
		io.WriteString(p.Out, strconv.Quote(val.String()))

	case r.Bool:
		io.WriteString(p.Out, strconv.FormatBool(val.Bool()))

	case r.Map:
		l := val.Len()

		io.WriteString(p.Out, "{\n")
		for i, k := range val.MapKeys() {
			io.WriteString(p.Out, next)
			io.WriteString(p.Out, strconv.Quote(k.String()))
			io.WriteString(p.Out, ": ")
			p.PrintValue(val.MapIndex(k), level+1)
			if i < l-1 {
				io.WriteString(p.Out, ",\n")
			} else {
				io.WriteString(p.Out, "\n")
			}
		}
		io.WriteString(p.Out, cur)
		io.WriteString(p.Out, "}")

	case r.Array, r.Slice:
		l := val.Len()

		io.WriteString(p.Out, "[\n")
		for i := 0; i < l; i++ {
			io.WriteString(p.Out, next)
			p.PrintValue(val.Index(i), level+1)
			if i < l-1 {
				io.WriteString(p.Out, ",\n")
			} else {
				io.WriteString(p.Out, "\n")
			}
		}
		io.WriteString(p.Out, cur)
		io.WriteString(p.Out, "]")

	case r.Interface, r.Ptr:
		p.PrintValue(val.Elem(), level)

	case r.Struct:
		i := val.Interface()
		if i, ok := i.(fmt.Stringer); ok {
			io.WriteString(p.Out, i.String())
		} else {
			l := val.NumField()

			io.WriteString(p.Out, "struct {\n")
			for i := 0; i < l; i++ {
				io.WriteString(p.Out, next)
				io.WriteString(p.Out, val.Type().Field(i).Name)
				io.WriteString(p.Out, ": ")
				p.PrintValue(val.Field(i), level+1)
				if i < l-1 {
					io.WriteString(p.Out, ",\n")
				} else {
					io.WriteString(p.Out, "\n")
				}
			}
			io.WriteString(p.Out, cur)
			io.WriteString(p.Out, "}")
		}

	default:
		io.WriteString(p.Out, "unsupported:")
		io.WriteString(p.Out, val.String())
	}
}
<|endoftext|>


<commit_before>// probes.go
//
// This file implements the probe API calls

package atlas

import (
	"fmt"
	"github.com/bndr/gopencils"
)

// GetProbe returns data for a single probe
func GetProbe(id int) (p *Probe, err error) {
	auth := WantAuth()
	api := gopencils.Api(apiEndpoint, auth)
	r, err := api.Res("probes").Id(id, &p).Get()
	if err != nil {
		err = fmt.Errorf("err: %v - r:%v\n", err, r)
		return
	}
	return
}

type Probes []Probe

// GetProbes returns data for a collection of probes
func GetProbes(opts map[string]string) (p *ProbesList, err error) {
	log.Printf("GetProbes: opts=%+v", opts)
	auth := WantAuth()
	api := gopencils.Api(apiEndpoint, auth)

	var plist *interface{}

	r, err := api.Res("probes", plist).Get()
	if err != nil {
		err = fmt.Errorf("%v - r:%v\n", err, r)
		return
	}
	fmt.Printf("r: %#v\nplist: %#v\n", r, plist)
	p = plist
	return
}
<commit_msg>Begin support for pagination for answers.<commit_after>// probes.go
//
// This file implements the probe API calls

package atlas

import (
	"fmt"
	"github.com/bndr/gopencils"
	"log"
)

// GetProbe returns data for a single probe
func GetProbe(id int) (p *Probe, err error) {
	auth := WantAuth()
	api := gopencils.Api(apiEndpoint, auth)
	r, err := api.Res("probes").Id(id, &p).Get()
	if err != nil {
		err = fmt.Errorf("err: %v - r:%v\n", err, r)
		return
	}
	return
}

// ProbesList is our main answer
type ProbesList struct {
	Count    int
	Next     string
	Previous string
	Results  []Probe
}

// GetProbes returns data for a collection of probes
func GetProbes(opts map[string]string) (p *ProbesList, err error) {
	log.Printf("GetProbes: opts=%+v", opts)
	auth := WantAuth()
	api := gopencils.Api(apiEndpoint, auth)

	var rawlist ProbesList

	r, err := api.Res("probes", &rawlist).Get(opts)
	log.Printf("rawlist=%+v r=%+v", rawlist, r)
	if err != nil {
		err = fmt.Errorf("%v - r:%v\n", err, r)
		return
	}

	// Empty answer
	if rawlist == nil {
		return nil, fmt.Errorf("empty probe list")
	}

	if rawlist.Next != "" {
		// We have pagination

	}
	p = &rawlist.Results
	fmt.Printf("r: %#v\np: %#v\n", r, p)
	return
}
<|endoftext|>


<commit_before>	package main

	import (
		"flag"
		"time"
		"strings"

		"github.com/aws/aws-sdk-go/service/ec2"
		"github.com/aws/aws-sdk-go/aws"
		"github.com/mitchellh/cli"
	)

	type CreateCommand struct {
		Ui 			cli.Ui
		InstanceId 	string
		Name 		string
		DryRun		bool
		NoReboot	bool
	}

	// descriptions for args
	var createDscrInstanceId = "The instance from which to create the AMI"
	var createDscrName = "The name of the AMI; the current timestamp will be automatically appended"
	var createDscrDryRun = "Execute a simulated run"
	var createDscrNoReboot = "If true, do not reboot the instance before creating the AMI. It is preferable to reboot the instance to guarantee a consistent filesystem when taking the snapshot, but the likelihood of an inconsistent snapshot is very low."

	func (c *CreateCommand) Help() string {
		return `ec2-snapper create <args> [--help]

	Create an AMI of the given EC2 instance.

	Available args are:
	--instance      ` + createDscrInstanceId + `
	--name          ` + createDscrName + `
	--dry-run       ` + createDscrDryRun + `
	--no-reboot     ` + createDscrNoReboot
	}

	func (c *CreateCommand) Synopsis() string {
		return "Create an AMI of the given EC2 instance"
	}

	func (c *CreateCommand) Run(args []string) int {

		// Handle the command-line args
		cmdFlags := flag.NewFlagSet("create", flag.ExitOnError)
		cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }

		cmdFlags.StringVar(&c.InstanceId, "instance", "", createDscrInstanceId)
		cmdFlags.StringVar(&c.Name, "name", "", createDscrName)
		cmdFlags.BoolVar(&c.DryRun, "dry-run", false, createDscrDryRun)
		cmdFlags.BoolVar(&c.NoReboot, "no-reboot", true, createDscrNoReboot)

		if err := cmdFlags.Parse(args); err != nil {
			return 1
		}

		// Check for required command-line args
		if c.InstanceId == "" {
			c.Ui.Error("ERROR: The argument '--instance' is required.")
			return 1
		}

		if c.Name == "" {
			c.Ui.Error("ERROR: The argument '--name' is required.")
			return 1
		}

		// Create an EC2 service object; AWS region is picked up from the "AWS_REGION" env var.
		svc := ec2.New(nil)

		// Generate a nicely formatted timestamp for right now
		const dateLayoutForAmiName = "2006-01-02 at 15_04_05 (MST)"
		t := time.Now()

		// Create the AMI Snapshot
		name := c.Name + " - " + t.Format(dateLayoutForAmiName)

		c.Ui.Output("==> Creating AMI for " + c.InstanceId + "...")

		resp, err := svc.CreateImage(&ec2.CreateImageInput{
			Name: &name,
			InstanceID: &c.InstanceId,
			DryRun: &c.DryRun,
			NoReboot: &c.NoReboot })
		if err != nil && strings.Contains(err.Error(), "NoCredentialProviders") {
			c.Ui.Error("ERROR: No AWS credentials were found.  Either set the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or run this program on an EC2 instance that has an IAM Role with the appropriate permissions.")
			return 1
		} else if err != nil {
			panic(err)
		}

		// Sleep here to give time for AMI to get found
		time.Sleep(3000 * time.Millisecond)

		// Assign tags to this AMI.  We'll use these when it comes time to delete the AMI
		c.Ui.Output("==> Adding tags to AMI " + *resp.ImageID + "...")

		svc.CreateTags(&ec2.CreateTagsInput{
			Resources: []*string{resp.ImageID},
			Tags: []*ec2.Tag{
				&ec2.Tag{ Key: aws.String("ec2-snapper-instance-id"), Value: &c.InstanceId },
			},
		})

		// Check the status of the AMI
		respDscrImages, err := svc.DescribeImages(&ec2.DescribeImagesInput{
			Filters: []*ec2.Filter{
				&ec2.Filter{
					Name: aws.String("image-id"),
					Values: []*string{resp.ImageID},
				},
			},
		})
		if err != nil {
			panic(err)
		}

		// If no AMI at all was found, throw an error
		if len(respDscrImages.Images) == 0 {
			c.Ui.Error("ERROR: Could not find the AMI just created.")
			return 1
		}

		// If the AMI's status is failed throw an error
		if *respDscrImages.Images[0].State == "failed" {
			c.Ui.Error("ERROR: AMI was crexated but entered a state of 'failed'. This is an AWS issue. Please re-run this command.  Note that you will need to manually de-register the AMI in the AWS console or via the API.")
			return 1
		}

		// Announce success
		c.Ui.Info("==> Success! Created " + *resp.ImageID + " named \"" + name + "\"")
		return 0
	}

<commit_msg>Update create_command.go<commit_after>	package main

	import (
		"flag"
		"time"
		"strings"

		"github.com/aws/aws-sdk-go/service/ec2"
		"github.com/aws/aws-sdk-go/aws"
		"github.com/mitchellh/cli"
	)

	type CreateCommand struct {
		Ui 			cli.Ui
		InstanceId 	string
		Name 		string
		DryRun		bool
		NoReboot	bool
	}

	// descriptions for args
	var createDscrInstanceId = "The instance from which to create the AMI"
	var createDscrName = "The name of the AMI; the current timestamp will be automatically appended"
	var createDscrDryRun = "Execute a simulated run"
	var createDscrNoReboot = "If true, do not reboot the instance before creating the AMI. It is preferable to reboot the instance to guarantee a consistent filesystem when taking the snapshot, but the likelihood of an inconsistent snapshot is very low."

	func (c *CreateCommand) Help() string {
		return `ec2-snapper create <args> [--help]

	Create an AMI of the given EC2 instance.

	Available args are:
	--instance      ` + createDscrInstanceId + `
	--name          ` + createDscrName + `
	--dry-run       ` + createDscrDryRun + `
	--no-reboot     ` + createDscrNoReboot
	}

	func (c *CreateCommand) Synopsis() string {
		return "Create an AMI of the given EC2 instance"
	}

	func (c *CreateCommand) Run(args []string) int {

		// Handle the command-line args
		cmdFlags := flag.NewFlagSet("create", flag.ExitOnError)
		cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }

		cmdFlags.StringVar(&c.InstanceId, "instance", "", createDscrInstanceId)
		cmdFlags.StringVar(&c.Name, "name", "", createDscrName)
		cmdFlags.BoolVar(&c.DryRun, "dry-run", false, createDscrDryRun)
		cmdFlags.BoolVar(&c.NoReboot, "no-reboot", true, createDscrNoReboot)

		if err := cmdFlags.Parse(args); err != nil {
			return 1
		}

		// Check for required command-line args
		if c.InstanceId == "" {
			c.Ui.Error("ERROR: The argument '--instance' is required.")
			return 1
		}

		if c.Name == "" {
			c.Ui.Error("ERROR: The argument '--name' is required.")
			return 1
		}

		// Create an EC2 service object; AWS region is picked up from the "AWS_REGION" env var.
		svc := ec2.New(nil)

		// Generate a nicely formatted timestamp for right now
		const dateLayoutForAmiName = "2006-01-02 at 15_04_05 (MST)"
		t := time.Now()

		// Create the AMI Snapshot
		name := c.Name + " - " + t.Format(dateLayoutForAmiName)

		c.Ui.Output("==> Creating AMI for " + c.InstanceId + "...")

		resp, err := svc.CreateImage(&ec2.CreateImageInput{
			Name: &name,
			InstanceID: &c.InstanceId,
			DryRun: &c.DryRun,
			NoReboot: &c.NoReboot })
		if err != nil && strings.Contains(err.Error(), "NoCredentialProviders") {
			c.Ui.Error("ERROR: No AWS credentials were found.  Either set the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or run this program on an EC2 instance that has an IAM Role with the appropriate permissions.")
			return 1
		} else if err != nil {
			panic(err)
		}

		// Sleep here to give time for AMI to get found
		time.Sleep(3000 * time.Millisecond)

		// Assign tags to this AMI.  We'll use these when it comes time to delete the AMI
		c.Ui.Output("==> Adding tags to AMI " + *resp.ImageID + "...")

		svc.CreateTags(&ec2.CreateTagsInput{
			Resources: []*string{resp.ImageID},
			Tags: []*ec2.Tag{
				&ec2.Tag{ Key: aws.String("ec2-snapper-instance-id"), Value: &c.InstanceId },
			},
		})

		// Check the status of the AMI
		respDscrImages, err := svc.DescribeImages(&ec2.DescribeImagesInput{
			Filters: []*ec2.Filter{
				&ec2.Filter{
					Name: aws.String("image-id"),
					Values: []*string{resp.ImageID},
				},
			},
		})
		if err != nil {
			panic(err)
		}

		// If no AMI at all was found, throw an error
		if len(respDscrImages.Images) == 0 {
			c.Ui.Error("ERROR: Could not find the AMI just created.")
			return 1
		}

		// If the AMI's status is failed throw an error
		if *respDscrImages.Images[0].State == "failed" {
			c.Ui.Error("ERROR: AMI was created but entered a state of 'failed'. This is an AWS issue. Please re-run this command.  Note that you will need to manually de-register the AMI in the AWS console or via the API.")
			return 1
		}

		// Announce success
		c.Ui.Info("==> Success! Created " + *resp.ImageID + " named \"" + name + "\"")
		return 0
	}

<|endoftext|>


<commit_before>package crypto

import (
	"crypto/cipher"
	"crypto/rand"

	"golang.org/x/crypto/twofish"
)

const (
	BlockSize = twofish.BlockSize
	KeySize   = 32
)

type (
	EncryptionKey [KeySize]byte
)

// Encryption and decryption of []bytes is supported, but requires keeping some
// overhead information. Also, nothing is done in-place, which means the
// functions are more memory intensive, but that's not generally the bottleneck
// when doing encryption. Developers are less likely to make mistakes when
// inputs and outputs are different memory, which is why this method has been
// chosen. Additionally, the overhead of using encryption is more transparent.

// GenerateEncryptionKey produces a key that can be used for encrypting and
// decrypting files.
func GenerateEncryptionKey() (key EncryptionKey, err error) {
	_, err = rand.Read(key[:])
	if err != nil {
		return
	}

	return
}

// EncryptBytes encrypts a []byte using a key. The padded ciphertext, iv, and
// amount of padding used are returned. `plaintext` is not overwritten.
func EncryptBytes(key EncryptionKey, plaintext []byte) (ciphertext []byte, iv []byte, padding int, err error) {
	// Determine the length needed for padding. The ciphertext must be padded
	// to a multiple of BlockSize.
	padding = BlockSize - (len(plaintext) % BlockSize)
	if padding == BlockSize {
		padding = 0
	}

	// Create the padded + unencrypted ciphertext.
	ciphertext = make([]byte, len(plaintext)+padding)
	copy(ciphertext, plaintext)

	// Create the iv.
	iv = make([]byte, BlockSize)
	_, err = rand.Read(iv)
	if err != nil {
		return
	}

	// Encrypt the ciphertext.
	block, err := twofish.NewCipher(key[:])
	if err != nil {
		return
	}
	encrypter := cipher.NewCBCEncrypter(block, iv)
	encrypter.CryptBlocks(ciphertext, ciphertext)

	return
}

// DecryptBytes decrypts a ciphertext using a key, an iv, and a volume of
// padding. `ciphertext` is not overwritten. The plaintext is returned.
func DecryptBytes(key EncryptionKey, ciphertext []byte, iv []byte, padding int) (plaintext []byte, err error) {
	// Verify the iv is the correct length.
	if len(iv) != BlockSize {
		return errors.New("iv is not correct size")
	}
	if len(ciphertext) % BlockSize != 0 {
		return errors.New("ciphertext is not correct size")
	}
	if padding > ciphertext {
		return errors.New("stated padding is longer than the ciphertext")
	}

	// Allocate the plaintext.
	plaintext = make([]byte, len(ciphertext))

	// Decrypt the ciphertext.
	block, err := twofish.NewCipher(key[:])
	if err != nil {
		return
	}
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(ciphertext, plaintext)

	// Remove the padding.
	plaintext = plaintext[:len(ciphertext)-padding]
	return
}
<commit_msg>fix errors in encryption implementation<commit_after>package crypto

import (
	"crypto/cipher"
	"crypto/rand"
	"errors"

	"golang.org/x/crypto/twofish"
)

const (
	BlockSize = twofish.BlockSize
	KeySize   = 32
)

type (
	EncryptionKey [KeySize]byte
)

// Encryption and decryption of []bytes is supported, but requires keeping some
// overhead information. Also, nothing is done in-place, which means the
// functions are more memory intensive, but that's not generally the bottleneck
// when doing encryption. Developers are less likely to make mistakes when
// inputs and outputs are different memory, which is why this method has been
// chosen. Additionally, the overhead of using encryption is more transparent.

// GenerateEncryptionKey produces a key that can be used for encrypting and
// decrypting files.
func GenerateEncryptionKey() (key EncryptionKey, err error) {
	_, err = rand.Read(key[:])
	if err != nil {
		return
	}

	return
}

// EncryptBytes encrypts a []byte using a key. The padded ciphertext, iv, and
// amount of padding used are returned. `plaintext` is not overwritten.
func EncryptBytes(key EncryptionKey, plaintext []byte) (ciphertext []byte, iv []byte, padding int, err error) {
	// Determine the length needed for padding. The ciphertext must be padded
	// to a multiple of BlockSize.
	padding = BlockSize - (len(plaintext) % BlockSize)
	if padding == BlockSize {
		padding = 0
	}

	// Create the padded + unencrypted ciphertext.
	ciphertext = make([]byte, len(plaintext)+padding)
	copy(ciphertext, plaintext)

	// Create the iv.
	iv = make([]byte, BlockSize)
	_, err = rand.Read(iv)
	if err != nil {
		return
	}

	// Encrypt the ciphertext.
	blockCipher, err := twofish.NewCipher(key[:])
	if err != nil {
		return
	}
	encrypter := cipher.NewCBCEncrypter(blockCipher, iv)
	encrypter.CryptBlocks(ciphertext, ciphertext)

	return
}

// DecryptBytes decrypts a ciphertext using a key, an iv, and a volume of
// padding. `ciphertext` is not overwritten. The plaintext is returned.
func DecryptBytes(key EncryptionKey, ciphertext []byte, iv []byte, padding int) (plaintext []byte, err error) {
	// Verify the iv is the correct length.
	if len(iv) != BlockSize {
		err = errors.New("iv is not correct size")
		return
	}
	if len(ciphertext)%BlockSize != 0 {
		err = errors.New("ciphertext is not correct size")
		return
	}
	if padding > len(ciphertext) {
		err = errors.New("stated padding is longer than the ciphertext")
		return
	}

	// Allocate the plaintext.
	plaintext = make([]byte, len(ciphertext))

	// Decrypt the ciphertext.
	blockCipher, err := twofish.NewCipher(key[:])
	if err != nil {
		return
	}
	decrypter := cipher.NewCBCDecrypter(blockCipher, iv)
	decrypter.CryptBlocks(plaintext, ciphertext)

	// Remove the padding.
	plaintext = plaintext[:len(ciphertext)-padding]
	return
}
<|endoftext|>


<commit_before>package data

import (
	"fmt"
	"sort"
)

type Trade struct {
	LedgerSequence   uint32
	TransactionIndex uint32
	TransactionType  string
	Op               string
	Paid             *Amount
	Got              *Amount
	Giver            Account
	Taker            Account
}

func newTrade(txm *TransactionWithMetaData, i int) (*Trade, error) {
	_, final, previous, action := txm.MetaData.AffectedNodes[i].AffectedNode()
	v, ok := final.(*Offer)
	if !ok || action == Created {
		return nil, nil
	}
	p := previous.(*Offer)
	if p != nil && p.TakerGets == nil || p.TakerPays == nil {
		// Some "micro" offer consumptions don't change both balances!
		return nil, nil
	}
	paid, err := p.TakerPays.Subtract(v.TakerPays)
	if err != nil {
		return nil, err
	}
	got, err := p.TakerGets.Subtract(v.TakerGets)
	if err != nil {
		return nil, err
	}
	trade := &Trade{
		LedgerSequence:   txm.LedgerSequence,
		TransactionIndex: txm.MetaData.TransactionIndex,
		TransactionType:  txm.GetTransactionType().String(),
		Op:               "Modify",
		Paid:             paid,
		Got:              got,
		Giver:            *v.Account,
		Taker:            txm.Transaction.GetBase().Account,
	}
	if action == Deleted {
		trade.Op = "Delete"
	}
	return trade, nil
}

func (t *Trade) Rate() float64 {
	return t.Paid.Ratio(*t.Got).Float()
}

func (t Trade) String() string {
	return fmt.Sprintf("%8d %3d %22.8f %22.8f %-38s %-38s %34s %34s %11s %s", t.LedgerSequence, t.TransactionIndex, t.Paid.Float(), t.Rate(), t.Got.Asset(), t.Paid.Asset(), t.Taker, t.Giver, t.TransactionType, t.Op)

}

type TradeSlice []Trade

func NewTradeSlice(txm *TransactionWithMetaData) (TradeSlice, error) {
	var trades TradeSlice
	for i := range txm.MetaData.AffectedNodes {
		trade, err := newTrade(txm, i)
		if err != nil {
			return nil, err
		}
		if trade != nil {
			trades = append(trades, *trade)
		}
	}
	trades.Sort()
	return trades, nil
}

func (s TradeSlice) Filter(account Account) TradeSlice {
	var trades TradeSlice
	for i := range s {
		if s[i].Taker.Equals(account) || s[i].Giver.Equals(account) {
			trades = append(trades, s[i])
		}
	}
	return trades
}

func (s TradeSlice) Sort()         { sort.Sort(s) }
func (s TradeSlice) Len() int      { return len(s) }
func (s TradeSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s TradeSlice) Less(i, j int) bool {
	if s[i].LedgerSequence == s[j].LedgerSequence {
		if s[i].TransactionIndex == s[j].TransactionIndex {
			if s[i].Got.Currency.Equals(s[j].Got.Currency) {
				if s[i].Got.Issuer.Equals(s[j].Got.Issuer) {
					if s[i].Paid.Currency.Equals(s[j].Paid.Currency) {
						if s[i].Paid.Issuer.Equals(s[j].Paid.Issuer) {
							return s[i].Rate() < s[j].Rate()
						}
						return s[i].Paid.Issuer.Less(s[j].Paid.Issuer)
					}
					return s[i].Paid.Currency.Less(s[j].Paid.Currency)
				}
				return s[i].Got.Issuer.Less(s[j].Got.Issuer)
			}
			return s[i].Got.Currency.Less(s[j].Got.Currency)
		}
		return s[i].TransactionIndex < s[j].TransactionIndex
	}
	return s[i].LedgerSequence < s[j].LedgerSequence
}
<commit_msg>Alter Trade formatting<commit_after>package data

import (
	"fmt"
	"sort"
)

type Trade struct {
	LedgerSequence   uint32
	TransactionIndex uint32
	TransactionType  string
	Op               string
	Paid             *Amount
	Got              *Amount
	Giver            Account
	Taker            Account
}

func newTrade(txm *TransactionWithMetaData, i int) (*Trade, error) {
	_, final, previous, action := txm.MetaData.AffectedNodes[i].AffectedNode()
	v, ok := final.(*Offer)
	if !ok || action == Created {
		return nil, nil
	}
	p := previous.(*Offer)
	if p != nil && p.TakerGets == nil || p.TakerPays == nil {
		// Some "micro" offer consumptions don't change both balances!
		return nil, nil
	}
	paid, err := p.TakerPays.Subtract(v.TakerPays)
	if err != nil {
		return nil, err
	}
	got, err := p.TakerGets.Subtract(v.TakerGets)
	if err != nil {
		return nil, err
	}
	trade := &Trade{
		LedgerSequence:   txm.LedgerSequence,
		TransactionIndex: txm.MetaData.TransactionIndex,
		TransactionType:  txm.GetTransactionType().String(),
		Op:               "Modify",
		Paid:             paid,
		Got:              got,
		Giver:            *v.Account,
		Taker:            txm.Transaction.GetBase().Account,
	}
	if action == Deleted {
		trade.Op = "Delete"
	}
	return trade, nil
}

func (t *Trade) Rate() float64 {
	return t.Got.Ratio(*t.Paid).Float()
}

func (t Trade) String() string {
	return fmt.Sprintf("%8d %3d %22.8f %22.8f %-38s %22.8f %-38s %34s %34s %11s %s", t.LedgerSequence, t.TransactionIndex, t.Rate(), t.Paid.Float(), t.Paid.Asset(), t.Got.Float(), t.Got.Asset(), t.Taker, t.Giver, t.TransactionType, t.Op)

}

type TradeSlice []Trade

func NewTradeSlice(txm *TransactionWithMetaData) (TradeSlice, error) {
	var trades TradeSlice
	for i := range txm.MetaData.AffectedNodes {
		trade, err := newTrade(txm, i)
		if err != nil {
			return nil, err
		}
		if trade != nil {
			trades = append(trades, *trade)
		}
	}
	trades.Sort()
	return trades, nil
}

func (s TradeSlice) Filter(account Account) TradeSlice {
	var trades TradeSlice
	for i := range s {
		if s[i].Taker.Equals(account) || s[i].Giver.Equals(account) {
			trades = append(trades, s[i])
		}
	}
	return trades
}

func (s TradeSlice) Sort()         { sort.Sort(s) }
func (s TradeSlice) Len() int      { return len(s) }
func (s TradeSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s TradeSlice) Less(i, j int) bool {
	if s[i].LedgerSequence == s[j].LedgerSequence {
		if s[i].TransactionIndex == s[j].TransactionIndex {
			if s[i].Got.Currency.Equals(s[j].Got.Currency) {
				if s[i].Got.Issuer.Equals(s[j].Got.Issuer) {
					if s[i].Paid.Currency.Equals(s[j].Paid.Currency) {
						if s[i].Paid.Issuer.Equals(s[j].Paid.Issuer) {
							return s[i].Rate() < s[j].Rate()
						}
						return s[i].Paid.Issuer.Less(s[j].Paid.Issuer)
					}
					return s[i].Paid.Currency.Less(s[j].Paid.Currency)
				}
				return s[i].Got.Issuer.Less(s[j].Got.Issuer)
			}
			return s[i].Got.Currency.Less(s[j].Got.Currency)
		}
		return s[i].TransactionIndex < s[j].TransactionIndex
	}
	return s[i].LedgerSequence < s[j].LedgerSequence
}
<|endoftext|>


<commit_before>package deepcopier

import (
	"fmt"
	"reflect"
	"strings"
)

const (
	// TagName is the deepcopier struct tag name.
	TagName = "deepcopier"
	// FieldOptionName is the from field option name for struct tag.
	FieldOptionName = "field"
	// ContextOptionName is the context option name for struct tag.
	ContextOptionName = "context"
	// SkipOptionName is the skip option name for struct tag.
	SkipOptionName = "skip"
)

type (
	// TagOptions is a map that contains extracted struct tag options.
	TagOptions map[string]string

	// Options are copier options.
	Options struct {
		// Context given to WithContext() method.
		Context map[string]interface{}
		// Reversed reverses struct tag checkings.
		Reversed bool
	}

	// Processor is a copy processor.
	Processor func(dst interface{}, src interface{}, options Options) error
)

// DeepCopier deep copies a struct to/from a struct.
type DeepCopier struct {
	dst interface{}
	src interface{}
	ctx map[string]interface{}
}

// Copy sets source or destination.
func Copy(src interface{}) *DeepCopier {
	return &DeepCopier{src: src}
}

// WithContext injects the given context into the builder instance.
func (dc *DeepCopier) WithContext(ctx map[string]interface{}) *DeepCopier {
	dc.ctx = ctx
	return dc
}

// To sets the destination.
func (dc *DeepCopier) To(dst interface{}) error {
	dc.dst = dst
	return process(dc.dst, dc.src, Options{Context: dc.ctx})
}

// From sets the given the source as destination and destination as source.
func (dc *DeepCopier) From(src interface{}) error {
	dc.dst = dc.src
	dc.src = src
	return process(dc.dst, dc.src, Options{Context: dc.ctx, Reversed: true})
}

// process handles copy.
func process(dst interface{}, src interface{}, args ...Options) error {
	var (
		options  = Options{}
		dstValue = reflect.Indirect(reflect.ValueOf(dst))
	)

	if len(args) > 0 {
		options = args[0]
	}

	if !dstValue.CanAddr() {
		return fmt.Errorf("destination %+v is unaddressable", dstValue.Interface())
	}

	processors := []Processor{
		processMethods,
		processFields,
	}

	for _, processor := range processors {
		if err := processor(dst, src, options); err != nil {
			return err
		}
	}

	return nil
}

func processMethods(dst interface{}, src interface{}, options Options) error {
	var (
		dstValue       = reflect.Indirect(reflect.ValueOf(dst))
		srcMethodNames = getMethodNames(src)
	)

	for _, m := range srcMethodNames {
		name, opts := getRelatedField(dst, m)
		if name == "" {
			continue
		}

		if _, ok := opts[SkipOptionName]; ok {
			continue
		}

		method := reflect.ValueOf(src).MethodByName(m)
		if !method.IsValid() {
			return fmt.Errorf("method %s is invalid", m)
		}

		var (
			dstFieldType, _ = dstValue.Type().FieldByName(name)
			dstFieldValue   = dstValue.FieldByName(name)
		)

		withContext := false
		if _, ok := opts[ContextOptionName]; ok {
			withContext = true
		}

		args := []reflect.Value{}
		if withContext {
			args = []reflect.Value{reflect.ValueOf(options.Context)}
		}

		result := method.Call(args)[0]

		if result.Type().AssignableTo(dstFieldType.Type) && result.IsValid() {
			dstFieldValue.Set(result)
		}
	}

	return nil
}

func processFields(dst interface{}, src interface{}, options Options) error {
	var (
		srcValue      = reflect.Indirect(reflect.ValueOf(src))
		dstValue      = reflect.Indirect(reflect.ValueOf(dst))
		srcFieldNames = getFieldNames(src)
	)

	for _, f := range srcFieldNames {
		var (
			srcFieldValue               = srcValue.FieldByName(f)
			srcFieldType, srcFieldFound = srcValue.Type().FieldByName(f)
			srcFieldName                = srcFieldType.Name
			dstFieldName                = srcFieldName
			tagOptions                  TagOptions
		)

		if !srcFieldFound {
			continue
		}

		if options.Reversed {
			tagOptions = getTagOptions(srcFieldType.Tag.Get(TagName))
			if v, ok := tagOptions[FieldOptionName]; ok && v != "" {
				dstFieldName = v
			}
		} else {
			if name, opts := getRelatedField(dst, srcFieldName); name != "" {
				dstFieldName, tagOptions = name, opts
			}
		}

		if _, ok := tagOptions[SkipOptionName]; ok {
			continue
		}

		var (
			dstFieldType, dstFieldFound = dstValue.Type().FieldByName(dstFieldName)
			dstFieldValue               = dstValue.FieldByName(dstFieldName)
		)

		if !dstFieldFound {
			continue
		}

		// Empty interfaces
		if dstFieldValue.Kind() == reflect.Interface {
			dstFieldValue.Set(srcFieldValue)
			continue
		}

		// Ptr -> Value
		if srcFieldType.Type.Kind() == reflect.Ptr && !srcFieldValue.IsNil() && dstFieldType.Type.Kind() != reflect.Ptr {
			indirect := reflect.Indirect(srcFieldValue)

			if indirect.Type().AssignableTo(dstFieldType.Type) {
				dstFieldValue.Set(indirect)
				continue
			}
		}

		// Other types
		if srcFieldType.Type.AssignableTo(dstFieldType.Type) {
			dstFieldValue.Set(srcFieldValue)
		}
	}

	return nil
}

// getTagOptions parses deepcopier tag field and returns options.
func getTagOptions(value string) TagOptions {
	options := TagOptions{}

	for _, opt := range strings.Split(value, ";") {
		o := strings.Split(opt, ":")

		// deepcopier:"keyword; without; value;"
		if len(o) == 1 {
			options[o[0]] = ""
		}

		// deepcopier:"key:value; anotherkey:anothervalue"
		if len(o) == 2 {
			options[strings.TrimSpace(o[0])] = strings.TrimSpace(o[1])
		}
	}

	return options
}

// getRelatedField returns first matching field.
func getRelatedField(instance interface{}, name string) (string, TagOptions) {
	var (
		value      = reflect.Indirect(reflect.ValueOf(instance))
		fieldName  string
		tagOptions TagOptions
	)

	for i := 0; i < value.NumField(); i++ {
		var (
			vField     = value.Field(i)
			tField     = value.Type().Field(i)
			tagOptions = getTagOptions(tField.Tag.Get(TagName))
		)

		if tField.Type.Kind() == reflect.Struct && tField.Anonymous {
			if n, o := getRelatedField(vField.Interface(), name); n != "" {
				return n, o
			}
		}

		if v, ok := tagOptions[FieldOptionName]; ok && v == name {
			return tField.Name, tagOptions
		}

		if tField.Name == name {
			return tField.Name, tagOptions
		}
	}

	return fieldName, tagOptions
}

// getMethodNames returns instance's method names.
func getMethodNames(instance interface{}) []string {
	var methods []string

	t := reflect.TypeOf(instance)
	for i := 0; i < t.NumMethod(); i++ {
		methods = append(methods, t.Method(i).Name)
	}

	return methods
}

// getFieldNames returns instance's field names.
func getFieldNames(instance interface{}) []string {
	var (
		fields []string
		v      = reflect.Indirect(reflect.ValueOf(instance))
		t      = v.Type()
	)

	if t.Kind() != reflect.Struct {
		return nil
	}

	for i := 0; i < v.NumField(); i++ {
		var (
			vField = v.Field(i)
			tField = v.Type().Field(i)
		)

		// Is exportable?
		if tField.PkgPath != "" {
			continue
		}

		if tField.Type.Kind() == reflect.Struct && tField.Anonymous {
			fields = append(fields, getFieldNames(vField.Interface())...)
			continue
		}

		fields = append(fields, tField.Name)
	}

	return fields
}
<commit_msg>Refacto: remove processors.<commit_after>package deepcopier

import (
	"fmt"
	"reflect"
	"strings"
)

const (
	// TagName is the deepcopier struct tag name.
	TagName = "deepcopier"
	// FieldOptionName is the from field option name for struct tag.
	FieldOptionName = "field"
	// ContextOptionName is the context option name for struct tag.
	ContextOptionName = "context"
	// SkipOptionName is the skip option name for struct tag.
	SkipOptionName = "skip"
)

type (
	// TagOptions is a map that contains extracted struct tag options.
	TagOptions map[string]string

	// Options are copier options.
	Options struct {
		// Context given to WithContext() method.
		Context map[string]interface{}
		// Reversed reverses struct tag checkings.
		Reversed bool
	}
)

// DeepCopier deep copies a struct to/from a struct.
type DeepCopier struct {
	dst interface{}
	src interface{}
	ctx map[string]interface{}
}

// Copy sets source or destination.
func Copy(src interface{}) *DeepCopier {
	return &DeepCopier{src: src}
}

// WithContext injects the given context into the builder instance.
func (dc *DeepCopier) WithContext(ctx map[string]interface{}) *DeepCopier {
	dc.ctx = ctx
	return dc
}

// To sets the destination.
func (dc *DeepCopier) To(dst interface{}) error {
	dc.dst = dst
	return process(dc.dst, dc.src, Options{Context: dc.ctx})
}

// From sets the given the source as destination and destination as source.
func (dc *DeepCopier) From(src interface{}) error {
	dc.dst = dc.src
	dc.src = src
	return process(dc.dst, dc.src, Options{Context: dc.ctx, Reversed: true})
}

// process handles copy.
func process(dst interface{}, src interface{}, args ...Options) error {
	var (
		options        = Options{}
		srcValue       = reflect.Indirect(reflect.ValueOf(src))
		dstValue       = reflect.Indirect(reflect.ValueOf(dst))
		srcFieldNames  = getFieldNames(src)
		srcMethodNames = getMethodNames(src)
	)

	if len(args) > 0 {
		options = args[0]
	}

	if !dstValue.CanAddr() {
		return fmt.Errorf("destination %+v is unaddressable", dstValue.Interface())
	}

	for _, m := range srcMethodNames {
		name, opts := getRelatedField(dst, m)
		if name == "" {
			continue
		}

		if _, ok := opts[SkipOptionName]; ok {
			continue
		}

		method := reflect.ValueOf(src).MethodByName(m)
		if !method.IsValid() {
			return fmt.Errorf("method %s is invalid", m)
		}

		var (
			dstFieldType, _ = dstValue.Type().FieldByName(name)
			dstFieldValue   = dstValue.FieldByName(name)
		)

		withContext := false
		if _, ok := opts[ContextOptionName]; ok {
			withContext = true
		}

		args := []reflect.Value{}
		if withContext {
			args = []reflect.Value{reflect.ValueOf(options.Context)}
		}

		result := method.Call(args)[0]

		if result.Type().AssignableTo(dstFieldType.Type) && result.IsValid() {
			dstFieldValue.Set(result)
		}
	}

	for _, f := range srcFieldNames {
		var (
			srcFieldValue               = srcValue.FieldByName(f)
			srcFieldType, srcFieldFound = srcValue.Type().FieldByName(f)
			srcFieldName                = srcFieldType.Name
			dstFieldName                = srcFieldName
			tagOptions                  TagOptions
		)

		if !srcFieldFound {
			continue
		}

		if options.Reversed {
			tagOptions = getTagOptions(srcFieldType.Tag.Get(TagName))
			if v, ok := tagOptions[FieldOptionName]; ok && v != "" {
				dstFieldName = v
			}
		} else {
			if name, opts := getRelatedField(dst, srcFieldName); name != "" {
				dstFieldName, tagOptions = name, opts
			}
		}

		if _, ok := tagOptions[SkipOptionName]; ok {
			continue
		}

		var (
			dstFieldType, dstFieldFound = dstValue.Type().FieldByName(dstFieldName)
			dstFieldValue               = dstValue.FieldByName(dstFieldName)
		)

		if !dstFieldFound {
			continue
		}

		// Empty interfaces
		if dstFieldValue.Kind() == reflect.Interface {
			dstFieldValue.Set(srcFieldValue)
			continue
		}

		// Ptr -> Value
		if srcFieldType.Type.Kind() == reflect.Ptr && !srcFieldValue.IsNil() && dstFieldType.Type.Kind() != reflect.Ptr {
			indirect := reflect.Indirect(srcFieldValue)

			if indirect.Type().AssignableTo(dstFieldType.Type) {
				dstFieldValue.Set(indirect)
				continue
			}
		}

		// Other types
		if srcFieldType.Type.AssignableTo(dstFieldType.Type) {
			dstFieldValue.Set(srcFieldValue)
		}
	}

	return nil
}

// getTagOptions parses deepcopier tag field and returns options.
func getTagOptions(value string) TagOptions {
	options := TagOptions{}

	for _, opt := range strings.Split(value, ";") {
		o := strings.Split(opt, ":")

		// deepcopier:"keyword; without; value;"
		if len(o) == 1 {
			options[o[0]] = ""
		}

		// deepcopier:"key:value; anotherkey:anothervalue"
		if len(o) == 2 {
			options[strings.TrimSpace(o[0])] = strings.TrimSpace(o[1])
		}
	}

	return options
}

// getRelatedField returns first matching field.
func getRelatedField(instance interface{}, name string) (string, TagOptions) {
	var (
		value      = reflect.Indirect(reflect.ValueOf(instance))
		fieldName  string
		tagOptions TagOptions
	)

	for i := 0; i < value.NumField(); i++ {
		var (
			vField     = value.Field(i)
			tField     = value.Type().Field(i)
			tagOptions = getTagOptions(tField.Tag.Get(TagName))
		)

		if tField.Type.Kind() == reflect.Struct && tField.Anonymous {
			if n, o := getRelatedField(vField.Interface(), name); n != "" {
				return n, o
			}
		}

		if v, ok := tagOptions[FieldOptionName]; ok && v == name {
			return tField.Name, tagOptions
		}

		if tField.Name == name {
			return tField.Name, tagOptions
		}
	}

	return fieldName, tagOptions
}

// getMethodNames returns instance's method names.
func getMethodNames(instance interface{}) []string {
	var methods []string

	t := reflect.TypeOf(instance)
	for i := 0; i < t.NumMethod(); i++ {
		methods = append(methods, t.Method(i).Name)
	}

	return methods
}

// getFieldNames returns instance's field names.
func getFieldNames(instance interface{}) []string {
	var (
		fields []string
		v      = reflect.Indirect(reflect.ValueOf(instance))
		t      = v.Type()
	)

	if t.Kind() != reflect.Struct {
		return nil
	}

	for i := 0; i < v.NumField(); i++ {
		var (
			vField = v.Field(i)
			tField = v.Type().Field(i)
		)

		// Is exportable?
		if tField.PkgPath != "" {
			continue
		}

		if tField.Type.Kind() == reflect.Struct && tField.Anonymous {
			fields = append(fields, getFieldNames(vField.Interface())...)
			continue
		}

		fields = append(fields, tField.Name)
	}

	return fields
}
<|endoftext|>


<commit_before>package deepcopier

import (
	"fmt"
	"reflect"
	"strings"
	"time"

	"github.com/guregu/null"
	"github.com/lib/pq"
	"github.com/oleiade/reflections"
)

const (
	// TagName is struct field tag name.
	TagName = "deepcopier"

	// FieldOptionName is the from field option name for struct tag.
	FieldOptionName = "field"

	// ContextOptionName is the context option name for struct tag.
	ContextOptionName = "context"

	// SkipOptionName is the skip option name for struct tag.
	SkipOptionName = "skip"
)

// DeepCopier deep copies a struct to/from a struct.
type DeepCopier struct {
	Source      interface{}
	Destination interface{}
	Tagged      interface{}
	Context     map[string]interface{}
	Reversed    bool
}

// FieldOptions contains options passed to SetField method.
type FieldOptions struct {
	SourceField      string
	DestinationField string
	WithContext      bool
	Skip             bool
}

// Copy sets the source.
func Copy(source interface{}) *DeepCopier {
	return &DeepCopier{
		Source:   source,
		Reversed: false,
	}
}

// To sets the given tagged struct as destination struct.
// Source -> Destination
func (dc *DeepCopier) To(tagged interface{}) error {
	dc.Destination = tagged
	dc.Tagged = tagged
	return dc.ProcessCopy()
}

// From sets the given tagged struct as source and the current source as destination.
// Source <- Destination
func (dc *DeepCopier) From(tagged interface{}) error {
	dc.Destination = dc.Source
	dc.Source = tagged
	dc.Tagged = tagged
	dc.Reversed = true
	return dc.ProcessCopy()
}

// ProcessCopy processes copy.
func (dc *DeepCopier) ProcessCopy() error {
	fields, _ := reflections.Fields(dc.Tagged)
	for _, field := range fields {
		fieldOptions := &FieldOptions{
			SourceField:      field,
			DestinationField: field,
			WithContext:      false,
			Skip:             false,
		}
		tagOptions, _ := reflections.GetFieldTag(dc.Tagged, field, TagName)
		if tagOptions != "" {
			opts := dc.GetTagOptions(tagOptions)
			if _, ok := opts[FieldOptionName]; ok {
				fieldName := opts[FieldOptionName]
				if !dc.Reversed {
					fieldOptions.SourceField = fieldName
				} else {
					fieldOptions.DestinationField = fieldName
				}
			}
			if _, ok := opts[ContextOptionName]; ok {
				fieldOptions.WithContext = true
			}
			if _, ok := opts[SkipOptionName]; ok {
				fieldOptions.Skip = true
			}
		}
		if err := dc.SetField(fieldOptions); err != nil {
			return err
		}
	}
	return nil
}

// -----------------------------------------------------------------------------
// Options
// -----------------------------------------------------------------------------

// WithContext injects the given context into the builder instance.
func (dc *DeepCopier) WithContext(context map[string]interface{}) *DeepCopier {
	dc.Context = context
	return dc
}

// -----------------------------------------------------------------------------
// Struct tags
// -----------------------------------------------------------------------------

// GetTagOptions parses deepcopier tag field and returns options.
func (dc *DeepCopier) GetTagOptions(value string) map[string]string {
	options := map[string]string{}
	for _, opt := range strings.Split(value, ";") {
		o := strings.Split(opt, ":")
		// deepcopier:"keyword; without; value;"
		if len(o) == 1 {
			k := o[0]
			options[k] = ""
		}
		// deepcopier:"key:value; anotherkey:anothervalue"
		if len(o) == 2 {
			k, v := o[0], o[1]
			k = strings.TrimSpace(k)
			v = strings.TrimSpace(v)
			options[k] = v
		}
	}
	return options
}

// -----------------------------------------------------------------------------
// Field Setters
// -----------------------------------------------------------------------------

// SetField sets the value of the given field.
func (dc *DeepCopier) SetField(options *FieldOptions) error {
	if options.Skip {
		return nil
	}

	if dc.Reversed {
		has, _ := reflections.HasField(dc.Destination, options.DestinationField)
		if !has {
			return nil
		}
	}

	has, _ := reflections.HasField(dc.Source, options.SourceField)
	if !has {
		err := dc.HandleMethod(options)
		if err != nil {
			has, _ = reflections.HasField(dc.Destination, options.DestinationField)
			if has {
				return nil
			}
		}
		return nil
	}

	kind, _ := reflections.GetFieldKind(dc.Source, options.SourceField)
	if kind == reflect.Struct {
		if err := dc.HandleStructField(options); err != nil {
			return err
		}
		return nil
	}

	if err := dc.HandleField(options); err != nil {
		return err
	}

	return nil
}

// SetFieldValue Sets the given value to the given field.
func (dc *DeepCopier) SetFieldValue(entity interface{}, name string, value reflect.Value) error {
	kind := value.Kind()

	// Maps
	if kind == reflect.Map {
		switch v := value.Interface().(type) {
		case map[string]interface{}, map[string]string, map[string]map[string]string, map[string]map[string]map[string]string:
			if err := reflections.SetField(entity, name, v); err != nil {
				return err
			}
			return nil
		}
	}

	// Structs
	if kind == reflect.Struct {
		switch v := value.Interface().(type) {
		case time.Time, pq.NullTime:
			if err := reflections.SetField(entity, name, v); err != nil {
				return err
			}
			return nil
		case null.String:
			if err := reflections.SetField(entity, name, v); err != nil {
				return err
			}
			return nil
		}
	}

	// Slices
	if kind == reflect.Slice {
		switch v := value.Interface().(type) {
		case []int8, []int16, []int32, []int64, []int, []uint8, []uint16, []uint32, []uint64, []uint, []float32, []float64, []string, []bool:
			if err := reflections.SetField(entity, name, v); err != nil {
				return err
			}
			return nil
		}
	}

	// Reflect
	switch kind {
	case reflect.Int8:
		if err := reflections.SetField(entity, name, int8(value.Int())); err != nil {
			return err
		}
		return nil
	case reflect.Int16:
		if err := reflections.SetField(entity, name, int16(value.Int())); err != nil {
			return err
		}
		return nil
	case reflect.Int32:
		if err := reflections.SetField(entity, name, int32(value.Int())); err != nil {
			return err
		}
		return nil
	case reflect.Int64:
		if err := reflections.SetField(entity, name, value.Int()); err != nil {
			return err
		}
		return nil
	case reflect.Int:
		if err := reflections.SetField(entity, name, int(value.Int())); err != nil {
			return err
		}
		return nil
	case reflect.Uint8:
		if err := reflections.SetField(entity, name, uint8(value.Uint())); err != nil {
			return err
		}
		return nil
	case reflect.Uint16:
		if err := reflections.SetField(entity, name, uint16(value.Uint())); err != nil {
			return err
		}
		return nil
	case reflect.Uint32:
		if err := reflections.SetField(entity, name, uint32(value.Uint())); err != nil {
			return err
		}
		return nil
	case reflect.Uint64:
		if err := reflections.SetField(entity, name, value.Uint()); err != nil {
			return err
		}
		return nil
	case reflect.Uint:
		if err := reflections.SetField(entity, name, uint(value.Uint())); err != nil {
			return err
		}
		return nil
	case reflect.Float32:
		if err := reflections.SetField(entity, name, float32(value.Float())); err != nil {
			return err
		}
		return nil
	case reflect.Float64:
		if err := reflections.SetField(entity, name, value.Float()); err != nil {
			return err
		}
		return nil
	case reflect.String:
		if err := reflections.SetField(entity, name, value.String()); err != nil {
			return err
		}
		return nil
	case reflect.Bool:
		if err := reflections.SetField(entity, name, value.Bool()); err != nil {
			return err
		}
		return nil
	}

	return nil
}

// -----------------------------------------------------------------------------
// Field Type Handlers
// -----------------------------------------------------------------------------

// HandleStructField sets the value for the given supported struct field.
func (dc *DeepCopier) HandleStructField(options *FieldOptions) error {
	f, err := reflections.GetField(dc.Source, options.SourceField)
	if err != nil {
		return err
	}

	switch v := f.(type) {
	case pq.NullTime:
		if v.Valid {
			if err := reflections.SetField(dc.Destination, options.DestinationField, &v.Time); err != nil {
				return err
			}
		}
	case time.Time:
		if err := reflections.SetField(dc.Destination, options.DestinationField, v); err != nil {
			return err
		}
	}

	return nil
}

// HandleField sets value for the given field.
func (dc *DeepCopier) HandleField(options *FieldOptions) error {
	v, err := reflections.GetField(dc.Source, options.SourceField)
	if err != nil {
		return err
	}

	value := reflect.ValueOf(v)
	if err := dc.SetFieldValue(dc.Destination, options.DestinationField, value); err != nil {
		return err
	}

	return nil
}

// HandleMethod tries to call method on model and sets result in resource field.
func (dc *DeepCopier) HandleMethod(options *FieldOptions) error {
	if dc.Reversed {
		return nil
	}

	method := reflect.ValueOf(dc.Source).MethodByName(options.SourceField)
	if !method.IsValid() {
		return fmt.Errorf("Method %s does not exist", options.SourceField)
	}

	var results []reflect.Value
	if options.WithContext {
		results = method.Call([]reflect.Value{reflect.ValueOf(dc.Context)})
	} else {
		results = method.Call([]reflect.Value{})
	}

	if err := dc.SetFieldValue(dc.Destination, options.DestinationField, results[0]); err != nil {
		return err
	}

	return nil
}
<commit_msg>Because less is more.<commit_after>package deepcopier

import (
	"fmt"
	"reflect"
	"strings"
	"time"

	"github.com/guregu/null"
	"github.com/lib/pq"
	"github.com/oleiade/reflections"
)

const (
	// TagName is struct field tag name.
	TagName = "deepcopier"

	// FieldOptionName is the from field option name for struct tag.
	FieldOptionName = "field"

	// ContextOptionName is the context option name for struct tag.
	ContextOptionName = "context"

	// SkipOptionName is the skip option name for struct tag.
	SkipOptionName = "skip"
)

// DeepCopier deep copies a struct to/from a struct.
type DeepCopier struct {
	Source      interface{}
	Destination interface{}
	Tagged      interface{}
	Context     map[string]interface{}
	Reversed    bool
}

// FieldOptions contains options passed to SetField method.
type FieldOptions struct {
	SourceField      string
	DestinationField string
	WithContext      bool
	Skip             bool
}

// Copy sets the source.
func Copy(source interface{}) *DeepCopier {
	return &DeepCopier{
		Source:   source,
		Reversed: false,
	}
}

// To sets the given tagged struct as destination struct.
// Source -> Destination
func (dc *DeepCopier) To(tagged interface{}) error {
	dc.Destination = tagged
	dc.Tagged = tagged
	return dc.ProcessCopy()
}

// From sets the given tagged struct as source and the current source as destination.
// Source <- Destination
func (dc *DeepCopier) From(tagged interface{}) error {
	dc.Destination = dc.Source
	dc.Source = tagged
	dc.Tagged = tagged
	dc.Reversed = true
	return dc.ProcessCopy()
}

// ProcessCopy processes copy.
func (dc *DeepCopier) ProcessCopy() error {
	fields, _ := reflections.Fields(dc.Tagged)
	for _, field := range fields {
		fieldOptions := &FieldOptions{
			SourceField:      field,
			DestinationField: field,
			WithContext:      false,
			Skip:             false,
		}
		tagOptions, _ := reflections.GetFieldTag(dc.Tagged, field, TagName)
		if tagOptions != "" {
			opts := dc.GetTagOptions(tagOptions)
			if _, ok := opts[FieldOptionName]; ok {
				fieldName := opts[FieldOptionName]
				if !dc.Reversed {
					fieldOptions.SourceField = fieldName
				} else {
					fieldOptions.DestinationField = fieldName
				}
			}
			if _, ok := opts[ContextOptionName]; ok {
				fieldOptions.WithContext = true
			}
			if _, ok := opts[SkipOptionName]; ok {
				fieldOptions.Skip = true
			}
		}
		if err := dc.SetField(fieldOptions); err != nil {
			return err
		}
	}
	return nil
}

// -----------------------------------------------------------------------------
// Options
// -----------------------------------------------------------------------------

// WithContext injects the given context into the builder instance.
func (dc *DeepCopier) WithContext(context map[string]interface{}) *DeepCopier {
	dc.Context = context
	return dc
}

// -----------------------------------------------------------------------------
// Struct tags
// -----------------------------------------------------------------------------

// GetTagOptions parses deepcopier tag field and returns options.
func (dc *DeepCopier) GetTagOptions(value string) map[string]string {
	options := map[string]string{}
	for _, opt := range strings.Split(value, ";") {
		o := strings.Split(opt, ":")
		// deepcopier:"keyword; without; value;"
		if len(o) == 1 {
			k := o[0]
			options[k] = ""
		}
		// deepcopier:"key:value; anotherkey:anothervalue"
		if len(o) == 2 {
			k, v := o[0], o[1]
			k = strings.TrimSpace(k)
			v = strings.TrimSpace(v)
			options[k] = v
		}
	}
	return options
}

// -----------------------------------------------------------------------------
// Field Setters
// -----------------------------------------------------------------------------

// SetField sets the value of the given field.
func (dc *DeepCopier) SetField(options *FieldOptions) error {
	if options.Skip {
		return nil
	}

	if dc.Reversed {
		has, _ := reflections.HasField(dc.Destination, options.DestinationField)
		if !has {
			return nil
		}
	}

	has, _ := reflections.HasField(dc.Source, options.SourceField)
	if !has {
		err := dc.HandleMethod(options)
		if err != nil {
			has, _ = reflections.HasField(dc.Destination, options.DestinationField)
			if has {
				return nil
			}
		}
		return nil
	}

	kind, _ := reflections.GetFieldKind(dc.Source, options.SourceField)
	if kind == reflect.Struct {
		if err := dc.HandleStructField(options); err != nil {
			return err
		}
		return nil
	}

	if err := dc.HandleField(options); err != nil {
		return err
	}

	return nil
}

// SetFieldValue Sets the given value to the given field.
func (dc *DeepCopier) SetFieldValue(entity interface{}, name string, value reflect.Value) error {
	kind := value.Kind()

	// Maps
	if kind == reflect.Map {
		switch v := value.Interface().(type) {
		case map[string]interface{}, map[string]string, map[string]map[string]string, map[string]map[string]map[string]string:
			if err := reflections.SetField(entity, name, v); err != nil {
				return err
			}
			return nil
		}
	}

	// Structs
	if kind == reflect.Struct {
		switch v := value.Interface().(type) {
		case time.Time, pq.NullTime, null.String:
			if err := reflections.SetField(entity, name, v); err != nil {
				return err
			}
			return nil
		}
	}

	// Slices
	if kind == reflect.Slice {
		switch v := value.Interface().(type) {
		case []int8, []int16, []int32, []int64, []int, []uint8, []uint16, []uint32, []uint64, []uint, []float32, []float64, []string, []bool:
			if err := reflections.SetField(entity, name, v); err != nil {
				return err
			}
			return nil
		}
	}

	// Reflect
	switch kind {
	case reflect.Int8:
		if err := reflections.SetField(entity, name, int8(value.Int())); err != nil {
			return err
		}
		return nil
	case reflect.Int16:
		if err := reflections.SetField(entity, name, int16(value.Int())); err != nil {
			return err
		}
		return nil
	case reflect.Int32:
		if err := reflections.SetField(entity, name, int32(value.Int())); err != nil {
			return err
		}
		return nil
	case reflect.Int64:
		if err := reflections.SetField(entity, name, value.Int()); err != nil {
			return err
		}
		return nil
	case reflect.Int:
		if err := reflections.SetField(entity, name, int(value.Int())); err != nil {
			return err
		}
		return nil
	case reflect.Uint8:
		if err := reflections.SetField(entity, name, uint8(value.Uint())); err != nil {
			return err
		}
		return nil
	case reflect.Uint16:
		if err := reflections.SetField(entity, name, uint16(value.Uint())); err != nil {
			return err
		}
		return nil
	case reflect.Uint32:
		if err := reflections.SetField(entity, name, uint32(value.Uint())); err != nil {
			return err
		}
		return nil
	case reflect.Uint64:
		if err := reflections.SetField(entity, name, value.Uint()); err != nil {
			return err
		}
		return nil
	case reflect.Uint:
		if err := reflections.SetField(entity, name, uint(value.Uint())); err != nil {
			return err
		}
		return nil
	case reflect.Float32:
		if err := reflections.SetField(entity, name, float32(value.Float())); err != nil {
			return err
		}
		return nil
	case reflect.Float64:
		if err := reflections.SetField(entity, name, value.Float()); err != nil {
			return err
		}
		return nil
	case reflect.String:
		if err := reflections.SetField(entity, name, value.String()); err != nil {
			return err
		}
		return nil
	case reflect.Bool:
		if err := reflections.SetField(entity, name, value.Bool()); err != nil {
			return err
		}
		return nil
	}

	return nil
}

// -----------------------------------------------------------------------------
// Field Type Handlers
// -----------------------------------------------------------------------------

// HandleStructField sets the value for the given supported struct field.
func (dc *DeepCopier) HandleStructField(options *FieldOptions) error {
	f, err := reflections.GetField(dc.Source, options.SourceField)
	if err != nil {
		return err
	}

	switch v := f.(type) {
	case pq.NullTime:
		if v.Valid {
			if err := reflections.SetField(dc.Destination, options.DestinationField, &v.Time); err != nil {
				return err
			}
		}
	case time.Time:
		if err := reflections.SetField(dc.Destination, options.DestinationField, v); err != nil {
			return err
		}
	}

	return nil
}

// HandleField sets value for the given field.
func (dc *DeepCopier) HandleField(options *FieldOptions) error {
	v, err := reflections.GetField(dc.Source, options.SourceField)
	if err != nil {
		return err
	}

	value := reflect.ValueOf(v)
	if err := dc.SetFieldValue(dc.Destination, options.DestinationField, value); err != nil {
		return err
	}

	return nil
}

// HandleMethod tries to call method on model and sets result in resource field.
func (dc *DeepCopier) HandleMethod(options *FieldOptions) error {
	if dc.Reversed {
		return nil
	}

	method := reflect.ValueOf(dc.Source).MethodByName(options.SourceField)
	if !method.IsValid() {
		return fmt.Errorf("Method %s does not exist", options.SourceField)
	}

	var results []reflect.Value
	if options.WithContext {
		results = method.Call([]reflect.Value{reflect.ValueOf(dc.Context)})
	} else {
		results = method.Call([]reflect.Value{})
	}

	if err := dc.SetFieldValue(dc.Destination, options.DestinationField, results[0]); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package reflections_test

import (
	"fmt"
	"github.com/oleiade/reflections"
	"log"
	"reflect"
)

type MyStruct struct {
	FirstField  string `matched:"first tag"`
	SecondField int    `matched:"second tag"`
	ThirdField  string `unmatched:"third tag"`
}

func ExampleGetField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	fieldsToExtract := []string{"FirstField", "ThirdField"}

	for _, fieldName := range fieldsToExtract {
		value, err := reflections.GetField(s, fieldName)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(value)
	}
}

func ExampleGetFieldKind() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var firstFieldKind reflect.Kind
	var secondFieldKind reflect.Kind
	var err error

	// GetFieldKind will return reflect.String
	firstFieldKind, err = reflections.GetFieldKind(s, "FirstField")
	if err != nil {
		log.Fatal(err)
	}

	// GetFieldKind will return reflect.Int
	secondFieldKind, err = reflections.GetFieldKind(s, "SecondField")
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleHasField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	// has == true
	has, _ := reflections.HasField(s, "FirstField")
	fmt.Println(has)

	// has == false
	has, _ = reflections.HasField(s, "FourthField")
	fmt.Println(has)
}

func ExampleFields() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var fields []string

	// Fields will list every structure exportable fields.
	// Here, it's content would be equal to:
	// []string{"FirstField", "SecondField", "ThirdField"}
	fields, _ = reflections.Fields(s)
	fmt.Println(fields)
}

func ExampleItems() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var structItems map[string]interface{}

	// Items will return a field name to
	// field value map
	structItems, _ = reflections.Items(s)
	fmt.Println(structItems)
}

func ExampleTags() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var structTags map[string]string

	// Tags will return a field name to tag content
	// map. Nota that only field with the tag name
	// you've provided which will be matched.
	// Here structTags will contain:
	// {
	//     "FirstField": "first tag",
	//     "SecondField": "second tag",
	// }
	structTags, _ = reflections.Tags(s, "matched")
	fmt.Println(structTags)
}

func ExampleSetField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	// In order to be able to set the structure's values,
	// a pointer to it has to be passed to it.
	err := reflections.SetField(&s, "FirstField", "new value")
	if err != nil {
		log.Fatal(err)
	}

	// If you try to set a field's value using the wrong type,
	// an error will be returned
	err = reflections.SetField(&s, "FirstField", 123) // err != nil
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Fix : unused variables in examples<commit_after>package reflections_test

import (
	"fmt"
	"github.com/oleiade/reflections"
	"log"
	"reflect"
)

type MyStruct struct {
	FirstField  string `matched:"first tag"`
	SecondField int    `matched:"second tag"`
	ThirdField  string `unmatched:"third tag"`
}

func ExampleGetField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	fieldsToExtract := []string{"FirstField", "ThirdField"}

	for _, fieldName := range fieldsToExtract {
		value, err := reflections.GetField(s, fieldName)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(value)
	}
}

func ExampleGetFieldKind() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var firstFieldKind reflect.Kind
	var secondFieldKind reflect.Kind
	var err error

	// GetFieldKind will return reflect.String
	firstFieldKind, err = reflections.GetFieldKind(s, "FirstField")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(firstFieldKind)

	// GetFieldKind will return reflect.Int
	secondFieldKind, err = reflections.GetFieldKind(s, "SecondField")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(secondFieldKind)
}

func ExampleHasField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	// has == true
	has, _ := reflections.HasField(s, "FirstField")
	fmt.Println(has)

	// has == false
	has, _ = reflections.HasField(s, "FourthField")
	fmt.Println(has)
}

func ExampleFields() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var fields []string

	// Fields will list every structure exportable fields.
	// Here, it's content would be equal to:
	// []string{"FirstField", "SecondField", "ThirdField"}
	fields, _ = reflections.Fields(s)
	fmt.Println(fields)
}

func ExampleItems() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var structItems map[string]interface{}

	// Items will return a field name to
	// field value map
	structItems, _ = reflections.Items(s)
	fmt.Println(structItems)
}

func ExampleTags() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var structTags map[string]string

	// Tags will return a field name to tag content
	// map. Nota that only field with the tag name
	// you've provided which will be matched.
	// Here structTags will contain:
	// {
	//     "FirstField": "first tag",
	//     "SecondField": "second tag",
	// }
	structTags, _ = reflections.Tags(s, "matched")
	fmt.Println(structTags)
}

func ExampleSetField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	// In order to be able to set the structure's values,
	// a pointer to it has to be passed to it.
	err := reflections.SetField(&s, "FirstField", "new value")
	if err != nil {
		log.Fatal(err)
	}

	// If you try to set a field's value using the wrong type,
	// an error will be returned
	err = reflections.SetField(&s, "FirstField", 123) // err != nil
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package patreon

import (
	"fmt"
	"os"

	"golang.org/x/oauth2"
)

var testAccessToken = os.Getenv("PATREON_ACCESS_TOKEN")

// Fetches the list of pledges with corresponding users.
// This example is a port of PHP version https://github.com/Patreon/patreon-php/blob/master/examples/patron-list.php
func Example_fetchPatronsAndPledges() {
	ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: testAccessToken})
	tc := oauth2.NewClient(oauth2.NoContext, ts)

	// Create client with static access token
	client := NewClient(tc)

	// Get your campaign data
	campaignResponse, err := client.FetchCampaign()
	if err != nil {
		return
	}

	campaignId := campaignResponse.Data[0].Id

	cursor := ""
	page := 1

	for {
		pledgesResponse, err := client.FetchPledges(campaignId,
			WithPageSize(25),
			WithCursor(cursor))

		if err != nil {
			panic(err)
			return
		}

		// Get all the users in an easy-to-lookup way
		users := make(map[string]*User)
		for _, item := range pledgesResponse.Included.Items {
			u, ok := item.(*User)
			if !ok {
				continue
			}

			users[u.Id] = u
		}

		fmt.Printf("Page %d\r\n", page)

		// Loop over the pledges to get e.g. their amount and user name
		for _, pledge := range pledgesResponse.Data {
			amount := pledge.Attributes.AmountCents
			patronId := pledge.Relationships.Patron.Data.Id
			patronFullName := users[patronId].Attributes.FullName

			fmt.Printf("%s is pledging %d cents\r\n", patronFullName, amount)
		}

		// Get the link to the next page of pledges
		nextLink := pledgesResponse.Links.Next
		if nextLink == "" {
			break
		}

		cursor = nextLink
		page++
	}

	fmt.Print("Done!")
}
<commit_msg>Add refresh token example<commit_after>package patreon

import (
	"context"
	"fmt"
	"os"
	"time"

	"golang.org/x/oauth2"
)

var testAccessToken = os.Getenv("PATREON_ACCESS_TOKEN")

// Fetches the list of pledges with corresponding users.
// This example is a port of PHP version https://github.com/Patreon/patreon-php/blob/master/examples/patron-list.php
func Example_fetchPatronsAndPledges() {
	ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: testAccessToken})
	tc := oauth2.NewClient(oauth2.NoContext, ts)

	// Create client with static access token
	client := NewClient(tc)

	// Get your campaign data
	campaignResponse, err := client.FetchCampaign()
	if err != nil {
		return
	}

	campaignId := campaignResponse.Data[0].Id

	cursor := ""
	page := 1

	for {
		pledgesResponse, err := client.FetchPledges(campaignId,
			WithPageSize(25),
			WithCursor(cursor))

		if err != nil {
			panic(err)
			return
		}

		// Get all the users in an easy-to-lookup way
		users := make(map[string]*User)
		for _, item := range pledgesResponse.Included.Items {
			u, ok := item.(*User)
			if !ok {
				continue
			}

			users[u.Id] = u
		}

		fmt.Printf("Page %d\r\n", page)

		// Loop over the pledges to get e.g. their amount and user name
		for _, pledge := range pledgesResponse.Data {
			amount := pledge.Attributes.AmountCents
			patronId := pledge.Relationships.Patron.Data.Id
			patronFullName := users[patronId].Attributes.FullName

			fmt.Printf("%s is pledging %d cents\r\n", patronFullName, amount)
		}

		// Get the link to the next page of pledges
		nextLink := pledgesResponse.Links.Next
		if nextLink == "" {
			break
		}

		cursor = nextLink
		page++
	}

	fmt.Print("Done!")
}

// Automatically refresh token
func Example_refreshToken() {
	config := oauth2.Config{
		ClientID:     "<client_id>",
		ClientSecret: "<client_secret>",
		Endpoint: oauth2.Endpoint{
			AuthURL:  AuthorizationURL,
			TokenURL: AccessTokenURL,
		},
		Scopes: []string{"users", "pledges-to-me", "my-campaign"},
	}

	token := oauth2.Token{
		RefreshToken: "<current_refresh_token>",
		// Must be non-nil, otherwise token will not be expired
		Expiry: time.Now().Add(-24 * time.Hour),
	}

	tc := config.Client(context.Background(), &token)

	client := NewClient(tc)
	_, err := client.FetchUser()
	if err != nil {
		panic(err)
	}

	print("OK")
}
<|endoftext|>