<commit_before>// Copyright 2015 Apcera Inc. All rights reserved.

package server

import (
	"fmt"
	"os"
	"os/exec"
	"testing"
)

func TestPSEmulation(t *testing.T) {
	var rss, vss, psRss, psVss int64
	var pcpu, psPcpu float64

	// PS version first
	pidStr := fmt.Sprintf("%d", os.Getpid())
	out, err := exec.Command("ps", "o", "pcpu=,rss=,vsz=", "-p", pidStr).Output()
	if err != nil {
		t.Fatalf("Failed to execute ps command: %v\n", err)
	}

	fmt.Sscanf(string(out), "%f %d %d", &psPcpu, &psRss, &psVss)
	psRss *= 1024 // 1k blocks, want bytes.
	psVss *= 1024 // 1k blocks, want bytes.

	// Our internal version
	procUsage(&pcpu, &rss, &vss)

	if pcpu != psPcpu {
		delta := int64(pcpu - psPcpu)
		if delta < 0 {
			delta = -delta
		}
		if delta > 5 { // 5%
			t.Fatalf("CPUs did not match close enough: %f vs %f", pcpu, psPcpu)
		}
	}
	if rss != psRss {
		delta := rss - psRss
		if delta < 0 {
			delta = -delta
		}
		t.Logf("delta is %d\n", delta)
		if delta > 200*1024 { // 200k
			t.Fatalf("RSSs did not match close enough: %d vs %d", rss, psRss)
		}
	}
}
<commit_msg>more tolerance for cpu drift during test<commit_after>// Copyright 2015 Apcera Inc. All rights reserved.

package server

import (
	"fmt"
	"os"
	"os/exec"
	"testing"
)

func TestPSEmulation(t *testing.T) {
	var rss, vss, psRss, psVss int64
	var pcpu, psPcpu float64

	// PS version first
	pidStr := fmt.Sprintf("%d", os.Getpid())
	out, err := exec.Command("ps", "o", "pcpu=,rss=,vsz=", "-p", pidStr).Output()
	if err != nil {
		t.Fatalf("Failed to execute ps command: %v\n", err)
	}

	fmt.Sscanf(string(out), "%f %d %d", &psPcpu, &psRss, &psVss)
	psRss *= 1024 // 1k blocks, want bytes.
	psVss *= 1024 // 1k blocks, want bytes.

	// Our internal version
	procUsage(&pcpu, &rss, &vss)

	if pcpu != psPcpu {
		delta := int64(pcpu - psPcpu)
		if delta < 0 {
			delta = -delta
		}
		if delta > 10 { // 10%
			t.Fatalf("CPUs did not match close enough: %f vs %f", pcpu, psPcpu)
		}
	}
	if rss != psRss {
		delta := rss - psRss
		if delta < 0 {
			delta = -delta
		}
		t.Logf("delta is %d\n", delta)
		if delta > 200*1024 { // 200k
			t.Fatalf("RSSs did not match close enough: %d vs %d", rss, psRss)
		}
	}
}
<|endoftext|>


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

package dig

import (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"strconv"
)

const (
	_optionalTag = "optional"
	_nameTag     = "name"
)

// Unique identification of an object in the graph.
type key struct {
	t    reflect.Type
	name string
}

// A Container is a directed, acyclic graph of dependencies. Dependencies are
// constructed on-demand and returned from a cache thereafter, so they're
// effectively singletons.
type Container struct {
	nodes map[key]*node
	cache map[key]reflect.Value
	// TODO: for advanced use-case, add an index
	// This will allow retrieval of a single type, without specifying the exact
	// tag, provided there is only one object of that given type
	//
	// It will also allow library owners to create a "default" tag for their
	// object, in case users want to provide another type with a different name
	//
	// index map[reflect.Type]key
}

// New constructs a ready-to-use Container.
func New() *Container {
	return &Container{
		nodes: make(map[key]*node),
		cache: make(map[key]reflect.Value),
	}
}

// Provide teaches the Container how to construct one or more new types. It
// accepts either a constructor function or an already-constructed object.
//
// Any function passed to Provide is assumed to be a constructor. Constructors
// can take any number of parameters, which will be supplied by the Container
// on demand. They must return at least one non-error value, all of which are
// then available in the Container. If the last returned value is an error, the
// Container inspects it to determine whether the constructor succeeded or
// failed. Regardless of position, returned errors are never put into the
// Container's dependency graph.
//
// All non-functions (including structs, pointers, Go's built-in collections,
// and primitive types like ints) are inserted into the Container as-is.
func (c *Container) Provide(constructor interface{}) error {
	ctype := reflect.TypeOf(constructor)
	if ctype == nil {
		return errors.New("can't provide an untyped nil")
	}
	if ctype.Kind() != reflect.Func {
		return fmt.Errorf("must provide constructor function, got %v (type %v)", constructor, ctype)
	}
	if err := c.provide(constructor, ctype); err != nil {
		return fmt.Errorf("can't provide %v: %v", ctype, err)
	}
	return nil
}

// Invoke runs a function, supplying its arguments from the Container. If the
// function's last return value is an error, that error is propagated to the
// caller. All other returned values (if any) are ignored.
//
// Passing anything other than a function to Invoke returns an error
// immediately.
func (c *Container) Invoke(function interface{}) error {
	ftype := reflect.TypeOf(function)
	if ftype == nil {
		return errors.New("can't invoke an untyped nil")
	}
	if ftype.Kind() != reflect.Func {
		return fmt.Errorf("can't invoke non-function %v (type %v)", function, ftype)
	}
	args, err := c.constructorArgs(ftype)
	if err != nil {
		return fmt.Errorf("failed to get arguments for %v (type %v): %v", function, ftype, err)
	}
	returned := reflect.ValueOf(function).Call(args)
	if len(returned) == 0 {
		return nil
	}
	if last := returned[len(returned)-1]; isError(last.Type()) {
		if err, _ := last.Interface().(error); err != nil {
			return err
		}
	}
	return nil
}

func (c *Container) provide(ctor interface{}, ctype reflect.Type) error {
	keys, err := c.getReturnKeys(ctor, ctype)
	if err != nil {
		return fmt.Errorf("unable to collect return types of a constructor: %v", err)
	}

	nodes := make([]*node, 0, len(keys))
	for k := range keys {
		n, err := newNode(k, ctor, ctype)
		if err != nil {
			return err
		}
		nodes = append(nodes, n)
		c.nodes[k] = n
	}

	for _, n := range nodes {
		if err := c.isAcyclic(n); err != nil {
			c.remove(nodes)
			return fmt.Errorf("introduces a cycle: %v", err)
		}
	}

	return nil
}

// Get the return types of a constructor with all the dig.Out returns get expanded.
func (c *Container) getReturnKeys(
	ctor interface{},
	ctype reflect.Type,
) (map[key]struct{}, error) {
	// Could pre-compute the size but it's tricky as counter is different
	// when dig.Out objects are mixed in
	returnTypes := make(map[key]struct{})

	// Check each return object
	for i := 0; i < ctype.NumOut(); i++ {
		outt := ctype.Out(i)

		err := traverseOutTypes(key{t: outt}, func(k key) error {
			if isError(k.t) {
				// Don't register errors into the container.
				return nil
			}

			// Tons of error checking
			if isInObject(k.t) {
				return errors.New("can't provide parameter objects")
			}
			if _, ok := returnTypes[k]; ok {
				return fmt.Errorf("returns multiple %v", k)
			}
			if _, ok := c.nodes[k]; ok {
				return fmt.Errorf("provides %v, which is already in the container", k)
			}

			returnTypes[k] = struct{}{}
			return nil
		})
		if err != nil {
			return returnTypes, err
		}
	}
	if len(returnTypes) == 0 {
		return nil, errors.New("must provide at least one non-error type")
	}

	return returnTypes, nil
}

// DFS traverse over all the types and execute the provided function.
// Types that embed dig.Out get recursed on. Returns the first error encountered.
func traverseOutTypes(k key, f func(key) error) error {
	if !isOutObject(k.t) {
		// call the provided function on non-Out type
		if err := f(k); err != nil {
			return err
		}
		return nil
	}

	for i := 0; i < k.t.NumField(); i++ {
		field := k.t.Field(i)
		ft := field.Type

		if field.PkgPath != "" {
			continue // skip private fields
		}

		// keep recursing to traverse all the embedded objects
		if err := traverseOutTypes(key{t: ft, name: field.Tag.Get(_nameTag)}, f); err != nil {
			return err
		}
	}
	return nil
}

func (c *Container) isAcyclic(n *node) error {
	return detectCycles(n, c.nodes, nil)
}

// Retrieve a type from the container
func (c *Container) get(e edge) (reflect.Value, error) {
	if v, ok := c.cache[e.key]; ok {
		return v, nil
	}

	if isInObject(e.t) {
		// We do not want parameter objects to be cached.
		return c.createInObject(e.t)
	}

	n, ok := c.nodes[e.key]
	if !ok {
		if e.optional {
			return reflect.Zero(e.t), nil
		}
		return _noValue, fmt.Errorf("type %v isn't in the container", e.key)
	}

	if err := c.contains(n.deps); err != nil {
		if e.optional {
			return reflect.Zero(e.t), nil
		}
		return _noValue, fmt.Errorf("missing dependencies for %v: %v", e.key, err)
	}

	args, err := c.constructorArgs(n.ctype)
	if err != nil {
		return _noValue, fmt.Errorf("couldn't get arguments for constructor %v: %v", n.ctype, err)
	}
	constructed := reflect.ValueOf(n.ctor).Call(args)

	// Provide-time validation ensures that all constructors return at least
	// one value.
	if err := constructed[len(constructed)-1]; isError(err.Type()) && err.Interface() != nil {
		return _noValue, fmt.Errorf(
			"constructor %v for type %v failed: %v", n.ctype, e.t, err.Interface())
	}

	for _, con := range constructed {
		// Set the resolved object into the cache.
		// This might look confusing at first like we're ignoring named types,
		// but `con` in this case will be the dig.Out object, which will
		// cause a recursion into the .set for each of it's memebers.
		c.set(key{t: con.Type()}, con)
	}
	return c.cache[e.key], nil
}

// Returns a new In parent object with all the dependency fields
// populated from the dig container.
func (c *Container) createInObject(t reflect.Type) (reflect.Value, error) {
	dest := reflect.New(t).Elem()
	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		if f.PkgPath != "" {
			continue // skip private fields
		}

		isOptional, err := isFieldOptional(t, f)
		if err != nil {
			return dest, err
		}

		e := edge{key: key{t: f.Type, name: f.Tag.Get(_nameTag)}, optional: isOptional}
		v, err := c.get(e)
		if err != nil {
			return dest, fmt.Errorf("could not get field %v (edge %v) of %v: %v", f.Name, e, t, err)
		}
		dest.Field(i).Set(v)
	}
	return dest, nil
}

// Set the value in the cache after a node resolution
func (c *Container) set(k key, v reflect.Value) {
	if !isOutObject(k.t) {
		// do not cache error types
		if k.t != _errType {
			c.cache[k] = v
		}
		return
	}

	// dig.Out objects are not acted upon directly, but rather their members are considered
	for i := 0; i < k.t.NumField(); i++ {
		f := k.t.Field(i)

		// recurse into all fields, which may or may not be more dig.Out objects
		fk := key{t: f.Type, name: f.Tag.Get(_nameTag)}
		c.set(fk, v.Field(i))
	}
}

func (c *Container) contains(deps []edge) error {
	var missing []key
	for _, d := range deps {
		if _, ok := c.nodes[d.key]; !ok && !d.optional {
			missing = append(missing, d.key)
		}
	}
	if len(missing) > 0 {
		return fmt.Errorf("container is missing: %v", missing)
	}
	return nil
}

func (c *Container) remove(nodes []*node) {
	for _, n := range nodes {
		delete(c.nodes, n.key)
	}
}

func (c *Container) constructorArgs(ctype reflect.Type) ([]reflect.Value, error) {
	args := make([]reflect.Value, 0, ctype.NumIn())
	for i := 0; i < ctype.NumIn(); i++ {
		arg, err := c.get(edge{key: key{t: ctype.In(i)}})
		if err != nil {
			return nil, fmt.Errorf("couldn't get arguments for constructor %v: %v", ctype, err)
		}
		args = append(args, arg)
	}
	return args, nil
}

type node struct {
	key

	ctor  interface{}
	ctype reflect.Type
	deps  []edge
}

type edge struct {
	key

	optional bool
}

func newNode(k key, ctor interface{}, ctype reflect.Type) (*node, error) {
	deps, err := getConstructorDependencies(ctype)
	return &node{
		key:   k,
		ctor:  ctor,
		ctype: ctype,
		deps:  deps,
	}, err
}

// Retrieves the dependencies for a constructor
func getConstructorDependencies(ctype reflect.Type) ([]edge, error) {
	var deps []edge
	for i := 0; i < ctype.NumIn(); i++ {
		err := traverseInTypes(ctype.In(i), func(e edge) {
			deps = append(deps, e)
		})
		if err != nil {
			return nil, err
		}
	}
	return deps, nil
}

func cycleError(cycle []key, last key) error {
	b := &bytes.Buffer{}
	for _, k := range cycle {
		fmt.Fprintf(b, "%v ->", k.t)
	}
	fmt.Fprintf(b, "%v", last.t)
	return errors.New(b.String())
}

func detectCycles(n *node, graph map[key]*node, path []key) error {
	for _, p := range path {
		if p == n.key {
			return cycleError(path, n.key)
		}
	}
	path = append(path, n.key)
	for _, dep := range n.deps {
		depNode, ok := graph[dep.key]
		if !ok {
			continue
		}
		if err := detectCycles(depNode, graph, path); err != nil {
			return err
		}
	}
	return nil
}

// Traverse all fields starting with the given type.
// Types that dig.In get recursed on. Returns the first error encountered.
func traverseInTypes(t reflect.Type, fn func(edge)) error {
	if !isInObject(t) {
		fn(edge{key: key{t: t}})
		return nil
	}

	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		if f.PkgPath != "" {
			continue // skip private fields
		}

		if isInObject(f.Type) {
			if err := traverseInTypes(f.Type, fn); err != nil {
				return err
			}
			continue
		}

		optional, err := isFieldOptional(t, f)
		if err != nil {
			return err
		}

		fn(edge{key: key{t: f.Type, name: f.Tag.Get(_nameTag)}, optional: optional})
	}

	return nil
}

// Checks if a field of an In struct is optional.
func isFieldOptional(parent reflect.Type, f reflect.StructField) (bool, error) {
	tag := f.Tag.Get(_optionalTag)
	if tag == "" {
		return false, nil
	}

	optional, err := strconv.ParseBool(tag)
	if err != nil {
		err = fmt.Errorf(
			"invalid value %q for %q tag on field %v of %v: %v",
			tag, _optionalTag, f.Name, parent, err)
	}

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

package dig

import (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"strconv"
)

const (
	_optionalTag = "optional"
	_nameTag     = "name"
)

// Unique identification of an object in the graph.
type key struct {
	t    reflect.Type
	name string
}

// A Container is a directed, acyclic graph of dependencies. Dependencies are
// constructed on-demand and returned from a cache thereafter, so they're
// effectively singletons.
type Container struct {
	nodes map[key]*node
	cache map[key]reflect.Value
	// TODO: for advanced use-case, add an index
	// This will allow retrieval of a single type, without specifying the exact
	// tag, provided there is only one object of that given type
	//
	// It will also allow library owners to create a "default" tag for their
	// object, in case users want to provide another type with a different name
	//
	// index map[reflect.Type]key
}

// New constructs a ready-to-use Container.
func New() *Container {
	return &Container{
		nodes: make(map[key]*node),
		cache: make(map[key]reflect.Value),
	}
}

// Provide teaches the Container how to construct one or more new types.
//
// Any function passed to Provide is assumed to be a constructor. Constructors
// can take any number of parameters, which will be supplied by the Container
// on demand. They must return at least one non-error value, all of which are
// then available in the Container. If the last returned value is an error, the
// Container inspects it to determine whether the constructor succeeded or
// failed. Regardless of position, returned errors are never put into the
// Container's dependency graph.
//
// All non-functions (including structs, pointers, Go's built-in collections,
// and primitive types like ints) are inserted into the Container as-is.
func (c *Container) Provide(constructor interface{}) error {
	ctype := reflect.TypeOf(constructor)
	if ctype == nil {
		return errors.New("can't provide an untyped nil")
	}
	if ctype.Kind() != reflect.Func {
		return fmt.Errorf("must provide constructor function, got %v (type %v)", constructor, ctype)
	}
	if err := c.provide(constructor, ctype); err != nil {
		return fmt.Errorf("can't provide %v: %v", ctype, err)
	}
	return nil
}

// Invoke runs a function, supplying its arguments from the Container. If the
// function's last return value is an error, that error is propagated to the
// caller. All other returned values (if any) are ignored.
//
// Passing anything other than a function to Invoke returns an error
// immediately.
func (c *Container) Invoke(function interface{}) error {
	ftype := reflect.TypeOf(function)
	if ftype == nil {
		return errors.New("can't invoke an untyped nil")
	}
	if ftype.Kind() != reflect.Func {
		return fmt.Errorf("can't invoke non-function %v (type %v)", function, ftype)
	}
	args, err := c.constructorArgs(ftype)
	if err != nil {
		return fmt.Errorf("failed to get arguments for %v (type %v): %v", function, ftype, err)
	}
	returned := reflect.ValueOf(function).Call(args)
	if len(returned) == 0 {
		return nil
	}
	if last := returned[len(returned)-1]; isError(last.Type()) {
		if err, _ := last.Interface().(error); err != nil {
			return err
		}
	}
	return nil
}

func (c *Container) provide(ctor interface{}, ctype reflect.Type) error {
	keys, err := c.getReturnKeys(ctor, ctype)
	if err != nil {
		return fmt.Errorf("unable to collect return types of a constructor: %v", err)
	}

	nodes := make([]*node, 0, len(keys))
	for k := range keys {
		n, err := newNode(k, ctor, ctype)
		if err != nil {
			return err
		}
		nodes = append(nodes, n)
		c.nodes[k] = n
	}

	for _, n := range nodes {
		if err := c.isAcyclic(n); err != nil {
			c.remove(nodes)
			return fmt.Errorf("introduces a cycle: %v", err)
		}
	}

	return nil
}

// Get the return types of a constructor with all the dig.Out returns get expanded.
func (c *Container) getReturnKeys(
	ctor interface{},
	ctype reflect.Type,
) (map[key]struct{}, error) {
	// Could pre-compute the size but it's tricky as counter is different
	// when dig.Out objects are mixed in
	returnTypes := make(map[key]struct{})

	// Check each return object
	for i := 0; i < ctype.NumOut(); i++ {
		outt := ctype.Out(i)

		err := traverseOutTypes(key{t: outt}, func(k key) error {
			if isError(k.t) {
				// Don't register errors into the container.
				return nil
			}

			// Tons of error checking
			if isInObject(k.t) {
				return errors.New("can't provide parameter objects")
			}
			if _, ok := returnTypes[k]; ok {
				return fmt.Errorf("returns multiple %v", k)
			}
			if _, ok := c.nodes[k]; ok {
				return fmt.Errorf("provides %v, which is already in the container", k)
			}

			returnTypes[k] = struct{}{}
			return nil
		})
		if err != nil {
			return returnTypes, err
		}
	}
	if len(returnTypes) == 0 {
		return nil, errors.New("must provide at least one non-error type")
	}

	return returnTypes, nil
}

// DFS traverse over all the types and execute the provided function.
// Types that embed dig.Out get recursed on. Returns the first error encountered.
func traverseOutTypes(k key, f func(key) error) error {
	if !isOutObject(k.t) {
		// call the provided function on non-Out type
		if err := f(k); err != nil {
			return err
		}
		return nil
	}

	for i := 0; i < k.t.NumField(); i++ {
		field := k.t.Field(i)
		ft := field.Type

		if field.PkgPath != "" {
			continue // skip private fields
		}

		// keep recursing to traverse all the embedded objects
		if err := traverseOutTypes(key{t: ft, name: field.Tag.Get(_nameTag)}, f); err != nil {
			return err
		}
	}
	return nil
}

func (c *Container) isAcyclic(n *node) error {
	return detectCycles(n, c.nodes, nil)
}

// Retrieve a type from the container
func (c *Container) get(e edge) (reflect.Value, error) {
	if v, ok := c.cache[e.key]; ok {
		return v, nil
	}

	if isInObject(e.t) {
		// We do not want parameter objects to be cached.
		return c.createInObject(e.t)
	}

	n, ok := c.nodes[e.key]
	if !ok {
		if e.optional {
			return reflect.Zero(e.t), nil
		}
		return _noValue, fmt.Errorf("type %v isn't in the container", e.key)
	}

	if err := c.contains(n.deps); err != nil {
		if e.optional {
			return reflect.Zero(e.t), nil
		}
		return _noValue, fmt.Errorf("missing dependencies for %v: %v", e.key, err)
	}

	args, err := c.constructorArgs(n.ctype)
	if err != nil {
		return _noValue, fmt.Errorf("couldn't get arguments for constructor %v: %v", n.ctype, err)
	}
	constructed := reflect.ValueOf(n.ctor).Call(args)

	// Provide-time validation ensures that all constructors return at least
	// one value.
	if err := constructed[len(constructed)-1]; isError(err.Type()) && err.Interface() != nil {
		return _noValue, fmt.Errorf(
			"constructor %v for type %v failed: %v", n.ctype, e.t, err.Interface())
	}

	for _, con := range constructed {
		// Set the resolved object into the cache.
		// This might look confusing at first like we're ignoring named types,
		// but `con` in this case will be the dig.Out object, which will
		// cause a recursion into the .set for each of it's memebers.
		c.set(key{t: con.Type()}, con)
	}
	return c.cache[e.key], nil
}

// Returns a new In parent object with all the dependency fields
// populated from the dig container.
func (c *Container) createInObject(t reflect.Type) (reflect.Value, error) {
	dest := reflect.New(t).Elem()
	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		if f.PkgPath != "" {
			continue // skip private fields
		}

		isOptional, err := isFieldOptional(t, f)
		if err != nil {
			return dest, err
		}

		e := edge{key: key{t: f.Type, name: f.Tag.Get(_nameTag)}, optional: isOptional}
		v, err := c.get(e)
		if err != nil {
			return dest, fmt.Errorf("could not get field %v (edge %v) of %v: %v", f.Name, e, t, err)
		}
		dest.Field(i).Set(v)
	}
	return dest, nil
}

// Set the value in the cache after a node resolution
func (c *Container) set(k key, v reflect.Value) {
	if !isOutObject(k.t) {
		// do not cache error types
		if k.t != _errType {
			c.cache[k] = v
		}
		return
	}

	// dig.Out objects are not acted upon directly, but rather their members are considered
	for i := 0; i < k.t.NumField(); i++ {
		f := k.t.Field(i)

		// recurse into all fields, which may or may not be more dig.Out objects
		fk := key{t: f.Type, name: f.Tag.Get(_nameTag)}
		c.set(fk, v.Field(i))
	}
}

func (c *Container) contains(deps []edge) error {
	var missing []key
	for _, d := range deps {
		if _, ok := c.nodes[d.key]; !ok && !d.optional {
			missing = append(missing, d.key)
		}
	}
	if len(missing) > 0 {
		return fmt.Errorf("container is missing: %v", missing)
	}
	return nil
}

func (c *Container) remove(nodes []*node) {
	for _, n := range nodes {
		delete(c.nodes, n.key)
	}
}

func (c *Container) constructorArgs(ctype reflect.Type) ([]reflect.Value, error) {
	args := make([]reflect.Value, 0, ctype.NumIn())
	for i := 0; i < ctype.NumIn(); i++ {
		arg, err := c.get(edge{key: key{t: ctype.In(i)}})
		if err != nil {
			return nil, fmt.Errorf("couldn't get arguments for constructor %v: %v", ctype, err)
		}
		args = append(args, arg)
	}
	return args, nil
}

type node struct {
	key

	ctor  interface{}
	ctype reflect.Type
	deps  []edge
}

type edge struct {
	key

	optional bool
}

func newNode(k key, ctor interface{}, ctype reflect.Type) (*node, error) {
	deps, err := getConstructorDependencies(ctype)
	return &node{
		key:   k,
		ctor:  ctor,
		ctype: ctype,
		deps:  deps,
	}, err
}

// Retrieves the dependencies for a constructor
func getConstructorDependencies(ctype reflect.Type) ([]edge, error) {
	var deps []edge
	for i := 0; i < ctype.NumIn(); i++ {
		err := traverseInTypes(ctype.In(i), func(e edge) {
			deps = append(deps, e)
		})
		if err != nil {
			return nil, err
		}
	}
	return deps, nil
}

func cycleError(cycle []key, last key) error {
	b := &bytes.Buffer{}
	for _, k := range cycle {
		fmt.Fprintf(b, "%v ->", k.t)
	}
	fmt.Fprintf(b, "%v", last.t)
	return errors.New(b.String())
}

func detectCycles(n *node, graph map[key]*node, path []key) error {
	for _, p := range path {
		if p == n.key {
			return cycleError(path, n.key)
		}
	}
	path = append(path, n.key)
	for _, dep := range n.deps {
		depNode, ok := graph[dep.key]
		if !ok {
			continue
		}
		if err := detectCycles(depNode, graph, path); err != nil {
			return err
		}
	}
	return nil
}

// Traverse all fields starting with the given type.
// Types that dig.In get recursed on. Returns the first error encountered.
func traverseInTypes(t reflect.Type, fn func(edge)) error {
	if !isInObject(t) {
		fn(edge{key: key{t: t}})
		return nil
	}

	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		if f.PkgPath != "" {
			continue // skip private fields
		}

		if isInObject(f.Type) {
			if err := traverseInTypes(f.Type, fn); err != nil {
				return err
			}
			continue
		}

		optional, err := isFieldOptional(t, f)
		if err != nil {
			return err
		}

		fn(edge{key: key{t: f.Type, name: f.Tag.Get(_nameTag)}, optional: optional})
	}

	return nil
}

// Checks if a field of an In struct is optional.
func isFieldOptional(parent reflect.Type, f reflect.StructField) (bool, error) {
	tag := f.Tag.Get(_optionalTag)
	if tag == "" {
		return false, nil
	}

	optional, err := strconv.ParseBool(tag)
	if err != nil {
		err = fmt.Errorf(
			"invalid value %q for %q tag on field %v of %v: %v",
			tag, _optionalTag, f.Name, parent, err)
	}

	return optional, err
}
<|endoftext|>


<commit_before>package commenttags

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
)

type DirectoryData struct {
	Dirname string
	Files   []FileData
}

func ProcessDirectory(name string, maxSize int64) (*DirectoryData, error) {
	fmt.Println("ProcessDirectory", name)

	data := DirectoryData{}
	data.Dirname = name

	dir, err := ioutil.ReadDir(name)
	if err != nil {
		return &data, err
	}
	if len(dir) != 0 {
		for _, v := range dir {
			// fmt.Printf("Check %s %d %# v\n", name, k, v.Name())
			// check file or folder
			if v.IsDir() {
				// ignore som filders like .git
				if v.Name() != ".git" {
					tmp, _ := ProcessDirectory(name+"/"+v.Name(), maxSize)
					// HACK: exception handler...
					for _, v := range tmp.Files {
						data.Files = append(data.Files, v)
					}
				}
			} else {
				// fmt.Println("Is File...")
				// TODO: check filesize  v.Size() < maxSize
				tmpFiles, errFiles := ProcessFile(name + "/" + v.Name())
				if errFiles != nil {
					fmt.Errorf("ERROR...", errFiles)
				}
				// if tags exist, add to the files array
				if len(tmpFiles.Tags) > 0 {
					data.Files = append(data.Files, *tmpFiles)
				}
			}
		}
	}
	return &data, nil
}

func (d *DirectoryData) PrettyPrint() {
	for _, v := range d.Files {
		v.PrettyPrint()
	}
}

func (d *DirectoryData) SaveJSON(filename string, perm os.FileMode) error {
	data, err := json.Marshal(d)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filename, data, perm)
	return err
}
<commit_msg>Fixed go vet issue<commit_after>package commenttags

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
)

type DirectoryData struct {
	Dirname string
	Files   []FileData
}

func ProcessDirectory(name string, maxSize int64) (*DirectoryData, error) {
	fmt.Println("ProcessDirectory", name)

	data := DirectoryData{}
	data.Dirname = name

	dir, err := ioutil.ReadDir(name)
	if err != nil {
		return &data, err
	}
	if len(dir) != 0 {
		for _, v := range dir {
			// fmt.Printf("Check %s %d %# v\n", name, k, v.Name())
			// check file or folder
			if v.IsDir() {
				// ignore som filders like .git
				if v.Name() != ".git" {
					tmp, _ := ProcessDirectory(name+"/"+v.Name(), maxSize)
					// HACK: exception handler...
					for _, v := range tmp.Files {
						data.Files = append(data.Files, v)
					}
				}
			} else {
				// fmt.Println("Is File...")
				// TODO: check filesize  v.Size() < maxSize
				tmpFiles, errFiles := ProcessFile(name + "/" + v.Name())
				if errFiles != nil {
					return &DirectoryData{}, errFiles
				}
				// if tags exist, add to the files array
				if len(tmpFiles.Tags) > 0 {
					data.Files = append(data.Files, *tmpFiles)
				}
			}
		}
	}
	return &data, nil
}

func (d *DirectoryData) PrettyPrint() {
	for _, v := range d.Files {
		v.PrettyPrint()
	}
}

func (d *DirectoryData) SaveJSON(filename string, perm os.FileMode) error {
	data, err := json.Marshal(d)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filename, data, perm)
	return err
}
<|endoftext|>


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

// Package wav decodes and encodes wav audio files.
//
// The decoder and encoder are both able to manage all wav audio formats, with
// any number of channels (except extensible WAV formats), these formats are:
//
//  8-bit unsigned PCM
//  16-bit signed PCM
//  32-bit signed PCM
//
//  32-bit floating-point PCM
//  64-bit floating-point PCM
//
//  μ-law
//  a-law
//
// Please refer to the WAV specification for in-depth details about its file
// format:
//
//    http://www.sonicspot.com/guide/wavefiles.html
//    https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
//
package wav
<commit_msg>Document what types of audio the encoder supports. Fixes #11<commit_after>// Copyright 2014 The Azul3D Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package wav decodes and encodes wav audio files.
//
// The decoder is able to decode all wav audio formats (except extensible WAV
// formats), with any number of channels. These formats are:
//
//  8-bit unsigned PCM
//  16-bit signed PCM
//  32-bit signed PCM
//
//  32-bit floating-point PCM
//  64-bit floating-point PCM
//
//  μ-law
//  a-law
//
// The encoder is capable of encoding any audio data -- but it currently will
// convert all data to 16-bit signed PCM on-the-fly before writing to a file.
//
// Ultimately this means regardless of what type of audio data you encode, it
// ends up as a 16-bit WAV file in the end. Future versions of this package
// will allow the encoder to output the same types as the decoder.
//
// Please refer to the WAV specification for in-depth details about its file
// format:
//
//    http://www.sonicspot.com/guide/wavefiles.html
//    https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
//
package wav
<|endoftext|>


<commit_before>// The hstspreload package has 4 parts:
//
// - A Go package with functions to check HSTS preload requirements.
//
// - The `hstspreload` command line tool, which can be installed with:
//
//     go get github.com/chromium/hstspreload/cmd/hstspreload
//
// - The `transport_security_state_static_generate.go` script, which can
// be installed with:
//
//     go get github.com/chromium/hstspreload/cmd/transport_security_state_static_generate
//
// - Source code for hstspreload.appspot.com
package hstspreload
<commit_msg>Change the start of the package documentation to the standard format, per `gometalinter`.<commit_after>// Package hstspreload has 4 parts:
//
// - A Go package with functions to check HSTS preload requirements.
//
// - The `hstspreload` command line tool, which can be installed with:
//
//     go get github.com/chromium/hstspreload/cmd/hstspreload
//
// - The `transport_security_state_static_generate.go` script, which can
// be installed with:
//
//     go get github.com/chromium/hstspreload/cmd/transport_security_state_static_generate
//
// - Source code for hstspreload.appspot.com
package hstspreload
<|endoftext|>


<commit_before>/*
Package response is a helper for the Core (https://github.com/volatile/core).
It provides syntactic sugar that lets you easily write responses on the context.

Usage

Example:

	package main

	import (
		"net/http"
		"strings"

		"github.com/volatile/core"
		"github.com/volatile/response"
		"github.com/volatile/route"
	)

	func main() {
		// We set functions for views templates.
		response.ViewsFuncs(response.FuncMap{
			"toUpper": strings.ToUpper,
			"toLower": strings.ToLower,
		})

		// Status response
		route.Get("^/status$", func(c *core.Context) {
			response.Status(c, http.StatusForbidden)
		})

		// String response
		route.Get("^/string$", func(c *core.Context) {
			response.String(c, "Hello, World!")
		})

		// Bytes response
		route.Get("^/bytes$", func(c *core.Context) {
			response.Bytes(c, []byte("Hello, World!"))
		})

		// JSON response
		route.Get("^/json$", func(c *core.Context) {
			response.JSON(c, &Car{
				ID:    1,
				Brand: "Bentley",
				Model: "Continental GT",
			})
		})

		// View response
		route.Get("^/(?P<name>[A-Za-z]+)$", func(c *core.Context, params map[string]string) {
			response.View(c, "hello", params)
		})

		core.Run()
	}

	type Car struct {
		ID    int    `json:"id"`
		Brand string `json:"brand"`
		Model string `json:"model"`
	}

Views

The views templates are recursively parsed from the "views" directory, just before running the server.
The file names and extensions and the directory organization doesn't matter. All the files are parsed.

Built-in functions

This package gives some functions out-of-the-box:

- "html" uses a raw string without escaping it

- "nl2br" replaces "\n" by "
"

Custom functions

To use functions in your views, use ViewsFuncs, like with the `html/template` standard package.
*/
package response
<commit_msg>Update doc<commit_after>/*
Package response is a helper for the Core (https://github.com/volatile/core).
It provides syntactic sugar that lets you easily write responses on the context.

Installation

In the terminal:

	$ go get github.com/volatile/response

Usage

Example:

	package main

	import (
		"net/http"
		"strings"

		"github.com/volatile/core"
		"github.com/volatile/response"
		"github.com/volatile/route"
	)

	func main() {
		// We set functions for views templates.
		response.ViewsFuncs(response.FuncMap{
			"toUpper": strings.ToUpper,
			"toLower": strings.ToLower,
		})

		// Status response
		route.Get("^/status$", func(c *core.Context) {
			response.Status(c, http.StatusForbidden)
		})

		// String response
		route.Get("^/string$", func(c *core.Context) {
			response.String(c, "Hello, World!")
		})

		// Bytes response
		route.Get("^/bytes$", func(c *core.Context) {
			response.Bytes(c, []byte("Hello, World!"))
		})

		// JSON response
		route.Get("^/json$", func(c *core.Context) {
			response.JSON(c, &Car{
				ID:    1,
				Brand: "Bentley",
				Model: "Continental GT",
			})
		})

		// View response
		route.Get("^/(?P<name>[A-Za-z]+)$", func(c *core.Context, params map[string]string) {
			response.View(c, "hello", params)
		})

		core.Run()
	}

	type Car struct {
		ID    int    `json:"id"`
		Brand string `json:"brand"`
		Model string `json:"model"`
	}

Views

The views templates are recursively parsed from the "views" directory, just before running the server.
The file names and extensions and the directory organization doesn't matter. All the files are parsed.

Built-in functions

This package gives some functions out-of-the-box:

- "html" uses a raw string without escaping it

- "nl2br" replaces "\n" by "
"

Custom functions

To use functions in your views, use ViewsFuncs, like with the `html/template` standard package.
*/
package response
<|endoftext|>


<commit_before>// Copyright 2017 The Foo Authors. All rights reserved.

/*
This package was created for fun. The other important reason is testing what
the machinism is of gopkg.

Below is a very simple example for usage:

    f := foo.NewFoo()
    f.Bar()

code above will output some text to the stdout.
/*
package foo // import "gopkg.in/foo.v1"
<commit_msg>:( bad luck<commit_after>// Copyright 2017 The Foo Authors. All rights reserved.

/*
This package was created for fun. The other important reason is testing what
the machinism is of gopkg.

Below is a very simple example for usage:

    f := foo.NewFoo()
    f.Bar()

code above will output some text to the stdout.
*/
package foo // import "gopkg.in/foo.v1"
<|endoftext|>


<commit_before>/*
Example use:

	import (
		"net/url"
	)

	base, err := url.Parse("http://example.com")
	c, err := New(base)

	c.Get(&Params{
		Path: "path/to/resource",
		Headers:
		Query:
		Body:
		unmarshalerMap:
	})

*/
package grestclient
<commit_msg>Alter doc.go slightly<commit_after>/*
Example use:

	import (
		"net/url"
	)

	base, err := url.Parse("http://example.com")
	c, err := New(base)

	var success string
	var otherSuccess string
	var fail string
	c.Get(&Params{
		Path: "path/to/resource",
		Headers: http.Header{"One-Off": []string{"one"}},
		Query: url.Values{"testquery": []string{"test-override"}},
		Body:         "hello",
		UnmarshalMap: UnmarshalMap{
			200: &success,
			201: &otherSuccess,
			202: &otherSuccess,
			400: &fail,
			404: &fail,
		},
	})

*/
package grestclient
<|endoftext|>


<commit_before>/*
Call a golang web application from node-webkit to get a native looking application.

Instructions

Go get golang-nw:

    go get github.com/lonnc/golang-nw/cmd/golang-nw-pkg

Create an app:

See https://github.com/lonnc/golang-nw/blob/master/cmd/example/main.go
	package main

	import (
		"fmt"
		"github.com/lonnc/golang-nw"
		"net/http"
	)

	func main() {
		// Setup our handler
		http.HandleFunc("/", hello)

		// Create a link back to node-webkit using the environment variable
		// populated by golang-nw's node-webkit code
		nodeWebkit, err := nw.New()
		if err != nil {
			panic(err)
		}

		// Pick a random localhost port, start listening for http requests using default handler
		// and send a message back to node-webkit to redirect
		if err := nodeWebkit.ListenAndServe(nil); err != nil {
			panic(err)
		}
	}

	func hello(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello from golang.")
	}

Build your app:

    go install .\src\github.com\lonnc\golang-nw\cmd\example

Wrap it in node-webkit:

    .\bin\golang-nw-pkg.exe -app=.\bin\example.exe -name="My Application" -bin="myapp.exe" -toolbar=false

    Building:        myapp.exe.nw
    Downloading:     https://s3.amazonaws.com/node-webkit/v0.8.4/node-webkit-v0.8.4-win-ia32.zip
    Packaging:       myapp.exe

You are now good to go:

    .\myapp.exe

You may want to create your own build script so you can control window dimensions etc.
See http://godoc.org/github.com/lonnc/golang-nw/build and
https://github.com/lonnc/golang-nw/blob/master/cmd/golang-nw-pkg/pkg.go

Command line options:

    $ ./bin/golang-nw-pkg -h
    Usage of ./bin/golang-nw-pkg:
      -app="myapp": Web application to be wrapped by node-webkit.
      -arch="amd64": Target arch [386|amd64].
      -bin="myapp": Destination file for combined application and node-webkit .nw file (will be placed in binDir directory).
      -binDir=".": Destination directory for bin and dependencies.
      -cacheDir=".": Directory to cache node-webkit download.
      -includesDir="": Directory containing additional files to bundle with the .nw file
      -name="My Application": Application name.
      -os="linux": Target os [linux|windows|darwin].
      -toolbar=true: Enable toolbar.
      -version="v0.9.2": node-webkit version.

Known issues:

1) libudev.so.0 - On ubuntu >=13.10 (and similar) libudev.so.0 has been removed.
tl;dr:

    $ ./bin/golang-nw-pkg -app=./bin/example -name="My Application" -bin="myapp" -toolbar=false
    $ sed -i -e 's/udev\.so\.0/udev.so.1/g' myapp

Node-webkit has various work arounds described at https://github.com/rogerwang/node-webkit/wiki/The-solution-of-lacking-libudev.so.0

2) Download of node-webkit appears to stall - It's a ~43MB download and can take longer than expected (it could do with some feedback).

*/
package nw
<commit_msg>Update golang-nw-pkg cli options.<commit_after>/*
Call a golang web application from node-webkit to get a native looking application.

Instructions

Go get golang-nw:

    go get github.com/lonnc/golang-nw/cmd/golang-nw-pkg

Create an app:

See https://github.com/lonnc/golang-nw/blob/master/cmd/example/main.go
	package main

	import (
		"fmt"
		"github.com/lonnc/golang-nw"
		"net/http"
	)

	func main() {
		// Setup our handler
		http.HandleFunc("/", hello)

		// Create a link back to node-webkit using the environment variable
		// populated by golang-nw's node-webkit code
		nodeWebkit, err := nw.New()
		if err != nil {
			panic(err)
		}

		// Pick a random localhost port, start listening for http requests using default handler
		// and send a message back to node-webkit to redirect
		if err := nodeWebkit.ListenAndServe(nil); err != nil {
			panic(err)
		}
	}

	func hello(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello from golang.")
	}

Build your app:

    go install .\src\github.com\lonnc\golang-nw\cmd\example

Wrap it in node-webkit:

    .\bin\golang-nw-pkg.exe -app=.\bin\example.exe -name="My Application" -bin="myapp.exe" -toolbar=false

    Building:        myapp.exe.nw
    Downloading:     https://s3.amazonaws.com/node-webkit/v0.8.4/node-webkit-v0.8.4-win-ia32.zip
    Packaging:       myapp.exe

You are now good to go:

    .\myapp.exe

You may want to create your own build script so you can control window dimensions etc.
See http://godoc.org/github.com/lonnc/golang-nw/build and
https://github.com/lonnc/golang-nw/blob/master/cmd/golang-nw-pkg/pkg.go

Command line options:

    $ ./bin/golang-nw-pkg -h
    Usage of ./bin/golang-nw-pkg:
      -app="myapp": Web application to be wrapped by node-webkit.
      -arch="amd64": Target arch [386|amd64].
      -bin="myapp": Destination file for combined application and node-webkit .nw file (will be placed in binDir directory).
      -binDir=".": Destination directory for bin and dependencies.
      -cacheDir=".": Directory to cache node-webkit download.
      -frame=true: Set to false to make window frameless.
      -fullscreen=false: Enable fullscreen mode.
      -includesDir="": Directory containing additional files to bundle with the .nw file
      -name="My Application": Application name.
      -os="linux": Target os [linux|windows|darwin].
      -toolbar=true: Enable toolbar.
      -version="v0.9.2": node-webkit version.

Known issues:

1) libudev.so.0 - On ubuntu >=13.10 (and similar) libudev.so.0 has been removed.
tl;dr:

    $ ./bin/golang-nw-pkg -app=./bin/example -name="My Application" -bin="myapp" -toolbar=false
    $ sed -i -e 's/udev\.so\.0/udev.so.1/g' myapp

Node-webkit has various work arounds described at https://github.com/rogerwang/node-webkit/wiki/The-solution-of-lacking-libudev.so.0

2) Download of node-webkit appears to stall - It's a ~43MB download and can take longer than expected (it could do with some feedback).

*/
package nw
<|endoftext|>


<commit_before>package tocenize

import (
	"fmt"
	"io/ioutil"
	"log"
	"regexp"
	"strings"

	"github.com/kylelemons/godebug/diff"
)

var Verbose = false

type Job struct {
	MinDepth int
	MaxDepth int
	Diff     bool
	Print    bool
	Update   bool
}

type Document struct {
	Path  string
	Lines []string
	eol   string
}

func NewDocument(path string) (Document, error) {
	doc := Document{
		Path: path,
	}
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return doc, err
	}
	doc.Lines, doc.eol = lines(string(b))
	return doc, nil
}

func lines(s string) (lines []string, eol string) {
	lines = strings.Split(s, "\n")
	eol = "\n"
	for _, l := range lines {
		if len(l) > 0 && l[len(l)-1] == '\r' {
			eol = "\r\n"
			l = strings.TrimRight(l, "\r")
		}
	}
	return
}

func (d Document) String() string {
	return strings.Join(d.Lines, d.eol)
}

func (d Document) Update(toc TOC, job Job) error {
	s, e := d.FindTOC()
	if s == -1 {
		s, e = d.SuggestTOC(toc)
	}
	nd := Document{Path: d.Path, eol: d.eol}
	if s > -1 && e > -1 {
		nd.Lines = make([]string, s)
		copy(nd.Lines, d.Lines[:s])
		for _, tocLine := range toc.Headings {
			nd.Lines = append(nd.Lines, tocLine.string(toc.MinDepth()))
		}
		nd.Lines = append(nd.Lines, d.Lines[e:]...)
	}
	if job.Diff {
		if Verbose {
			log.Println("Diff -old +new")
			fmt.Println()
		}
		fmt.Println(diff.Diff(d.String(), nd.String()))
		return nil
	}
	if job.Print {
		if Verbose {
			log.Println("printing full result")
			fmt.Println()
		}
		fmt.Println(nd.String())
		return nil
	}
	if job.Update {
		if Verbose {
			log.Println("updating file")
		}
		err := ioutil.WriteFile(d.Path, []byte(nd.String()), 0644)
		return err
	}
	return nil
}

// SuggestTOC looks for the first heading below a root heading.
// A root heading has minimum depth and the depth must only be used once.
// e.g.
//
// 	# Name
// 	--here--
// 	## A
// 	## B
func (d Document) SuggestTOC(toc TOC) (start, end int) {
	minCount := 0
	for _, tocLine := range toc.Headings {
		if tocLine.Depth == toc.MinDepth() {
			minCount++
			if minCount > 1 {
				// too many root headings
				break
			}
		}
		if tocLine.Depth > toc.MinDepth() {
			if minCount == 1 {
				if Verbose {
					log.Printf("found end of root paragraph on line %d for new TOC", tocLine.Index+1)
				}
				return tocLine.Index, tocLine.Index
			}
			// ## appears before # which is odd
			break
		}
	}
	// in doubt, insert at top
	if Verbose {
		log.Println("chose first line for new TOC (unable to find root paragraph or existing TOC)")
	}
	return 0, 0
}

func (d Document) FindTOC() (start, end int) {
	start = -1
	end = -1
	curStart := -1
	curEnd := -1
	isToc := false
	for i, l := range d.Lines {
		if reIsTOCLine.MatchString(l) {
			if !isToc {
				curStart = i
				isToc = true
			}
			curEnd = i + 1
			continue
		}
		if isToc {
			isToc = false
			if curEnd-curStart > end-start {
				start = curStart
				end = curEnd
			}
		}
	}
	if start > -1 && Verbose {
		log.Printf("found existing TOC on lines %d-%d", start+1, end+1)
	}
	return start, end
}

var reIsTOCLine = regexp.MustCompile(`^\s*- \[.*\]\(#.*\)\s*$`)
<commit_msg>Fall back to line before first significant heading<commit_after>package tocenize

import (
	"fmt"
	"io/ioutil"
	"log"
	"regexp"
	"strings"

	"github.com/kylelemons/godebug/diff"
)

var Verbose = false

type Job struct {
	MinDepth int
	MaxDepth int
	Diff     bool
	Print    bool
	Update   bool
}

type Document struct {
	Path  string
	Lines []string
	eol   string
}

func NewDocument(path string) (Document, error) {
	doc := Document{
		Path: path,
	}
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return doc, err
	}
	doc.Lines, doc.eol = lines(string(b))
	return doc, nil
}

func lines(s string) (lines []string, eol string) {
	lines = strings.Split(s, "\n")
	eol = "\n"
	for _, l := range lines {
		if len(l) > 0 && l[len(l)-1] == '\r' {
			eol = "\r\n"
			l = strings.TrimRight(l, "\r")
		}
	}
	return
}

func (d Document) String() string {
	return strings.Join(d.Lines, d.eol)
}

func (d Document) Update(toc TOC, job Job) error {
	s, e := d.FindTOC()
	if s == -1 {
		s, e = d.SuggestTOC(toc)
	}
	nd := Document{Path: d.Path, eol: d.eol}
	if s > -1 && e > -1 {
		nd.Lines = make([]string, s)
		copy(nd.Lines, d.Lines[:s])
		for _, tocLine := range toc.Headings {
			nd.Lines = append(nd.Lines, tocLine.string(toc.MinDepth()))
		}
		nd.Lines = append(nd.Lines, d.Lines[e:]...)
	}
	if job.Diff {
		if Verbose {
			log.Println("Diff -old +new")
			fmt.Println()
		}
		fmt.Println(diff.Diff(d.String(), nd.String()))
		return nil
	}
	if job.Print {
		if Verbose {
			log.Println("printing full result")
			fmt.Println()
		}
		fmt.Println(nd.String())
		return nil
	}
	if job.Update {
		if Verbose {
			log.Println("updating file")
		}
		err := ioutil.WriteFile(d.Path, []byte(nd.String()), 0644)
		return err
	}
	return nil
}

// SuggestTOC looks for the first heading below a root heading.
// A root heading has minimum depth and the depth must only be used once.
// e.g.
//
// 	# Name
// 	--here--
// 	## A
// 	## B
func (d Document) SuggestTOC(toc TOC) (start, end int) {
	minCount := 0
	for _, tocLine := range toc.Headings {
		if tocLine.Depth == toc.MinDepth() {
			minCount++
			if minCount > 1 {
				// too many root headings
				break
			}
		}
		if tocLine.Depth > toc.MinDepth() {
			if minCount == 1 {
				if Verbose {
					log.Printf("found end of root paragraph on line %d for new TOC", tocLine.Index+1)
				}
				return tocLine.Index, tocLine.Index
			}
			// ## appears before # which is odd
			break
		}
	}
	if len(toc.Headings) > 0 {
		start = toc.Headings[0].Index
		if Verbose {
			log.Printf("chose line %d before first significant heading", start+1)
		}
		return start, start
	}
	// in doubt, insert at top
	if Verbose {
		log.Println("chose first line for new TOC (unable to find root paragraph or existing TOC)")
	}
	return 0, 0
}

func (d Document) FindTOC() (start, end int) {
	start = -1
	end = -1
	curStart := -1
	curEnd := -1
	isToc := false
	for i, l := range d.Lines {
		if reIsTOCLine.MatchString(l) {
			if !isToc {
				curStart = i
				isToc = true
			}
			curEnd = i + 1
			continue
		}
		if isToc {
			isToc = false
			if curEnd-curStart > end-start {
				start = curStart
				end = curEnd
			}
		}
	}
	if start > -1 && Verbose {
		log.Printf("found existing TOC on lines %d-%d", start+1, end+1)
	}
	return start, end
}

var reIsTOCLine = regexp.MustCompile(`^\s*- \[.*\]\(#.*\)\s*$`)
<|endoftext|>


<commit_before>// Package filedb provides simple file-based JSON storage amd querying.
package filedb
<commit_msg>tweaked doc<commit_after>// Package filedb provides simple low-performance file-based storage amd querying.
package filedb
<|endoftext|>


<commit_before>/*
ldbrest is a simple REST server for exposing a leveldb[1] database over TCP.

Leveldb is a key-value database written to be embedded. Its major trade-off
from an operational standpoint is that a single database can only be open
*for reading OR writing* by a single process at a time.

These properties make it perfect for a simple REST server offering CRUD
operations on keys. ldbrest exposes a few other useful endpoints as well.

It is invoked with an optional -s/-serveaddr flag and a required positional
/path/to/leveldb. "serveaddr" can be a "host:port" for TCP or a
/path/to/socketfile for a streaming unix domain socket and can be given more
than once. Without any -s/-serveaddr flags it will serve on "127.0.0.1:7000".

The server offers these endpoints:

  GET /key/<name>
Returns the value associated with the <name> key in the response body with
content-type text/plain (or 404s).

  PUT /key/<name>
Takes the (unparsed) request body and stores it as the value under key <name>
and returns a 204.

  DELETE /key/<name>
Deletes the key <name> and returns a 204.

  GET /iterate
Iterates over the sorted keys. It takes optional query string parameters to
control the iterator:

* "forward" is whether to iterate forward through sorted order or reverse
(default "yes", iterate forward)

* "start" is a key to start from (default beginning/end)

* "include_start" is whether to include the key precisely matching "start" if
it exists (default "yes")

* "end" is the key at which to terminate iteration (defaults to end/beginning)

* "include_end" is whether to include the key precisely matching "end" if it
exists (default "no")

* "max" is a maximum number of keys(/values) to return, this can be provided
in conjunction with "end" in which case either condition would terminate
iteration (default 1000, higher values than this will be ignored)

* "include_values" is whether to produce {"key": "<key>", "value": "<value>"}
objects or just "<key>" strings (default "yes")

It then returns a JSON object with two keys "more" and "data". "data" is an
array of either objects or strings depending on "include_values", while "more"
is false unless "end" was provided but "max" caused the end of iteration (there
was still more to go before we would have hit "end").

  POST /batch
Accepts a JSON request body with key "ops", an array of objects with keys "op",
"key", and "value". "op" may be "put" or "delete", in the latter case "value"
may be omitted.

  GET /property/<name>
Gets and returns the leveldb property in the text/plain 200 response body, or
404s if it isn't a valid property name.

  POST /snapshot
Needs a JSON request body with key "destination", which should be a file system
path. ldbrest will make a complete copy of the database at that location, then
return a 204 (after what might be a while).

[1] https://github.com/google/leveldb
*/
package main
<commit_msg>better explanation of /batch<commit_after>/*
ldbrest is a simple REST server for exposing a leveldb[1] database over TCP.

Leveldb is a key-value database written to be embedded. Its major trade-off
from an operational standpoint is that a single database can only be open
*for reading OR writing* by a single process at a time.

These properties make it perfect for a simple REST server offering CRUD
operations on keys. ldbrest exposes a few other useful endpoints as well.

It is invoked with an optional -s/-serveaddr flag and a required positional
/path/to/leveldb. "serveaddr" can be a "host:port" for TCP or a
/path/to/socketfile for a streaming unix domain socket and can be given more
than once. Without any -s/-serveaddr flags it will serve on "127.0.0.1:7000".

The server offers these endpoints:

  GET /key/<name>
Returns the value associated with the <name> key in the response body with
content-type text/plain (or 404s).

  PUT /key/<name>
Takes the (unparsed) request body and stores it as the value under key <name>
and returns a 204.

  DELETE /key/<name>
Deletes the key <name> and returns a 204.

  GET /iterate
Iterates over the sorted keys. It takes optional query string parameters to
control the iterator:

* "forward" is whether to iterate forward through sorted order or reverse
(default "yes", iterate forward)

* "start" is a key to start from (default beginning/end)

* "include_start" is whether to include the key precisely matching "start" if
it exists (default "yes")

* "end" is the key at which to terminate iteration (defaults to end/beginning)

* "include_end" is whether to include the key precisely matching "end" if it
exists (default "no")

* "max" is a maximum number of keys(/values) to return, this can be provided
in conjunction with "end" in which case either condition would terminate
iteration (default 1000, higher values than this will be ignored)

* "include_values" is whether to produce {"key": "<key>", "value": "<value>"}
objects or just "<key>" strings (default "yes")

It then returns a JSON object with two keys "more" and "data". "data" is an
array of either objects or strings depending on "include_values", while "more"
is false unless "end" was provided but "max" caused the end of iteration (there
was still more to go before we would have hit "end").

  POST /batch
Applies a batch of updates atomically. It accepts a JSON request body with key
"ops", an array of objects with keys "op", "key", and "value". "op" may be
"put" or "delete", in the latter case "value" may be omitted.

  GET /property/<name>
Gets and returns the leveldb property in the text/plain 200 response body, or
404s if it isn't a valid property name.

  POST /snapshot
Needs a JSON request body with key "destination", which should be a file system
path. ldbrest will make a complete copy of the database at that location, then
return a 204 (after what might be a while).

[1] https://github.com/google/leveldb
*/
package main
<|endoftext|>


<commit_before>/*
Foo bar.

Supported versions

This library supports reading v2.3 and v2.4 tags, but only writing
v2.4 tags.

The primary reason for not allowing writing older versions is that
they cannot represent all data that is available with v2.4, and
designing the API in a way that's both user friendly and able to
reject data is not worth the trouble.

Automatic upgrading

The library's internal representation of tags matches that of v2.4.
When tags with an older version are being read, they will be
automatically converted to v2.4.

One consequence of this is that when you read a file with v2.3 tags
and immediately save it, it will now be a file with valid v2.4 tags.

The upgrade process makes the following changes to the tags:

  - TYER, TDAT and TIME get replaced by TDRC
  - TORY gets replaced by TDOR
  - XDOR gets replaced by TDOR
  - The slash as a separator for multiple values gets replaced by null bytes

One special case is the TRDA frame because there is no way to
automatically convert it to v2.4. The upgrade process will not
directly delete the frame, so that you can manually upgrade it if
desired, but it won't be written back to the file. The frame is rarely
used and insignificant, so it's not a big loss.

Accessing and manipulating frames

There are two ways to access frames: Using provided getter and setter
methods (there is one for every standard frame), and working directly
with the underlying frames.

For frames that usually support multiple values, e.g. languages, there
will be two different setters and getters: One that operates on slices
and one that operates on single values. When getting a single value,
it will return the first value from the underlying list. When setting
a single value, it will overwrite the list with a single value.

Text frames and user text frames can be manipulated with the
GetTextFrame* and SetTextFrame* class of functions. There are special
methods for working with integers, slices and times. This class of
functions expects the raw frame names (e.g. "TLEN"), with the special
case of user text frames ("TXXX") where it expects a format of the
kind "TXXX:The frame description" to address a specific user text
frame.

Encodings

While ID3v2 allows a variety of encodings (ISO-8859-1, UTF-16 and in
v2.4 also UTF-8), this library only supports writing UTF-8. When
reading frames with different encodings, they will be converted to
UTF-8.

The rationale behind this is that UTF-8 is the encoding assumed by
most of the Go standard library, and that the other encodings have no
realistic benefits over UTF-8.

*/
package id3
<commit_msg>document behaviour on invalid data<commit_after>/*
Foo bar.

Supported versions

This library supports reading v2.3 and v2.4 tags, but only writing
v2.4 tags.

The primary reason for not allowing writing older versions is that
they cannot represent all data that is available with v2.4, and
designing the API in a way that's both user friendly and able to
reject data is not worth the trouble.

Automatic upgrading

The library's internal representation of tags matches that of v2.4.
When tags with an older version are being read, they will be
automatically converted to v2.4.

One consequence of this is that when you read a file with v2.3 tags
and immediately save it, it will now be a file with valid v2.4 tags.

The upgrade process makes the following changes to the tags:

  - TYER, TDAT and TIME get replaced by TDRC
  - TORY gets replaced by TDOR
  - XDOR gets replaced by TDOR
  - The slash as a separator for multiple values gets replaced by null bytes

One special case is the TRDA frame because there is no way to
automatically convert it to v2.4. The upgrade process will not
directly delete the frame, so that you can manually upgrade it if
desired, but it won't be written back to the file. The frame is rarely
used and insignificant, so it's not a big loss.

Accessing and manipulating frames

There are two ways to access frames: Using provided getter and setter
methods (there is one for every standard frame), and working directly
with the underlying frames.

For frames that usually support multiple values, e.g. languages, there
will be two different setters and getters: One that operates on slices
and one that operates on single values. When getting a single value,
it will return the first value from the underlying list. When setting
a single value, it will overwrite the list with a single value.

Text frames and user text frames can be manipulated with the
GetTextFrame* and SetTextFrame* class of functions. There are special
methods for working with integers, slices and times. This class of
functions expects the raw frame names (e.g. "TLEN"), with the special
case of user text frames ("TXXX") where it expects a format of the
kind "TXXX:The frame description" to address a specific user text
frame.

Encodings

While ID3v2 allows a variety of encodings (ISO-8859-1, UTF-16 and in
v2.4 also UTF-8), this library only supports writing UTF-8. When
reading frames with different encodings, they will be converted to
UTF-8.

The rationale behind this is that UTF-8 is the encoding assumed by
most of the Go standard library, and that the other encodings have no
realistic benefits over UTF-8.

Behaviour when encounterind invalid data

There are two kinds of invalid data that can be encountered: Data that
doesn't look like a valid frame, and data that is invalid in the
context of its frame.

An example for the first case is a frame identifier that doesn't
consist of only A-Z0-9. That usually happens when other programs wrote
invalid data. One common case are wrongly encoded sizes, which will
cause us to read random binary data.

An example for the second case is text that isn't valid according to
the specified encoding.

In the first case, parsing of the entire tag will be aborted because
it cannot be ensured that bad things won't happen.

In the second case only that specific frame will be dropped.
*/
package id3
<|endoftext|>


<commit_before>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

/*
Package btcdb provides a database interface for the bitcoin block chain.

As of May 2013, there are over 235,000 blocks in the bitcoin block chain and
and over 17 million transactions (which turns out to be over 11Gb of data).
btcdb provides a database layer to store and retrieve this data in a fairly
simple and efficient manner.  The use of this should not require specific
knowledge of the database backend used although currently only db_sqlite is
provided.

Basic Design

The basic design of btcdb is to provide two classes of items in a
database; blocks and transactions (tx) where the block number
increases monotonically.  Each transaction belongs to a single block
although a block can have a variable number of transactions.  Along
with these two items, several convenience functions for dealing with
the database are provided as well as functions to query specific items
that may be present in a block or tx (although many of these are in
the db_sqlite subpackage).

Usage

At the highest level, the use of this packages just requires that you
import it, setup a database, insert some data into it, and optionally,
query the data back.  In a more concrete example:

        // Import packages.
        import (
               "github.com/conformal/btcdb"
               _ "github.com/conformal/btcdb/sqlite3"
        )

	// Create a database and schedule it to be closed on exit.
        dbName := "example.db"
        db, err := btcdb.CreateDB("sqlite", dbName)
	if err != nil {
		// Log and handle the error
	}
	defer db.Close()

        // Insert a block.
        newHeight, err := db.InsertBlock(block)
	if err != nil {
		// Log and handle the error
	}

        // Sync the database.
        db.Sync()
*/
package btcdb
<commit_msg>Small errors in documentation.<commit_after>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

/*
Package btcdb provides a database interface for the Bitcoin block chain.

As of May 2013, there are over 235,000 blocks in the Bitcoin block chain and
and over 17 million transactions (which turns out to be over 11GB of data).
btcdb provides a database layer to store and retrieve this data in a fairly
simple and efficient manner.  The use of this should not require specific
knowledge of the database backend used although currently only db_sqlite is
provided.

Basic Design

The basic design of btcdb is to provide two classes of items in a
database; blocks and transactions (tx) where the block number
increases monotonically.  Each transaction belongs to a single block
although a block can have a variable number of transactions.  Along
with these two items, several convenience functions for dealing with
the database are provided as well as functions to query specific items
that may be present in a block or tx (although many of these are in
the db_sqlite subpackage).

Usage

At the highest level, the use of this packages just requires that you
import it, setup a database, insert some data into it, and optionally,
query the data back.  In a more concrete example:

        // Import packages.
        import (
               "github.com/conformal/btcdb"
               _ "github.com/conformal/btcdb/sqlite3"
        )

	// Create a database and schedule it to be closed on exit.
        dbName := "example.db"
        db, err := btcdb.CreateDB("sqlite", dbName)
	if err != nil {
		// Log and handle the error
	}
	defer db.Close()

        // Insert a block.
        newHeight, err := db.InsertBlock(block)
	if err != nil {
		// Log and handle the error
	}

        // Sync the database.
        db.Sync()
*/
package btcdb
<|endoftext|>


<commit_before>package modelserver

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gorilla/mux"
	"net/http"
	"strings"
)

type UserData struct {
	User string
	Data map[string]string
}

type Users struct {
	UsersList []UserData
}

type HandlerFunction func(http.ResponseWriter, *http.Request)

type RouterProvider interface {
	GetRouter() *mux.Router
	GetHandlerFunc() HandlerFunction
}

func (c Config) GetRouter() *mux.Router {
	fmt.Println("Getting routes")
	router := mux.NewRouter()
	router.HandleFunc("/{action}", c.GetHandlerFunc())
	return router
}

func (c Config) RenderResponse(w http.ResponseWriter, r *http.Request, users Users) {
	js, err := json.Marshal(users)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func (c Config) GetHandlerFunc() HandlerFunction {
	return func(w http.ResponseWriter, r *http.Request) {
		// todo: abstract pagedata provider interface
		path := strings.TrimRight(r.URL.Path, "/")
		switch path[1:] {
		case "users":
			users := make([]UserData, 1)
			users[0] = UserData{"alex", map[string]string{"name": "Aleksandr"}}
			c.RenderResponse(w, r, Users{users})
			break
		default:
			http.Error(w, errors.New("Not found").Error(), 404)
			break
		}

	}
}
<commit_msg>Adding more elements to the data array<commit_after>package modelserver

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gorilla/mux"
	"net/http"
	"strings"
)

type UserData struct {
	User string
	Data map[string]string
}

type Users struct {
	UsersList []UserData
}

type HandlerFunction func(http.ResponseWriter, *http.Request)

type RouterProvider interface {
	GetRouter() *mux.Router
	GetHandlerFunc() HandlerFunction
}

func (c Config) GetRouter() *mux.Router {
	fmt.Println("Getting routes")
	router := mux.NewRouter()
	router.HandleFunc("/{action}", c.GetHandlerFunc())
	return router
}

func (c Config) RenderResponse(w http.ResponseWriter, r *http.Request, users Users) {
	js, err := json.Marshal(users)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func (c Config) GetHandlerFunc() HandlerFunction {
	// Bootstrap? Get data from the database? ...
	return func(w http.ResponseWriter, r *http.Request) {
		path := strings.TrimRight(r.URL.Path, "/")
		switch path[1:] {
		case "users":
			users := make([]UserData, 2)
			users[0] = UserData{"mitch", map[string]string{"name": "Mitchy Mitch"}}
			users[1] = UserData{"stich", map[string]string{"name": "Stichy Stitch"}}
			c.RenderResponse(w, r, Users{users})
			break
		default:
			http.Error(w, errors.New("Not found").Error(), 404)
			break
		}

	}
}
<|endoftext|>


<commit_before>// Package validator implements value validations
//
// Copyright 2014 Roberto Teixeira <robteix@robteix.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
Package validator implements value validations based on struct tags.

In code it is often necessary to validate that a given value is valid before
using it for something. A typical example might be something like this.

	if age < 18 {
		return error.New("age cannot be under 18")
	}

This is a simple enough example, but it can get significantly more complex,
especially when dealing with structs.

	l := len(strings.Trim(s.Username))
	if l < 3 || l > 40  || !regexp.MatchString("^[a-zA-Z]$", s.Username) ||	s.Age < 18 || s.Password {
		return errors.New("Invalid request")
	}

You get the idea. Package validator allows one to define valid values as
struct tags when defining a new struct type.

	type NewUserRequest struct {
		Username string `validate:"min=3,max=40,regexp=^[a-zA-Z]$"`
		Name string     `validate:"nonzero"`
		Age int         `validate:"min=18"`
		Password string `validate:"min=8"`
	}

Then validating a variable of type NewUserRequest becomes trivial.

	nur := NewUserRequest{Username: "something", ...}
	if valid, _ := validator.Validate(nur); valid {
		// do something
	}

Builtin validator functions

Here is the list of validator functions builtin in the package.

	max
		For numeric numbers, max will simply make sure that the value is
		equal to the parameter given. For strings, it checks that
		the string length is exactly that number of characters. For slices,
		arrays, and maps, validates the number of items. (Usage: len=10)

	max
		For numeric numbers, max will simply make sure that the value is
		lesser or equal to the parameter given. For strings, it checks that
		the string length is at most that number of characters. For slices,
		arrays, and maps, validates the number of items. (Usage: max=10)

	min
		For numeric numbers, min will simply make sure that the value is
		greater or equal to the parameter given. For strings, it checks that
		the string length is at least that number of characters. For slices,
		arrays, and maps, validates the number of items. (Usage: min=10)

	nonzero
		This validates that the value is not zero. The appropriate zero value
		is given by the Go spec (e.g. for int it's 0, for string it's "", for
		pointers is nil, etc.) Usage: nonzero

	regexp
		Only valid for string types, it will validate that the value matches
		the regular expression provided as parameter. (Usage: regexp=^a.*b$)

Note that there are no tests to prevent conflicting validator parameters. For
instance, these fields will never be valid.

	...
	A int     `validate:"max=0,min=1"`
	B string  `validate:"len=10,regexp=^$"
	...

Custom validation functions

It is possible to define custom validation functions by using SetValidationFunc.
First, one needs to create a validation function.

	// Very simple validation func
	func notZZ(v interface{}, param string) error {
		st := reflect.ValueOf(v)
		if st.Kind() != reflect.String {
			return validate.ErrUnsupported
		}
		if st.String() == "ZZ" {
			return errors.New("value cannot be ZZ")
		}
		return nil
	}

Then one needs to add it to the list of validation funcs and give it a "tag" name.

	validate.SetValidationFunc("notzz", notZZ)

Then it is possible to use the notzz validation tag. This will print
"Field A error: value cannot be ZZ"

	type T struct {
		A string  `validate:"nonzero,notzz"`
	}
	t := T{"ZZ"}
	if valid, errs := validator.Validate(t); !valid {
		fmt.Printf("Field A error: %s\n", errs["A"][0])
	}

To use parameters, it is very similar.

	// Very simple validator with parameter
	func notSomething(v interface{}, param string) error {
		st := reflect.ValueOf(v)
		if st.Kind() != reflect.String {
			return validate.ErrUnsupported
		}
		if st.String() == param {
			return errors.New("value cannot be " + param)
		}
		return nil
	}

And then the code below should print "Field A error: value cannot be ABC".

	validator.SetValidationFunc("notsomething", notSomething)
	type T struct {
		A string  `validate:"notsomething=ABC"`
	}
	t := T{"ABC"}
	if valid, errs := validator.Validate(t); !valid {
		fmt.Printf("Field A error: %s\n", errs["A"][0])
	}

As well, it is possible to overwrite builtin validation functions.

	validate.SetValidationFunc("min", myMinFunc)

And you can delete a validation function by setting it to nil.

	validate.SetValidationFunc("notzz", nil)
	validate.SetValidationFunc("nonzero", nil)

Using a non-existing validation func in a field tag will always return
false and with error validate.ErrUnknownTag.

Finally, package validator also provides a helper function that can be used
to validate simple variables/values.

    // valid: true, errs: []
	valid, errs = validator.Valid(42, "min=10, max=50")

	// valid: false, errs: [validate.ErrZeroValue]
	valid, errs = validator.Valid(nil, "nonzero")

	// valid: false, errs: [validate.ErrMin,validate.ErrMax]
	valid, errs = validator.Valid("hi", "nonzero,min=3,max=2")

Custom tag name

In case there is a reason why one would not wish to use tag 'validate' (maybe due to
a conflict with a different package), it is possible to tell the package to use
a different tag.

	validator.SetTag("valid")

Then.

	Type T struct {
		A int    `valid:"min=8, max=10"`
		B string `valid:"nonzero"`
	}

SetTag is permanent. The new tag name will be used until it is again changed
with a new call to SetTag. A way to temporarily use a different tag exists.

	validator.WithTag("foo").Validate(t)
	validator.WithTag("bar").Validate(t)
	// But this will go back to using 'validate'
	validator.Validate(t)

Multiple validators

You may often need to have a different set of validation
rules for different situations. In all the examples above,
we only used the default validator but you could create a
new one and set specific rules for it.

For instance, you might use the same struct to decode incoming JSON for a REST API
but your needs will change when you're using it to, say, create a new instance
in storage vs. when you need to change something.

	type User struct {
		Username string `validate:"nonzero"`
		Name string     `validate:"nonzero"`
		Age int         `validate:"nonzero"`
		Password string `validate:"nonzero"`
	}

Maybe when creating a new user, you need to make sure all values in the struct are filled,
but then you use the same struct to handle incoming requests to, say, change the password,
in which case you only need the Username and the Password and don't care for the others.
You might use two different validators.

	type User struct {
		Username string `creating:"nonzero" chgpw:"nonzero"`
		Name string     `creating:"nonzero"`
		Age int         `creating:"nonzero"`
		Password string `creating:"nonzero" chgpw:"nonzero"`
	}

	var (
		creationValidator = validator.NewValidator()
		chgPwValidator = validator.NewValidator()
	)

	func init() {
		creationValidator.SetTag("creating")
		chgPwValidator.SetTag("chgpw")
	}

	...

	func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
		var u User
		json.NewDecoder(r.Body).Decode(&user)
		if valid, _ := creationValidator.Validate(user); !valid {
			// the request did not include all of the User
			// struct fields, so send a http.StatusBadRequest
			// back or something
		}
		// create the new user
	}

	func SetNewUserPasswordHandler(w http.ResponseWriter, r *http.Request) {
		var u User
		json.NewDecoder(r.Body).Decode(&user)
		if valid, _ := chgPwValidator.Validate(user); !valid {
			// the request did not Username and Password,
			// so send a http.StatusBadRequest
			// back or something
		}
		// save the new password
	}

It is also possible to do all of that using only the default validator as long
as SetTag is always called before calling validator.Validate() or you chain the
with WithTag().

*/
package validator
<commit_msg>Updated docs to match new return type API<commit_after>// Package validator implements value validations
//
// Copyright 2014 Roberto Teixeira <robteix@robteix.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
Package validator implements value validations based on struct tags.

In code it is often necessary to validate that a given value is valid before
using it for something. A typical example might be something like this.

	if age < 18 {
		return error.New("age cannot be under 18")
	}

This is a simple enough example, but it can get significantly more complex,
especially when dealing with structs.

	l := len(strings.Trim(s.Username))
	if l < 3 || l > 40  || !regexp.MatchString("^[a-zA-Z]$", s.Username) ||	s.Age < 18 || s.Password {
		return errors.New("Invalid request")
	}

You get the idea. Package validator allows one to define valid values as
struct tags when defining a new struct type.

	type NewUserRequest struct {
		Username string `validate:"min=3,max=40,regexp=^[a-zA-Z]$"`
		Name string     `validate:"nonzero"`
		Age int         `validate:"min=18"`
		Password string `validate:"min=8"`
	}

Then validating a variable of type NewUserRequest becomes trivial.

	nur := NewUserRequest{Username: "something", ...}
	if errs := validator.Validate(nur); errs != nil {
		// do something
	}

Builtin validator functions

Here is the list of validator functions builtin in the package.

	max
		For numeric numbers, max will simply make sure that the value is
		equal to the parameter given. For strings, it checks that
		the string length is exactly that number of characters. For slices,
		arrays, and maps, validates the number of items. (Usage: len=10)

	max
		For numeric numbers, max will simply make sure that the value is
		lesser or equal to the parameter given. For strings, it checks that
		the string length is at most that number of characters. For slices,
		arrays, and maps, validates the number of items. (Usage: max=10)

	min
		For numeric numbers, min will simply make sure that the value is
		greater or equal to the parameter given. For strings, it checks that
		the string length is at least that number of characters. For slices,
		arrays, and maps, validates the number of items. (Usage: min=10)

	nonzero
		This validates that the value is not zero. The appropriate zero value
		is given by the Go spec (e.g. for int it's 0, for string it's "", for
		pointers is nil, etc.) Usage: nonzero

	regexp
		Only valid for string types, it will validate that the value matches
		the regular expression provided as parameter. (Usage: regexp=^a.*b$)

Note that there are no tests to prevent conflicting validator parameters. For
instance, these fields will never be valid.

	...
	A int     `validate:"max=0,min=1"`
	B string  `validate:"len=10,regexp=^$"
	...

Custom validation functions

It is possible to define custom validation functions by using SetValidationFunc.
First, one needs to create a validation function.

	// Very simple validation func
	func notZZ(v interface{}, param string) error {
		st := reflect.ValueOf(v)
		if st.Kind() != reflect.String {
			return validate.ErrUnsupported
		}
		if st.String() == "ZZ" {
			return errors.New("value cannot be ZZ")
		}
		return nil
	}

Then one needs to add it to the list of validation funcs and give it a "tag" name.

	validate.SetValidationFunc("notzz", notZZ)

Then it is possible to use the notzz validation tag. This will print
"Field A error: value cannot be ZZ"

	type T struct {
		A string  `validate:"nonzero,notzz"`
	}
	t := T{"ZZ"}
	if errs := validator.Validate(t); errs != nil {
		fmt.Printf("Field A error: %s\n", errs["A"][0])
	}

To use parameters, it is very similar.

	// Very simple validator with parameter
	func notSomething(v interface{}, param string) error {
		st := reflect.ValueOf(v)
		if st.Kind() != reflect.String {
			return validate.ErrUnsupported
		}
		if st.String() == param {
			return errors.New("value cannot be " + param)
		}
		return nil
	}

And then the code below should print "Field A error: value cannot be ABC".

	validator.SetValidationFunc("notsomething", notSomething)
	type T struct {
		A string  `validate:"notsomething=ABC"`
	}
	t := T{"ABC"}
	if errs := validator.Validate(t); errs != nil {
		fmt.Printf("Field A error: %s\n", errs["A"][0])
	}

As well, it is possible to overwrite builtin validation functions.

	validate.SetValidationFunc("min", myMinFunc)

And you can delete a validation function by setting it to nil.

	validate.SetValidationFunc("notzz", nil)
	validate.SetValidationFunc("nonzero", nil)

Using a non-existing validation func in a field tag will always return
false and with error validate.ErrUnknownTag.

Finally, package validator also provides a helper function that can be used
to validate simple variables/values.

    	// errs: nil
	errs = validator.Valid(42, "min=10, max=50")

	// errs: [validate.ErrZeroValue]
	errs = validator.Valid(nil, "nonzero")

	// errs: [validate.ErrMin,validate.ErrMax]
	errs = validator.Valid("hi", "nonzero,min=3,max=2")

Custom tag name

In case there is a reason why one would not wish to use tag 'validate' (maybe due to
a conflict with a different package), it is possible to tell the package to use
a different tag.

	validator.SetTag("valid")

Then.

	Type T struct {
		A int    `valid:"min=8, max=10"`
		B string `valid:"nonzero"`
	}

SetTag is permanent. The new tag name will be used until it is again changed
with a new call to SetTag. A way to temporarily use a different tag exists.

	validator.WithTag("foo").Validate(t)
	validator.WithTag("bar").Validate(t)
	// But this will go back to using 'validate'
	validator.Validate(t)

Multiple validators

You may often need to have a different set of validation
rules for different situations. In all the examples above,
we only used the default validator but you could create a
new one and set specific rules for it.

For instance, you might use the same struct to decode incoming JSON for a REST API
but your needs will change when you're using it to, say, create a new instance
in storage vs. when you need to change something.

	type User struct {
		Username string `validate:"nonzero"`
		Name string     `validate:"nonzero"`
		Age int         `validate:"nonzero"`
		Password string `validate:"nonzero"`
	}

Maybe when creating a new user, you need to make sure all values in the struct are filled,
but then you use the same struct to handle incoming requests to, say, change the password,
in which case you only need the Username and the Password and don't care for the others.
You might use two different validators.

	type User struct {
		Username string `creating:"nonzero" chgpw:"nonzero"`
		Name string     `creating:"nonzero"`
		Age int         `creating:"nonzero"`
		Password string `creating:"nonzero" chgpw:"nonzero"`
	}

	var (
		creationValidator = validator.NewValidator()
		chgPwValidator = validator.NewValidator()
	)

	func init() {
		creationValidator.SetTag("creating")
		chgPwValidator.SetTag("chgpw")
	}

	...

	func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
		var u User
		json.NewDecoder(r.Body).Decode(&user)
		if errs := creationValidator.Validate(user); errs != nil {
			// the request did not include all of the User
			// struct fields, so send a http.StatusBadRequest
			// back or something
		}
		// create the new user
	}

	func SetNewUserPasswordHandler(w http.ResponseWriter, r *http.Request) {
		var u User
		json.NewDecoder(r.Body).Decode(&user)
		if errs := chgPwValidator.Validate(user); errs != nil {
			// the request did not Username and Password,
			// so send a http.StatusBadRequest
			// back or something
		}
		// save the new password
	}

It is also possible to do all of that using only the default validator as long
as SetTag is always called before calling validator.Validate() or you chain the
with WithTag().

*/
package validator
<|endoftext|>