<commit_before>/*
Copyright 2018 The Jetstack cert-manager contributors.

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 pki

import (
	"crypto/x509"
	"testing"

	"github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1"
)

func buildCertificate(cn string, dnsNames ...string) *v1alpha1.Certificate {
	return &v1alpha1.Certificate{
		Spec: v1alpha1.CertificateSpec{
			CommonName: cn,
			DNSNames:   dnsNames,
		},
	}
}

func TestCommonNameForCertificate(t *testing.T) {
	type testT struct {
		name        string
		crtCN       string
		crtDNSNames []string
		expectedCN  string
	}
	tests := []testT{
		{
			name:       "certificate with CommonName set",
			crtCN:      "test",
			expectedCN: "test",
		},
		{
			name:        "certificate with one DNS name set",
			crtDNSNames: []string{"dnsname"},
			expectedCN:  "dnsname",
		},
		{
			name:        "certificate with both common name and dnsName set",
			crtCN:       "cn",
			crtDNSNames: []string{"dnsname"},
			expectedCN:  "cn",
		},
		{
			name:        "certificate with multiple dns names set",
			crtDNSNames: []string{"dnsname1", "dnsname2"},
			expectedCN:  "dnsname1",
		},
	}
	testFn := func(test testT) func(*testing.T) {
		return func(t *testing.T) {
			actualCN := CommonNameForCertificate(buildCertificate(test.crtCN, test.crtDNSNames...))
			if actualCN != test.expectedCN {
				t.Errorf("expected %q but got %q", test.expectedCN, actualCN)
				return
			}
		}
	}
	for _, test := range tests {
		t.Run(test.name, testFn(test))
	}
}

func TestDNSNamesForCertificate(t *testing.T) {
	type testT struct {
		name           string
		crtCN          string
		crtDNSNames    []string
		expectDNSNames []string
	}
	tests := []testT{
		{
			name:           "certificate with CommonName set",
			crtCN:          "test",
			expectDNSNames: []string{"test"},
		},
		{
			name:           "certificate with one DNS name set",
			crtDNSNames:    []string{"dnsname"},
			expectDNSNames: []string{"dnsname"},
		},
		{
			name:           "certificate with both common name and dnsName set",
			crtCN:          "cn",
			crtDNSNames:    []string{"dnsname"},
			expectDNSNames: []string{"cn", "dnsname"},
		},
		{
			name:           "certificate with multiple dns names set",
			crtDNSNames:    []string{"dnsname1", "dnsname2"},
			expectDNSNames: []string{"dnsname1", "dnsname2"},
		},
		{
			name:           "certificate with dnsName[0] set to equal common name",
			crtCN:          "cn",
			crtDNSNames:    []string{"cn", "dnsname"},
			expectDNSNames: []string{"cn", "dnsname"},
		},
		{
			name:           "certificate with a dnsName equal to cn",
			crtCN:          "cn",
			crtDNSNames:    []string{"dnsname", "cn"},
			expectDNSNames: []string{"cn", "dnsname"},
		},
	}
	testFn := func(test testT) func(*testing.T) {
		return func(t *testing.T) {
			actualDNSNames := DNSNamesForCertificate(buildCertificate(test.crtCN, test.crtDNSNames...))
			if len(actualDNSNames) != len(test.expectDNSNames) {
				t.Errorf("expected %q but got %q", test.expectDNSNames, actualDNSNames)
				return
			}
			for i, actual := range actualDNSNames {
				if test.expectDNSNames[i] != actual {
					t.Errorf("expected %q but got %q", test.expectDNSNames, actualDNSNames)
					return
				}
			}
		}
	}
	for _, test := range tests {
		t.Run(test.name, testFn(test))
	}
}

func TestSignatureAlgorithmForCertificate(t *testing.T) {
	type testT struct {
		name            string
		keyAlgo         v1alpha1.KeyAlgorithm
		keySize         int
		expectErr       bool
		expectedSigAlgo x509.SignatureAlgorithm
	}

	tests := []testT{
		{
			name:      "certificate with KeyAlgorithm rsa and size 1024",
			keyAlgo:   v1alpha1.RSAKeyAlgorithm,
			expectErr: true,
		},
		{
			name:            "certificate with KeyAlgorithm not set",
			keyAlgo:         v1alpha1.KeyAlgorithm(""),
			expectedSigAlgo: x509.SHA256WithRSA,
		},
		{
			name:            "certificate with KeyAlgorithm rsa and size 2048",
			keyAlgo:         v1alpha1.RSAKeyAlgorithm,
			keySize:         2048,
			expectedSigAlgo: x509.SHA256WithRSA,
		},
		{
			name:            "certificate with KeyAlgorithm rsa and size 3072",
			keyAlgo:         v1alpha1.RSAKeyAlgorithm,
			keySize:         3072,
			expectedSigAlgo: x509.SHA384WithRSA,
		},
		{
			name:            "certificate with KeyAlgorithm rsa and size 4096",
			keyAlgo:         v1alpha1.RSAKeyAlgorithm,
			keySize:         4096,
			expectedSigAlgo: x509.SHA512WithRSA,
		},
		{
			name:            "certificate with KeyAlgorithm ecdsa and size 256",
			keyAlgo:         v1alpha1.ECDSAKeyAlgorithm,
			keySize:         256,
			expectedSigAlgo: x509.ECDSAWithSHA256,
		},
		{
			name:            "certificate with KeyAlgorithm ecdsa and size 384",
			keyAlgo:         v1alpha1.ECDSAKeyAlgorithm,
			keySize:         384,
			expectedSigAlgo: x509.ECDSAWithSHA384,
		},
		{
			name:            "certificate with KeyAlgorithm ecdsa and size 521",
			keyAlgo:         v1alpha1.ECDSAKeyAlgorithm,
			keySize:         521,
			expectedSigAlgo: x509.ECDSAWithSHA512,
		},
		{
			name:      "certificate with KeyAlgorithm ecdsa and size 100",
			keyAlgo:   v1alpha1.ECDSAKeyAlgorithm,
			expectErr: true,
		},
		{
			name:            "certificate with KeyAlgorithm set to unknown key algo",
			keyAlgo:         v1alpha1.KeyAlgorithm("blah"),
			expectErr:       true,
			expectedSigAlgo: x509.UnknownSignatureAlgorithm,
		},
	}

	testFn := func(test testT) func(*testing.T) {
		return func(t *testing.T) {
			actualSigAlgo, err := SignatureAlgorithm(buildCertificateWithKeyParams(test.keyAlgo, test.keySize))
			if test.expectErr && err == nil {
				t.Error("expected err, but got no error")
				return
			}

			if !test.expectErr {
				if err != nil {
					t.Errorf("expected no err, but got '%q'", err)
					return
				}

				if actualSigAlgo != test.expectedSigAlgo {
					t.Errorf("expected %q but got %q", test.expectedSigAlgo, actualSigAlgo)
					return
				}
			}
		}
	}

	for _, test := range tests {
		t.Run(test.name, testFn(test))
	}
}
<commit_msg>Update unit tests<commit_after>/*
Copyright 2018 The Jetstack cert-manager contributors.

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 pki

import (
	"crypto/x509"
	"testing"

	"github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1"
)

func buildCertificate(cn string, dnsNames ...string) *v1alpha1.Certificate {
	return &v1alpha1.Certificate{
		Spec: v1alpha1.CertificateSpec{
			CommonName: cn,
			DNSNames:   dnsNames,
		},
	}
}

func TestCommonNameForCertificate(t *testing.T) {
	type testT struct {
		name        string
		crtCN       string
		crtDNSNames []string
		expectedCN  string
	}
	tests := []testT{
		{
			name:       "certificate with CommonName set",
			crtCN:      "test",
			expectedCN: "test",
		},
		{
			name:        "certificate with one DNS name set",
			crtDNSNames: []string{"dnsname"},
			expectedCN:  "dnsname",
		},
		{
			name:        "certificate with both common name and dnsName set",
			crtCN:       "cn",
			crtDNSNames: []string{"dnsname"},
			expectedCN:  "cn",
		},
		{
			name:        "certificate with multiple dns names set",
			crtDNSNames: []string{"dnsname1", "dnsname2"},
			expectedCN:  "dnsname1",
		},
	}
	testFn := func(test testT) func(*testing.T) {
		return func(t *testing.T) {
			actualCN := CommonNameForCertificate(buildCertificate(test.crtCN, test.crtDNSNames...))
			if actualCN != test.expectedCN {
				t.Errorf("expected %q but got %q", test.expectedCN, actualCN)
				return
			}
		}
	}
	for _, test := range tests {
		t.Run(test.name, testFn(test))
	}
}

func TestDNSNamesForCertificate(t *testing.T) {
	type testT struct {
		name           string
		crtCN          string
		crtDNSNames    []string
		expectDNSNames []string
	}
	tests := []testT{
		{
			name:           "certificate with CommonName set",
			crtCN:          "test",
			expectDNSNames: []string{"test"},
		},
		{
			name:           "certificate with one DNS name set",
			crtDNSNames:    []string{"dnsname"},
			expectDNSNames: []string{"dnsname"},
		},
		{
			name:           "certificate with both common name and dnsName set",
			crtCN:          "cn",
			crtDNSNames:    []string{"dnsname"},
			expectDNSNames: []string{"cn", "dnsname"},
		},
		{
			name:           "certificate with multiple dns names set",
			crtDNSNames:    []string{"dnsname1", "dnsname2"},
			expectDNSNames: []string{"dnsname1", "dnsname2"},
		},
		{
			name:           "certificate with dnsName[0] set to equal common name",
			crtCN:          "cn",
			crtDNSNames:    []string{"cn", "dnsname"},
			expectDNSNames: []string{"cn", "dnsname"},
		},
		{
			name:           "certificate with a dnsName equal to cn",
			crtCN:          "cn",
			crtDNSNames:    []string{"dnsname", "cn"},
			expectDNSNames: []string{"cn", "dnsname"},
		},
	}
	testFn := func(test testT) func(*testing.T) {
		return func(t *testing.T) {
			actualDNSNames := DNSNamesForCertificate(buildCertificate(test.crtCN, test.crtDNSNames...))
			if len(actualDNSNames) != len(test.expectDNSNames) {
				t.Errorf("expected %q but got %q", test.expectDNSNames, actualDNSNames)
				return
			}
			for i, actual := range actualDNSNames {
				if test.expectDNSNames[i] != actual {
					t.Errorf("expected %q but got %q", test.expectDNSNames, actualDNSNames)
					return
				}
			}
		}
	}
	for _, test := range tests {
		t.Run(test.name, testFn(test))
	}
}

func TestSignatureAlgorithmForCertificate(t *testing.T) {
	type testT struct {
		name            string
		keyAlgo         v1alpha1.KeyAlgorithm
		keySize         int
		expectErr       bool
		expectedSigAlgo x509.SignatureAlgorithm
		expectedKeyType x509.PublicKeyAlgorithm
	}

	tests := []testT{
		{
			name:      "certificate with KeyAlgorithm rsa and size 1024",
			keyAlgo:   v1alpha1.RSAKeyAlgorithm,
			expectErr: true,
		},
		{
			name:            "certificate with KeyAlgorithm not set",
			keyAlgo:         v1alpha1.KeyAlgorithm(""),
			expectedSigAlgo: x509.SHA256WithRSA,
			expectedKeyType: x509.RSA,
		},
		{
			name:            "certificate with KeyAlgorithm rsa and size 2048",
			keyAlgo:         v1alpha1.RSAKeyAlgorithm,
			keySize:         2048,
			expectedSigAlgo: x509.SHA256WithRSA,
			expectedKeyType: x509.RSA,
		},
		{
			name:            "certificate with KeyAlgorithm rsa and size 3072",
			keyAlgo:         v1alpha1.RSAKeyAlgorithm,
			keySize:         3072,
			expectedSigAlgo: x509.SHA384WithRSA,
			expectedKeyType: x509.RSA,
		},
		{
			name:            "certificate with KeyAlgorithm rsa and size 4096",
			keyAlgo:         v1alpha1.RSAKeyAlgorithm,
			keySize:         4096,
			expectedSigAlgo: x509.SHA512WithRSA,
			expectedKeyType: x509.RSA,
		},
		{
			name:            "certificate with KeyAlgorithm ecdsa and size 256",
			keyAlgo:         v1alpha1.ECDSAKeyAlgorithm,
			keySize:         256,
			expectedSigAlgo: x509.ECDSAWithSHA256,
			expectedKeyType: x509.ECDSA,
		},
		{
			name:            "certificate with KeyAlgorithm ecdsa and size 384",
			keyAlgo:         v1alpha1.ECDSAKeyAlgorithm,
			keySize:         384,
			expectedSigAlgo: x509.ECDSAWithSHA384,
			expectedKeyType: x509.ECDSA,
		},
		{
			name:            "certificate with KeyAlgorithm ecdsa and size 521",
			keyAlgo:         v1alpha1.ECDSAKeyAlgorithm,
			keySize:         521,
			expectedSigAlgo: x509.ECDSAWithSHA512,
			expectedKeyType: x509.ECDSA,
		},
		{
			name:      "certificate with KeyAlgorithm ecdsa and size 100",
			keyAlgo:   v1alpha1.ECDSAKeyAlgorithm,
			expectErr: true,
		},
		{
			name:      "certificate with KeyAlgorithm set to unknown key algo",
			keyAlgo:   v1alpha1.KeyAlgorithm("blah"),
			expectErr: true,
		},
	}

	testFn := func(test testT) func(*testing.T) {
		return func(t *testing.T) {
			actualPKAlgo, actualSigAlgo, err := SignatureAlgorithm(buildCertificateWithKeyParams(test.keyAlgo, test.keySize))
			if test.expectErr && err == nil {
				t.Error("expected err, but got no error")
				return
			}

			if !test.expectErr {
				if err != nil {
					t.Errorf("expected no err, but got '%q'", err)
					return
				}

				if actualSigAlgo != test.expectedSigAlgo {
					t.Errorf("expected %q but got %q", test.expectedSigAlgo, actualSigAlgo)
					return
				}

				if actualPKAlgo != test.expectedKeyType {
					t.Errorf("expected %q but got %q", test.expectedKeyType, actualPKAlgo)
					return
				}
			}
		}
	}

	for _, test := range tests {
		t.Run(test.name, testFn(test))
	}
}
<|endoftext|>


<commit_before>package jason

import (
	"encoding/json"
	"errors"
	"io"
)

// Value represents an arbitrary JSON value.
// It may contain a bool, number, string, object, array or null.
type Value struct {
	data   interface{}
	exists bool // Used to separate nil and non-existing values
}

// Object represents an object JSON object.
// It inherets from Value but with an additional method to access
// a map representation of it's content. It's useful when iterating.
type Object struct {
	Value
	m     map[string]*Value
	valid bool
}

// Returns the golang map.
// Needed when iterating through the values of the object.
func (v *Object) Map() map[string]*Value {
	return v.m
}

// Creates a new value from an io.reader.
// Returns an error if the reader does not contain valid json.
// Useful for parsing the body of a net/http response.
// Example: NewFromReader(res.Body)
func NewValueFromReader(reader io.Reader) (*Value, error) {
	j := new(Value)
	d := json.NewDecoder(reader)
	err := d.Decode(&j.data)
	return j, err
}

// Creates a new value from bytes.
// Returns an error if the bytes are not valid json.
func NewValueFromBytes(b []byte) (*Value, error) {
	j := new(Value)
	err := json.Unmarshal(b, &j.data)
	return j, err
}

// Creates a new value from a string.
// Returns an error if the string is not valid json.
func NewValueFromString(s string) (*Value, error) {
	b := []byte(s)
	return NewValueFromBytes(b)
}

func objectFromValue(v *Value, err error) (*Object, error) {
	if err != nil {
		return nil, err
	} else {

		o, err := v.AsObject()

		if err != nil {
			return nil, err
		} else {
			return o, nil
		}

	}
}

func NewObjectFromString(s string) (*Object, error) {
	return objectFromValue(NewValueFromString(s))
}

func NewObjectFromBytes(b []byte) (*Object, error) {
	return objectFromValue(NewValueFromBytes(b))
}

func NewObjectFromReader(reader io.Reader) (*Object, error) {
	return objectFromValue(NewValueFromReader(reader))
}

// Marshal into bytes.
func (v *Value) Marshal() ([]byte, error) {
	return json.Marshal(v.data)
}

// Private Get
func (v *Value) get(key string) (*Value, error) {

	// Assume this is an object
	obj, err := v.AsObject()

	if err == nil {
		child, ok := obj.Map()[key]
		if ok {
			return child, nil
		} else {
			return nil, errors.New("key not found")
		}
	}

	return nil, err
}

// Private get path
func (v *Value) getPath(keys []string) (*Value, error) {
	current := v
	var err error
	for _, key := range keys {
		current, err = current.get(key)

		if err != nil {
			return nil, err
		}
	}
	return current, nil
}

// Gets the value at key path.
// Returns error if the value does not exist.
// Example: Get("address", "street")
func (v *Object) Get(keys ...string) (*Value, error) {
	return v.getPath(keys)
}

// Gets the value at key path and attempts to typecast the value into an object.
// Returns error if the value is not a json object.
func (v *Object) GetObject(keys ...string) (*Object, error) {
	child, err := v.getPath(keys)

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

		obj, err := child.AsObject()

		if err != nil {
			return nil, err
		} else {
			return obj, nil
		}

	}

	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into a string.
// Returns error if the value is not a json string.
func (v *Object) GetString(keys ...string) (string, error) {
	child, err := v.getPath(keys)

	if err != nil {
		return "", err
	} else {
		return child.AsString()
	}

	return "", nil
}

// Gets the value at key path and attempts to typecast the value into null.
// Returns error if the value is not json null.
func (v *Object) GetNull(keys ...string) error {
	child, err := v.getPath(keys)

	if err != nil {
		return err
	}

	return child.AsNull()
}

// Gets the value at key path and attempts to typecast the value into a float64.
// Returns error if the value is not a json number.
func (v *Object) GetNumber(keys ...string) (float64, error) {
	child, err := v.getPath(keys)

	if err != nil {
		return 0, err
	} else {

		n, err := child.AsNumber()

		if err != nil {
			return 0, err
		} else {
			return n, nil
		}
	}

	return 0, nil
}

// Gets the value at key path and attempts to typecast the value into a bool.
// Returns error if the value is not a json boolean.
func (v *Object) GetBoolean(keys ...string) (bool, error) {
	child, err := v.getPath(keys)

	if err != nil {
		return false, err
	}

	return child.AsBoolean()
}

// Gets the value at key path and attempts to typecast the value into an array.
// Returns error if the value is not a json array.
func (v *Object) GetArray(keys ...string) ([]*Value, error) {
	child, err := v.getPath(keys)

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

		return child.AsArray()

	}

	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into an array of objects.
// Returns error if the value is not a json array or if any of the contained objects are not objects.
func (v *Object) GetObjectArray(keys ...string) ([]*Object, error) {
	child, err := v.getPath(keys)

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

		array, err := child.AsArray()

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

			typedArray := make([]*Object, len(array))

			for index, arrayItem := range array {
				typedArrayItem, err := arrayItem.AsObject()

				if err != nil {
					return nil, err
				} else {
					typedArray[index] = typedArrayItem
				}

			}
			return typedArray, nil
		}
	}

	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into an array of string.
// Returns error if the value is not a json array or if any of the contained objects are not strings.
func (v *Object) GetStringArray(keys ...string) ([]string, error) {
	child, err := v.getPath(keys)

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

		array, err := child.AsArray()

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

			typedArray := make([]string, len(array))

			for index, arrayItem := range array {
				typedArrayItem, err := arrayItem.AsString()

				if err != nil {
					return nil, err
				} else {
					typedArray[index] = typedArrayItem
				}

			}
			return typedArray, nil
		}
	}
	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into an array of floats.
// Returns error if the value is not a json array or if any of the contained objects are not numbers.
func (v *Object) GetNumberArray(keys ...string) ([]float64, error) {
	child, err := v.getPath(keys)

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

		array, err := child.AsArray()

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

			typedArray := make([]float64, len(array))

			for index, arrayItem := range array {
				typedArrayItem, err := arrayItem.AsNumber()

				if err != nil {
					return nil, err
				} else {
					typedArray[index] = typedArrayItem
				}

			}
			return typedArray, nil
		}
	}
	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into an array of bools.
// Returns error if the value is not a json array or if any of the contained objects are not booleans.
func (v *Object) GetBooleanArray(keys ...string) ([]bool, error) {
	child, err := v.getPath(keys)

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

		array, err := child.AsArray()

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

			typedArray := make([]bool, len(array))

			for index, arrayItem := range array {
				typedArrayItem, err := arrayItem.AsBoolean()

				if err != nil {
					return nil, err
				} else {
					typedArray[index] = typedArrayItem
				}

			}
			return typedArray, nil
		}
	}
	return nil, nil
}

// Returns an error if the value is not actually null
func (v *Value) AsNull() error {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case nil:
		valid = v.exists // Valid only if j also exists, since other values could possibly also be nil
		break
	}

	if valid {
		return nil
	}

	return errors.New("is not null")

}

// Attempts to typecast the current value into an array.
// Returns error if the current value is not a json array.
func (v *Value) AsArray() ([]*Value, error) {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case []interface{}:
		valid = true
		break
	}

	// Unsure if this is a good way to use slices, it's probably not
	var slice []*Value

	if valid {

		for _, element := range v.data.([]interface{}) {
			child := Value{element, true}
			slice = append(slice, &child)
		}

		return slice, nil
	}

	return slice, errors.New("Not an array")

}

// Attempts to typecast the current value into a float64.
// Returns error if the current value is not a json number.
func (v *Value) AsNumber() (float64, error) {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case float64:
		valid = true
		break
	}

	if valid {
		return v.data.(float64), nil
	}

	return 0, errors.New("not a number")
}

// Attempts to typecast the current value into a bool.
// Returns error if the current value is not a json boolean.
func (v *Value) AsBoolean() (bool, error) {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case bool:
		valid = true
		break
	}

	if valid {
		return v.data.(bool), nil
	}

	return false, errors.New("no bool")
}

// Attempts to typecast the current value into an object.
// Returns error if the current value is not a json object.
func (v *Value) AsObject() (*Object, error) {

	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case map[string]interface{}:
		valid = true
		break
	}

	if valid {
		obj := new(Object)
		obj.valid = valid

		m := make(map[string]*Value)

		if valid {

			for key, element := range v.data.(map[string]interface{}) {
				m[key] = &Value{element, true}

			}
		}

		obj.data = v.data
		obj.m = m

		return obj, nil
	}

	return nil, errors.New("not an object")
}

// Attempts to typecast the current value into a string.
// Returns error if the current value is not a json string
func (v *Value) AsString() (string, error) {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case string:
		valid = true
		break
	}

	if valid {
		return v.data.(string), nil
	}

	return "", errors.New("not a string")
}

// Returns the value a json formatted string.
// Note: The method named String() is used by golang's log method for logging.
func (v *Value) String() string {
	f, err := json.Marshal(v.data)
	if err != nil {
		return err.Error()
	} else {
		return string(f)
	}
}
<commit_msg>Add GetNullArray method<commit_after>package jason

import (
	"encoding/json"
	"errors"
	"io"
)

// Value represents an arbitrary JSON value.
// It may contain a bool, number, string, object, array or null.
type Value struct {
	data   interface{}
	exists bool // Used to separate nil and non-existing values
}

// Object represents an object JSON object.
// It inherets from Value but with an additional method to access
// a map representation of it's content. It's useful when iterating.
type Object struct {
	Value
	m     map[string]*Value
	valid bool
}

// Returns the golang map.
// Needed when iterating through the values of the object.
func (v *Object) Map() map[string]*Value {
	return v.m
}

// Creates a new value from an io.reader.
// Returns an error if the reader does not contain valid json.
// Useful for parsing the body of a net/http response.
// Example: NewFromReader(res.Body)
func NewValueFromReader(reader io.Reader) (*Value, error) {
	j := new(Value)
	d := json.NewDecoder(reader)
	err := d.Decode(&j.data)
	return j, err
}

// Creates a new value from bytes.
// Returns an error if the bytes are not valid json.
func NewValueFromBytes(b []byte) (*Value, error) {
	j := new(Value)
	err := json.Unmarshal(b, &j.data)
	return j, err
}

// Creates a new value from a string.
// Returns an error if the string is not valid json.
func NewValueFromString(s string) (*Value, error) {
	b := []byte(s)
	return NewValueFromBytes(b)
}

func objectFromValue(v *Value, err error) (*Object, error) {
	if err != nil {
		return nil, err
	} else {

		o, err := v.AsObject()

		if err != nil {
			return nil, err
		} else {
			return o, nil
		}

	}
}

func NewObjectFromString(s string) (*Object, error) {
	return objectFromValue(NewValueFromString(s))
}

func NewObjectFromBytes(b []byte) (*Object, error) {
	return objectFromValue(NewValueFromBytes(b))
}

func NewObjectFromReader(reader io.Reader) (*Object, error) {
	return objectFromValue(NewValueFromReader(reader))
}

// Marshal into bytes.
func (v *Value) Marshal() ([]byte, error) {
	return json.Marshal(v.data)
}

// Private Get
func (v *Value) get(key string) (*Value, error) {

	// Assume this is an object
	obj, err := v.AsObject()

	if err == nil {
		child, ok := obj.Map()[key]
		if ok {
			return child, nil
		} else {
			return nil, errors.New("key not found")
		}
	}

	return nil, err
}

// Private get path
func (v *Value) getPath(keys []string) (*Value, error) {
	current := v
	var err error
	for _, key := range keys {
		current, err = current.get(key)

		if err != nil {
			return nil, err
		}
	}
	return current, nil
}

// Gets the value at key path.
// Returns error if the value does not exist.
// Example: Get("address", "street")
func (v *Object) Get(keys ...string) (*Value, error) {
	return v.getPath(keys)
}

// Gets the value at key path and attempts to typecast the value into an object.
// Returns error if the value is not a json object.
func (v *Object) GetObject(keys ...string) (*Object, error) {
	child, err := v.getPath(keys)

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

		obj, err := child.AsObject()

		if err != nil {
			return nil, err
		} else {
			return obj, nil
		}

	}

	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into a string.
// Returns error if the value is not a json string.
func (v *Object) GetString(keys ...string) (string, error) {
	child, err := v.getPath(keys)

	if err != nil {
		return "", err
	} else {
		return child.AsString()
	}

	return "", nil
}

// Gets the value at key path and attempts to typecast the value into null.
// Returns error if the value is not json null.
func (v *Object) GetNull(keys ...string) error {
	child, err := v.getPath(keys)

	if err != nil {
		return err
	}

	return child.AsNull()
}

// Gets the value at key path and attempts to typecast the value into a float64.
// Returns error if the value is not a json number.
func (v *Object) GetNumber(keys ...string) (float64, error) {
	child, err := v.getPath(keys)

	if err != nil {
		return 0, err
	} else {

		n, err := child.AsNumber()

		if err != nil {
			return 0, err
		} else {
			return n, nil
		}
	}

	return 0, nil
}

// Gets the value at key path and attempts to typecast the value into a bool.
// Returns error if the value is not a json boolean.
func (v *Object) GetBoolean(keys ...string) (bool, error) {
	child, err := v.getPath(keys)

	if err != nil {
		return false, err
	}

	return child.AsBoolean()
}

// Gets the value at key path and attempts to typecast the value into an array.
// Returns error if the value is not a json array.
func (v *Object) GetArray(keys ...string) ([]*Value, error) {
	child, err := v.getPath(keys)

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

		return child.AsArray()

	}

	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into an array of objects.
// Returns error if the value is not a json array or if any of the contained objects are not objects.
func (v *Object) GetObjectArray(keys ...string) ([]*Object, error) {
	child, err := v.getPath(keys)

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

		array, err := child.AsArray()

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

			typedArray := make([]*Object, len(array))

			for index, arrayItem := range array {
				typedArrayItem, err := arrayItem.AsObject()

				if err != nil {
					return nil, err
				} else {
					typedArray[index] = typedArrayItem
				}

			}
			return typedArray, nil
		}
	}

	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into an array of string.
// Returns error if the value is not a json array or if any of the contained objects are not strings.
func (v *Object) GetStringArray(keys ...string) ([]string, error) {
	child, err := v.getPath(keys)

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

		array, err := child.AsArray()

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

			typedArray := make([]string, len(array))

			for index, arrayItem := range array {
				typedArrayItem, err := arrayItem.AsString()

				if err != nil {
					return nil, err
				} else {
					typedArray[index] = typedArrayItem
				}

			}
			return typedArray, nil
		}
	}
	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into an array of floats.
// Returns error if the value is not a json array or if any of the contained objects are not numbers.
func (v *Object) GetNumberArray(keys ...string) ([]float64, error) {
	child, err := v.getPath(keys)

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

		array, err := child.AsArray()

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

			typedArray := make([]float64, len(array))

			for index, arrayItem := range array {
				typedArrayItem, err := arrayItem.AsNumber()

				if err != nil {
					return nil, err
				} else {
					typedArray[index] = typedArrayItem
				}

			}
			return typedArray, nil
		}
	}
	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into an array of bools.
// Returns error if the value is not a json array or if any of the contained objects are not booleans.
func (v *Object) GetBooleanArray(keys ...string) ([]bool, error) {
	child, err := v.getPath(keys)

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

		array, err := child.AsArray()

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

			typedArray := make([]bool, len(array))

			for index, arrayItem := range array {
				typedArrayItem, err := arrayItem.AsBoolean()

				if err != nil {
					return nil, err
				} else {
					typedArray[index] = typedArrayItem
				}

			}
			return typedArray, nil
		}
	}
	return nil, nil
}

// Gets the value at key path and attempts to typecast the value into an array of nulls.
// Returns length, or an error if the value is not a json array or if any of the contained objects are not nulls.
func (v *Object) GetNullArray(keys ...string) (int64, error) {
	child, err := v.getPath(keys)

	if err != nil {
		return 0, err
	} else {

		array, err := child.AsArray()

		if err != nil {
			return 0, err
		} else {

			var length int64 = 0

			for _, arrayItem := range array {
				err := arrayItem.AsNull()

				if err != nil {
					return 0, err
				} else {
					length++
				}

			}
			return length, nil
		}
	}

	return 0, nil
}

// Returns an error if the value is not actually null
func (v *Value) AsNull() error {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case nil:
		valid = v.exists // Valid only if j also exists, since other values could possibly also be nil
		break
	}

	if valid {
		return nil
	}

	return errors.New("is not null")

}

// Attempts to typecast the current value into an array.
// Returns error if the current value is not a json array.
func (v *Value) AsArray() ([]*Value, error) {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case []interface{}:
		valid = true
		break
	}

	// Unsure if this is a good way to use slices, it's probably not
	var slice []*Value

	if valid {

		for _, element := range v.data.([]interface{}) {
			child := Value{element, true}
			slice = append(slice, &child)
		}

		return slice, nil
	}

	return slice, errors.New("Not an array")

}

// Attempts to typecast the current value into a float64.
// Returns error if the current value is not a json number.
func (v *Value) AsNumber() (float64, error) {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case float64:
		valid = true
		break
	}

	if valid {
		return v.data.(float64), nil
	}

	return 0, errors.New("not a number")
}

// Attempts to typecast the current value into a bool.
// Returns error if the current value is not a json boolean.
func (v *Value) AsBoolean() (bool, error) {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case bool:
		valid = true
		break
	}

	if valid {
		return v.data.(bool), nil
	}

	return false, errors.New("no bool")
}

// Attempts to typecast the current value into an object.
// Returns error if the current value is not a json object.
func (v *Value) AsObject() (*Object, error) {

	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case map[string]interface{}:
		valid = true
		break
	}

	if valid {
		obj := new(Object)
		obj.valid = valid

		m := make(map[string]*Value)

		if valid {

			for key, element := range v.data.(map[string]interface{}) {
				m[key] = &Value{element, true}

			}
		}

		obj.data = v.data
		obj.m = m

		return obj, nil
	}

	return nil, errors.New("not an object")
}

// Attempts to typecast the current value into a string.
// Returns error if the current value is not a json string
func (v *Value) AsString() (string, error) {
	var valid bool

	// Check the type of this data
	switch v.data.(type) {
	case string:
		valid = true
		break
	}

	if valid {
		return v.data.(string), nil
	}

	return "", errors.New("not a string")
}

// Returns the value a json formatted string.
// Note: The method named String() is used by golang's log method for logging.
func (v *Value) String() string {
	f, err := json.Marshal(v.data)
	if err != nil {
		return err.Error()
	} else {
		return string(f)
	}
}
<|endoftext|>


<commit_before>// Package nasa provides Go structs and functions for accessing the NASA API
//
// Queries are made with Go types as arguments and responses returned as valid Go types.
// For best experience, grap NASA API key from api.nasa.gov and set it to the environment variable NASAKEY
//   export NASAKEY=Your-NASA-API_KEY
//
// Example Usage
//
//  package main
//
//  import (
//  	"fmt"
//  	"log"
//  	"time"
//
//  	"github.com/peteretelej/nasa"
//  )
//
//  func main() {
//  	apod, err := nasa.ApodImage(time.Now())
//  	handle(err)
//  	fmt.Println(apod)
//
//  	// apod has structure of nasa.Image, hence get details with:
//  	// apod.Date, apod.Title, apod.Explanation, apod.URL, apod.HDURL etc
//  	fmt.Printf("Today's APOD is %s, available at %s", apod.Title, apod.HDURL)
//
//  	lastweek := time.Now().Add(-(7 * 24 * time.Hour))
//  	apod, err = nasa.ApodImage(lastweek)
//  	handle(err)
//  	fmt.Printf("APOD for 1 week ago:\n%s\n", apod)
//  }
//  func handle(err error) {
//  	if err != nil {
//  		log.Fatal(err)
//  	}
//  }
//

package nasa
<commit_msg>Fix godoc doc.go comment<commit_after>// Package nasa provides Go structs and functions for accessing the NASA API
//
// Queries are made with Go types as arguments and responses returned as valid Go types.
// For best experience, grap NASA API key from api.nasa.gov and set it to the environment variable NASAKEY
//   export NASAKEY=Your-NASA-API_KEY
//
// Example Usage
//
//  package main
//
//  import (
//  	"fmt"
//  	"log"
//  	"time"
//
//  	"github.com/peteretelej/nasa"
//  )
//
//  func main() {
//  	apod, err := nasa.ApodImage(time.Now())
//  	handle(err)
//  	fmt.Println(apod)
//
//  	// apod has structure of nasa.Image, hence get details with:
//  	// apod.Date, apod.Title, apod.Explanation, apod.URL, apod.HDURL etc
//  	fmt.Printf("Today's APOD is %s, available at %s", apod.Title, apod.HDURL)
//
//  	lastweek := time.Now().Add(-(7 * 24 * time.Hour))
//  	apod, err = nasa.ApodImage(lastweek)
//  	handle(err)
//  	fmt.Printf("APOD for 1 week ago:\n%s\n", apod)
//  }
//  func handle(err error) {
//  	if err != nil {
//  		log.Fatal(err)
//  	}
//  }
//
package nasa
<|endoftext|>


<commit_before>// Copyright 2014 The gocui 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 gocui allows to create console user interfaces.

Create a new GUI:

	g, err := gocui.NewGui()
	if err != nil {
		// handle error
	}
	defer g.Close()

	// Set GUI managers and key bindings
	// ...

	if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
		// handle error
	}

Set GUI managers:

	g.SetManager(mgr1, mgr2)

Managers are in charge of GUI's layout and can be used to build widgets. On
each iteration of the GUI's main loop, the Layout function of each configured
manager is executed. Managers are used to set-up and update the application's
main views, being possible to freely change them during execution. Also, it is
important to mention that a main loop iteration is executed on each reported
event (key-press, mouse event, window resize, etc).

GUIs are composed by Views, you can think of it as buffers. Views implement the
io.ReadWriter interface, so you can just write to them if you want to modify
their content. The same is valid for reading.

Create and initialize a view with absolute coordinates:

	if v, err := g.SetView("viewname", 2, 2, 22, 7); err != nil {
		if err != gocui.ErrUnknownView {
			// handle error
		}
		fmt.Fprintln(v, "This is a new view")
		// ...
	}

Views can also be created using relative coordinates:

	maxX, maxY := g.Size()
	if v, err := g.SetView("viewname", maxX/2-30, maxY/2, maxX/2+30, maxY/2+2); err != nil {
		// ...
	}

Configure keybindings:

	if err := g.SetKeybinding("viewname", gocui.KeyEnter, gocui.ModNone, fcn); err != nil {
		// handle error
	}

gocui implements full mouse support that can be enabled with:

	g.Mouse = true

Mouse events are handled like any other keybinding:

	if err := g.SetKeybinding("viewname", gocui.MouseLeft, gocui.ModNone, fcn); err != nil {
		// handle error
	}

IMPORTANT: Views can only be created, destroyed or updated in three ways: from
the Layout function within managers, from keybinding callbacks or via
*Gui.Execute(). The reason for this is that it allows gocui to be
concurrent-safe. So, if you want to update your GUI from a goroutine, you must
use *Gui.Execute(). For example:

	g.Execute(func(g *gocui.Gui) error {
		v, err := g.View("viewname")
		if err != nil {
			// handle error
		}
		v.Clear()
		fmt.Fprintln(v, "Writing from different goroutines")
		return nil
	})

By default, gocui provides a basic edition mode. This mode can be extended
and customized creating a new Editor and assigning it to *View.Editor:

	type Editor interface {
		Edit(v *View, key Key, ch rune, mod Modifier)
	}

DefaultEditor can be taken as example to create your own custom Editor:

	var DefaultEditor Editor = EditorFunc(simpleEditor)

	func simpleEditor(v *View, key Key, ch rune, mod Modifier) {
		switch {
		case ch != 0 && mod == 0:
			v.EditWrite(ch)
		case key == KeySpace:
			v.EditWrite(' ')
		case key == KeyBackspace || key == KeyBackspace2:
			v.EditDelete(true)
		// ...
		}
	}

Colored text:

Views allow to add colored text using ANSI colors. For example:

	fmt.Fprintln(v, "\x1b[0;31mHello world")

For more information, see the examples in folder "_examples/".
*/
package gocui
<commit_msg>Update docs<commit_after>// Copyright 2014 The gocui 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 gocui allows to create console user interfaces.

Create a new GUI:

	g, err := gocui.NewGui(gocui.OutputNormal)
	if err != nil {
		// handle error
	}
	defer g.Close()

	// Set GUI managers and key bindings
	// ...

	if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
		// handle error
	}

Set GUI managers:

	g.SetManager(mgr1, mgr2)

Managers are in charge of GUI's layout and can be used to build widgets. On
each iteration of the GUI's main loop, the Layout function of each configured
manager is executed. Managers are used to set-up and update the application's
main views, being possible to freely change them during execution. Also, it is
important to mention that a main loop iteration is executed on each reported
event (key-press, mouse event, window resize, etc).

GUIs are composed by Views, you can think of it as buffers. Views implement the
io.ReadWriter interface, so you can just write to them if you want to modify
their content. The same is valid for reading.

Create and initialize a view with absolute coordinates:

	if v, err := g.SetView("viewname", 2, 2, 22, 7); err != nil {
		if err != gocui.ErrUnknownView {
			// handle error
		}
		fmt.Fprintln(v, "This is a new view")
		// ...
	}

Views can also be created using relative coordinates:

	maxX, maxY := g.Size()
	if v, err := g.SetView("viewname", maxX/2-30, maxY/2, maxX/2+30, maxY/2+2); err != nil {
		// ...
	}

Configure keybindings:

	if err := g.SetKeybinding("viewname", gocui.KeyEnter, gocui.ModNone, fcn); err != nil {
		// handle error
	}

gocui implements full mouse support that can be enabled with:

	g.Mouse = true

Mouse events are handled like any other keybinding:

	if err := g.SetKeybinding("viewname", gocui.MouseLeft, gocui.ModNone, fcn); err != nil {
		// handle error
	}

IMPORTANT: Views can only be created, destroyed or updated in three ways: from
the Layout function within managers, from keybinding callbacks or via
*Gui.Execute(). The reason for this is that it allows gocui to be
concurrent-safe. So, if you want to update your GUI from a goroutine, you must
use *Gui.Execute(). For example:

	g.Execute(func(g *gocui.Gui) error {
		v, err := g.View("viewname")
		if err != nil {
			// handle error
		}
		v.Clear()
		fmt.Fprintln(v, "Writing from different goroutines")
		return nil
	})

By default, gocui provides a basic edition mode. This mode can be extended
and customized creating a new Editor and assigning it to *View.Editor:

	type Editor interface {
		Edit(v *View, key Key, ch rune, mod Modifier)
	}

DefaultEditor can be taken as example to create your own custom Editor:

	var DefaultEditor Editor = EditorFunc(simpleEditor)

	func simpleEditor(v *View, key Key, ch rune, mod Modifier) {
		switch {
		case ch != 0 && mod == 0:
			v.EditWrite(ch)
		case key == KeySpace:
			v.EditWrite(' ')
		case key == KeyBackspace || key == KeyBackspace2:
			v.EditDelete(true)
		// ...
		}
	}

Colored text:

Views allow to add colored text using ANSI colors. For example:

	fmt.Fprintln(v, "\x1b[0;31mHello world")

For more information, see the examples in folder "_examples/".
*/
package gocui
<|endoftext|>


<commit_before>/*
Package goserver provide request router with middleware

Basic example

	package main

	import (
		"fmt"
		"log"
		"net/http"

		"github.com/vardius/goserver"
	)

	func Index(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "Welcome!\n")
	}

	func Hello(w http.ResponseWriter, r *http.Request) {
		params, _ := goserver.ParamsFromContext(r.Context())
		fmt.Fprintf(w, "hello, %s!\n", params.Value("name"))
	}

	func main() {
		server := goserver.New()
		server.GET("/", Index)
		server.GET("/hello/:name", Hello)

		log.Fatal(http.ListenAndServe(":8080", server))
	}

Routing
The router determines how to handle that request.
Goserver uses a routing tree. Once one branch of the tree matches, only routes inside that branch are considered,
not any routes after that branch. When instantiating server, the root node of router tree is created.

Route types
- Static `/hello`
will match requests matching given route
- Named `/:name`
will match requests matching given route scheme
- Regexp `/:name:[a-z]+`
will match requests matching given route scheme and its regexp

Wildcards
The values of *named parameter* or *regexp parameters* are accessible via *request context*
`params, ok := goserver.ParamsFromContext(req.Context())`.
You can get the value of a parameter either by its index in the slice, or by using the `params.Value(name)` method:
`:name` or `/:name:[a-z]+` can be retrived by `params.Value("name")`.

Defining Routes
A full route definition contain up to three parts:
1. HTTP method under which route will be available
2. The URL path route. This is matched against the URL passed to the server,
and can contain named wildcard placeholders *(e.g. :placeholders)* to match dynamic parts in the URL.
3. `http.HandleFunc`, which tells the server to handle matched requests to the router with handler.

Take the following example:

	server.GET("/hello/:name:r([a-z]+)go", func(w http.ResponseWriter, r *http.Request) {
		params, _ := goserver.ParamsFromContext(r.Context())
		fmt.Fprintf(w, "hello, %s!\n", params.Value("name"))
	})

In this case, the route is matched by `/hello/rxxxxxgo` for example,
because the `:name` wildcard matches the regular expression wildcard given (`r([a-z]+)go`). However,
`/hello/foo` does not match, because "foo" fails the *name* wildcard. When using wildcards,
these are returned in the map from request context. The part of the path that the wildcard matched (e.g. *rxxxxxgo*) is used as value.
*/
package goserver
<commit_msg>Removed markdown from docs<commit_after>/*
Package goserver provide request router with middleware

The router determines how to handle that request.
Goserver uses a routing tree. Once one branch of the tree matches, only routes inside that branch are considered,
not any routes after that branch. When instantiating server, the root node of router tree is created.

Route types

- Static `/hello` (will match requests matching given route)
- Named `/:name` (will match requests matching given route scheme)
- Regexp `/:name:[a-z]+` (will match requests matching given route scheme and its regexp)

The values of *named parameter* or *regexp parameters* are accessible via *request context*
`params, ok := goserver.ParamsFromContext(req.Context())`.
You can get the value of a parameter either by its index in the slice, or by using the `params.Value(name)` method:
`:name` or `/:name:[a-z]+` can be retrived by `params.Value("name")`.

A full route definition contain up to three parts:

1. HTTP method under which route will be available
2. The URL path route. This is matched against the URL passed to the server,
and can contain named wildcard placeholders *(e.g. :placeholders)* to match dynamic parts in the URL.
3. `http.HandleFunc`, which tells the server to handle matched requests to the router with handler.

Take the following example:

	server.GET("/hello/:name:r([a-z]+)go", func(w http.ResponseWriter, r *http.Request) {
		params, _ := goserver.ParamsFromContext(r.Context())
		fmt.Fprintf(w, "hello, %s!\n", params.Value("name"))
	})

In this case, the route is matched by `/hello/rxxxxxgo` for example,
because the `:name` wildcard matches the regular expression wildcard given (`r([a-z]+)go`). However,
`/hello/foo` does not match, because "foo" fails the *name* wildcard. When using wildcards,
these are returned in the map from request context. The part of the path that the wildcard matched (e.g. *rxxxxxgo*) is used as value.

Basic example:

	package main

	import (
		"fmt"
		"log"
		"net/http"

		"github.com/vardius/goserver"
	)

	func Index(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "Welcome!\n")
	}

	func Hello(w http.ResponseWriter, r *http.Request) {
		params, _ := goserver.ParamsFromContext(r.Context())
		fmt.Fprintf(w, "hello, %s!\n", params.Value("name"))
	}

	func main() {
		server := goserver.New()
		server.GET("/", Index)
		server.GET("/hello/:name", Hello)

		log.Fatal(http.ListenAndServe(":8080", server))
	}
*/
package goserver
<|endoftext|>


<commit_before>/*
Package rx provides Reactive Extensions (ReactiveX) for Go, an API for
asynchronous programming with observable streams (Observables).

Heterogeneous

The implementation in this package is created by expanding templates from
"github.com/reactivego/rx/generic" on the "interface{}" type. A variable of
type "interface{}"" accepts a value of any type. This makes this package
heterogeneous, since the definition of a heterogeneous variable is that it
can contain a value of any type.

	From(1,"hi",2.3).Println()

Heterogenous is great when you want to mix values of different types in a
stream, but by gaining that, you loose type safety. However, by using
Generics for Go (https://github.com/reactivego/jig) it is also possible to
have the jig command generate typesafe implementation of the templates.

	FromInt(1,2,3).Println()

Creating Observables

Functions to create new observables from lists, slices and channels.
	From          http://reactivex.io/documentation/operators/from.html
	FromChan
	FromSlice

Combining Observables

Functions and methods on observable that allow combining multiple observables.
	Concat        http://reactivex.io/documentation/operators/concat.html

Transforming Observables

Functions and methods to transform observables to same or other types.
	Filter        http://reactivex.io/documentation/operators/filter.html
	MergeMap      http://reactivex.io/documentation/operators/flatmap.html
	Map           http://reactivex.io/documentation/operators/map.html
	Scan          http://reactivex.io/documentation/operators/scan.html

Side Effects triggered by Observables

Methods on observables to trigger side effects.
	Do            http://reactivex.io/documentation/operators/do.html
	DoOnError
	DoOnComplete
	Finally

For an overview of all implemented operators, see
https://github.com/reactivego/rx
*/
package rx

import _ "github.com/reactivego/rx/generic"

// In this package we have defined a non-exported alias 'any' for 'interface{}'.
// So in the examples, instead of 'interface{}' you will find 'any' being used.
// If you choose to use this package in your own code, you can decide for yourself
// how to call the interface{} type, this is not enforced by this package.
type any = interface{}
<commit_msg>Documentation update.<commit_after>/*
Package rx provides Reactive Extensions (ReactiveX) for Go, an API for
asynchronous programming with observable streams (Observables).

Heterogeneous

Heterogeneous simply means that you can mix types in function and method calls.
That is very convenient but not typesafe. The implementation in this package is
generated by expanding templates from the "generic" subdirectory on the
"interface{}" type. A function or method parameter of type interface{} accepts
mixed types.

	From(1,"hi",2.3).Println()

Creating Observables

Functions to create new observables from lists, slices and channels.
	From          http://reactivex.io/documentation/operators/from.html
	FromChan
	FromSlice

Combining Observables

Functions and methods on observable that allow combining multiple observables.
	Concat        http://reactivex.io/documentation/operators/concat.html

Transforming Observables

Functions and methods to transform observables to same or other types.
	Filter        http://reactivex.io/documentation/operators/filter.html
	MergeMap      http://reactivex.io/documentation/operators/flatmap.html
	Map           http://reactivex.io/documentation/operators/map.html
	Scan          http://reactivex.io/documentation/operators/scan.html

Side Effects triggered by Observables

Methods on observables to trigger side effects.
	Do            http://reactivex.io/documentation/operators/do.html
	DoOnError
	DoOnComplete
	Finally

For an overview of all implemented operators, see
https://github.com/reactivego/rx

Generics for Go

You don't need Generics for Go in order to use this package. If you are however
interested in regenerating this package, then read on.

The implementation in this package is generated from a generic implementation
found in the subdirectory "generic" inside this package. It works by replacing
the place-holder types in the templates with "interface{}". This creates a
heterogeneous package. To regenerate this implementation, run jig inside this
package directory as follows:

	go get -d github.com/reactivego/jig
	go run github.com/reactivego/jig -rv
*/
package rx

import _ "github.com/reactivego/rx/generic"

// In this package we have defined a non-exported alias 'any' for 'interface{}'.
// So in the examples, instead of 'interface{}' you will find 'any' being used.
// If you choose to use this package in your own code, you can decide for yourself
// how to call the interface{} type, this is not enforced by this package.
type any = interface{}
<|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.

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
<commit_msg>document handling of unsupported frames<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.

Unsupported frames

Unsupported frames, like extensions by Apple, will be left untouched,
meaning that they will be read and written as raw byte slices. If you
know how to handle them, you can write your own function to parse and
modify the content. All unsupported frames will be of type
UnsupportedFrame.

*/
package id3
<|endoftext|>


<commit_before>/*
Package junos allows you to run commands on and configure Junos devices.

Establishing a session
	jnpr := junos.NewSession(host, user, password)

Lock config
	err := jnpr.Lock()
	if err != nil {
		log.Fatal(err)
	}

Unlock config
	err = jnpr.Unlock()
	if err != nil {
		log.Fatal(err)
	}

Compare the current configuration to a rollback config.
	diff, err := jnpr.RollbackDiff(3)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(diff)

Rollback to an older configuration.
	err := jnpr.RollbackConfig(2)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}

Run operational mode commands, such as "show."
	output, err := jnpr.Command("show version", "text")
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(output)

When you specify "text," the output will be just like it is on the CLI:

*/
package junos<commit_msg>Updated documentation<commit_after>/*
Package junos allows you to run commands on and configure Junos devices.

Establishing a session
	jnpr := junos.NewSession(host, user, password)

Lock config
	err := jnpr.Lock()
	if err != nil {
		log.Fatal(err)
	}

Unlock config
	err = jnpr.Unlock()
	if err != nil {
		log.Fatal(err)
	}

Compare the current configuration to a rollback config.
	diff, err := jnpr.RollbackDiff(3)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(diff)

Rollback to an older configuration.
	err := jnpr.RollbackConfig(2)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}

Run operational mode commands, such as "show."
	output, err := jnpr.Command("show version", "text")
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(output)

When you specify "text," the output will be just like it is on the CLI:

    node0:
    --------------------------------------------------------------------------
    Hostname: firewall-1
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

    node1:
    --------------------------------------------------------------------------
    Hostname: firewall-2
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

*/
package junos<|endoftext|>


<commit_before>/*

Package minquery provides a mgo-like Query type called MinQuery, which supports
efficient query pagination (cursors to continue listing documents where
we left off).

Example using MinQuery

Let's say we have a users collection in MongoDB modeled with this Go struct:

    type User struct {
        ID      bson.ObjectID `bson:"_id"`
        Name    string        `bson:"name"`
        Country string        `bson:"country"`
    }

To query users having country=USA, sorted by Name and ID:

    q := minquery.New(session.DB(""), "users", bson.M{"country" : "USA"}).
        Sort("name", "_id").Limit(10)
    // If this is not the first page, set cursor:
    if cursor := getLastCursor(); cursor != "" {
        q = q.Cursor(cursor)
    }

    var users []*User
    newCursor, err := q.All(&users, "country", "name", "_id")

And that's all. newCursor is the cursor to be used to fetch the next batch.

Note #1: When calling MinQuery.All(), you have to provide the names
of the cursor fields, this will be used to build the cursor data
(and ultimately the cursor string) from.

Note #2: If you're retrieving partial results (by using MinQuery.Select()),
you have to include all the fields that are part of the cursor (the index entry)
even if you don't intend to use them directly, else MinQuery.All() will not
have all the values of the cursor fields, and so it will not be able to create
the proper cursor value.

*/
package minquery
<commit_msg>Added clarification about the getLastCursor() function.<commit_after>/*

Package minquery provides a mgo-like Query type called MinQuery, which supports
efficient query pagination (cursors to continue listing documents where
we left off).

Example using MinQuery

Let's say we have a users collection in MongoDB modeled with this Go struct:

    type User struct {
        ID      bson.ObjectID `bson:"_id"`
        Name    string        `bson:"name"`
        Country string        `bson:"country"`
    }

To query users having country=USA, sorted by Name and ID:

    q := minquery.New(session.DB(""), "users", bson.M{"country" : "USA"}).
        Sort("name", "_id").Limit(10)
    // If this is not the first page, set cursor:
    // getLastCursor() represents your logic how you acquire the last cursor.
    if cursor := getLastCursor(); cursor != "" {
        q = q.Cursor(cursor)
    }

    var users []*User
    newCursor, err := q.All(&users, "country", "name", "_id")

And that's all. newCursor is the cursor to be used to fetch the next batch.

Note #1: When calling MinQuery.All(), you have to provide the names
of the cursor fields, this will be used to build the cursor data
(and ultimately the cursor string) from.

Note #2: If you're retrieving partial results (by using MinQuery.Select()),
you have to include all the fields that are part of the cursor (the index entry)
even if you don't intend to use them directly, else MinQuery.All() will not
have all the values of the cursor fields, and so it will not be able to create
the proper cursor value.

*/
package minquery
<|endoftext|>


<commit_before>/*
Package cast provides tools for safely converting from one type to another, without information loss.
*/
package cast
<commit_msg>added to docs<commit_after>/*
Package cast provides tools for safely converting from one type to another, without information loss.

For example, you can safely convert a uint8, uint16, uint32, plus an int, int8, int16, int32, int64,
into an int64 without information loss.

In other words, if `v` (in the following example code) is any of the types just list, then the following
code would successfully return an int64 of the same value.

	i64, err := cast.Int64(v)

In addition to these types built into Go (that were in the list), this package also supports converting
custom types, as long as they implement a special method.

For int64, the special method is:

	interface {
		Int64() (int64, error)
	}

For example:

	type Always5 struct{}

	func (receiver Always5) Int64() (int64, error) {
		return 5, nil
	}

	// ...

	var v Always5

	// ...

	i64, err := cast.Int64(v)
*/
package cast
<|endoftext|>


<commit_before>// Copyright (c) 2015, Benjamin Borbe <bborbe@rocketnews.de>.
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package portfolio
<commit_msg>2015 -> 2016<commit_after>// Copyright (c) 2016, Benjamin Borbe <bborbe@rocketnews.de>.
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package portfolio
<|endoftext|>


<commit_before>/*

esc embeds files into go programs and provides http.FileSystem interfaces
to them.

It adds all named files or files recursively under named directories at the
path specified. The output file provides an http.FileSystem interface with
zero dependencies on packages outside the standard library.

Usage:
    esc [-o outfile.go] [-pkg package] [-prefix prefix] [name ...]

The flags are:
    -o=""
        output filename, defaults to stdout
    -pkg="main"
        package name of output file, defaults to main
    -prefix=""
        strip given prefix from filenames

Accessing Embedded Files

After producing an output file, the assets may be accessed with the FS()
function, which takes a flag to use local assets instead (for local
development).

Example

Embedded assets can be served with HTTP using the http.FileServer. Assuming you have a directory called "static" and
have run "esc -o static.go static" and main.go has the following code:

    package main

    import (
        "log"
        "net/http"
    )

    func main() {
        //FS() is created by esc and returns a http.Filesystem compatible with http.FileServer
        http.Handle("/static/", http.FileServer(FS(false)))
        log.Fatal(http.ListenAndServe(":8080", nil))
    }

You can now execute "go run main.go static.go" and access the embedded files in a
browser via http://localhost:8080/static/

*/
package main
<commit_msg>Clarify process to build and run example code.<commit_after>/*

esc embeds files into go programs and provides http.FileSystem interfaces
to them.

It adds all named files or files recursively under named directories at the
path specified. The output file provides an http.FileSystem interface with
zero dependencies on packages outside the standard library.

Usage:
	esc [-o outfile.go] [-pkg package] [-prefix prefix] [name ...]

The flags are:
	-o=""
		output filename, defaults to stdout
	-pkg="main"
		package name of output file, defaults to main
	-prefix=""
		strip given prefix from filenames

Accessing Embedded Files

After producing an output file, the assets may be accessed with the FS()
function, which takes a flag to use local assets instead (for local
development).

Example

Embedded assets can be served with HTTP using the http.FileServer. Assuming you have a directory
structure similar to the following:

	/..
	/main.go
	/static/index.html
	/static/css/style.css

Where main.go contains:

	package main

	import (
		"log"
		"net/http"
	)

	func main() {
		//FS() is created by esc and returns a http.Filesystem compatible with http.FileServer
		http.Handle("/static/", http.FileServer(FS(false)))
		log.Fatal(http.ListenAndServe(":8080", nil))
	}

1. Execute esc -o static.go static to generate the embedded data
2. go run main.go and static.go to start the server
3. access http://localhost:8080/static/ to view the files
*/
package main
<|endoftext|>


<commit_before>// Package js provides functions for interacting with native JavaScript APIs. Calls to these functions are treated specially by GopherJS and translated directly to their corresponding JavaScript syntax.
// The types Object and Any are containers for JavaScript objects and are no real citizens of the Go world, e.g. they do not implement interface{} and you cannot type assert them. The type Any may also contain Go values, but it provides no methods for accessing its content. It is only useful for passing it to functions of this package. The relation between interface{} (Go world), Object (JS world) and Any looks like this:
//
//  +------------------------------------+
//  |                                    |
//  |  +-------------+  +-------------+  |
//  |  |             |  |             |  |
//  |  | interface{} |  |  js.Object  |  |
//  |  |             |  |             |  |
//  |  +-------------+  +-------------+  |
//  |                                    |
//  |               js.Any               |
//  |                                    |
//  +------------------------------------+
//
// Type conversions between Go types and JavaScript types are performed automatically according to the following table:
//
//  | Go type                        | Conversions to interface{} | JavaScript type   |
//  | ------------------------------ | -------------------------- | ----------------- |
//  | bool                           | bool                       | Boolean           |
//  | int?, uint?, float?            | float64                    | Number            |
//  | string                         | string                     | String            |
//  | [?]int8                        | []int8                     | Int8Array         |
//  | [?]int16                       | []int16                    | Int16Array        |
//  | [?]int32, [?]int               | []int                      | Int32Array        |
//  | [?]uint8                       | []uint8                    | Uint8Array        |
//  | [?]uint16                      | []uint16                   | Uint16Array       |
//  | [?]uint32, [?]uint, [?]uintptr | []uint                     | Uint32Array       |
//  | [?]float32                     | []float32                  | Float32Array      |
//  | [?]float64                     | []float64                  | Float64Array      |
//  | all other slices and arrays    | []interface{}              | Array             |
//  | functions                      | func(...js.Any) js.Object  | Function          |
//  | time.Time                      | time.Time                  | Date              |
//  | -                              | *js.DOMNode                | instanceof Node   |
//  | maps, structs                  | map[string]interface{}     | instanceof Object |
//
package js

// Object is a container for a native JavaScript object. Calls to its methods are treated specially by GopherJS and translated directly to their JavaScript syntax. Nil is equal to JavaScript's "null".
// Object can not be used as a map key and it can only be converted to Any, but no other interface type, including interface{}. This means that you can't pass an Object obj to fmt.Println(obj), but using the println(obj) built-in is possible.
type Object interface {

	// Get returns the object's property with the given key.
	Get(key string) Object

	// Set assigns the value to the object's property with the given key.
	Set(key string, value Any)

	// Delete removes the object's property with the given key.
	Delete(key string)

	// Get returns the object's "length" property, converted to int.
	Length() int

	// Index returns the i'th element of an array.
	Index(i int) Object

	// SetIndex sets the i'th element of an array.
	SetIndex(i int, value Any)

	// Call calls the object's method with the given name.
	Call(name string, args ...Any) Object

	// Invoke calls the object itself. This will fail if it is not a function.
	Invoke(args ...Any) Object

	// New creates a new instance of this type object. This will fail if it not a function (constructor).
	New(args ...Any) Object

	// Bool returns the object converted to bool according to JavaScript type conversions.
	Bool() bool

	// String returns the object converted to string according to JavaScript type conversions.
	String() string

	// Int returns the object converted to int according to JavaScript type conversions (parseInt).
	Int() int

	// Int64 returns the object converted to int64 according to JavaScript type conversions (parseInt).
	Int64() int64

	// Uint64 returns the object converted to uint64 according to JavaScript type conversions (parseInt).
	Uint64() uint64

	// Float returns the object converted to float64 according to JavaScript type conversions (parseFloat).
	Float() float64

	// Interface returns the object converted to interface{}. See GopherJS' README for details.
	Interface() interface{}

	// Unsafe returns the object as an uintptr, which can be converted via unsafe.Pointer. Not intended for public use.
	Unsafe() uintptr
}

// Any may contain a JavaScript object or some Go value. Any can not be used as a map key and it can not be converted to some other interface type, including interface{}.
type Any interface{}

// DOMNode is used for encapsulating DOM nodes in a proper Go value. It is not feasible to convert a DOM node into a map[string]interface{}.
type DOMNode struct {
	Object
}

// Error encapsulates JavaScript errors. Those are turned into a Go panic and may be rescued, giving an *Error that holds the JavaScript error object.
type Error struct {
	Object
}

// Error returns the message of the encapsulated JavaScript error object.
func (err *Error) Error() string {
	return "JavaScript error: " + err.Get("message").String()
}

// Stack returns the stack property of the encapsulated JavaScript error object.
func (err *Error) Stack() string {
	return err.Get("stack").String()
}

// Global gives JavaScript's global object ("window" for browsers and "GLOBAL" for Node.js). Set this to a mock for testing with pure Go.
var Global Object

// This gives the value of JavaScript's "this" keyword. It can be used when passing Go functions to JavaScript as callbacks. Set this to a mock for testing with pure Go.
var This Object

// Arguments gives the value of JavaScript's "arguments" keyword. It can be used when passing Go functions to JavaScript as callbacks. Set this to a mock for testing with pure Go.
var Arguments []Object

// Module gives the value of the "module" variable set by Node.js. Hint: Set a module export with 'js.Module.Get("exports").Set("exportName", ...)'.
var Module Object

// Undefined gives the JavaScript value "undefined".
var Undefined Object

// Debugger gets compiled to JavaScript's "debugger;" statement.
func Debugger() {}

// InternalObject returns the internal JavaScript object that represents i. Not intended for public use.
func InternalObject(i interface{}) Object {
	return nil
}

// Keys returns the keys of the given JavaScript object.
func Keys(o Object) []string {
	if o == Undefined || o == nil {
		return nil
	}
	a := Global.Get("Object").Call("keys", o)
	s := make([]string, a.Length())
	for i := 0; i < a.Length(); i++ {
		s[i] = a.Index(i).String()
	}
	return s
}

// MakeWrapper creates a JavaScript object which has wrappers for the type's exported methods. This can be used to provide getter and setter methods for Go fields to JavaScript.
func MakeWrapper(i interface{}) Object {
	v := InternalObject(i)
	o := Global.Get("Object").New()
	methods := v.Get("constructor").Get("methods")
	for i := 0; i < methods.Length(); i++ {
		m := methods.Index(i)
		if m.Index(2).String() != "" { // not exported
			continue
		}
		o.Set(m.Index(1).String(), func(args ...Any) Object {
			return v.Call(m.Index(0).String(), args...)
		})
	}
	return o
}

// M is a simple map type. It is intended as a shorthand for JavaScript objects (before conversion).
type M map[string]Any

// S is a simple slice type. It is intended as a shorthand for JavaScript arrays (before conversion).
type S []Any

func init() {
	// avoid dead code elimination
	e := Error{}
	n := DOMNode{}
	_, _ = e, n
}
<commit_msg>small doc improvement<commit_after>// Package js provides functions for interacting with native JavaScript APIs. Calls to these functions are treated specially by GopherJS and translated directly to their corresponding JavaScript syntax.
// The types Object and Any are containers for JavaScript objects and are no real citizens of the Go world, e.g. they do not implement interface{} and you cannot type assert them. The type Any may also contain Go values, but it provides no methods for accessing its content. It is only useful for passing it to functions of this package. The relation between interface{} (Go world), Object (JS world) and Any looks like this:
//
//  +------------------------------------+
//  |                                    |
//  |  +-------------+  +-------------+  |
//  |  |             |  |             |  |
//  |  | interface{} |  |  js.Object  |  |
//  |  |             |  |             |  |
//  |  +-------------+  +-------------+  |
//  |                                    |
//  |               js.Any               |
//  |                                    |
//  +------------------------------------+
//
// Type conversions between Go types and JavaScript types are performed automatically according to the following table:
//
//  | Go type                        | Conversions to interface{} | JavaScript type   |
//  | ------------------------------ | -------------------------- | ----------------- |
//  | bool                           | bool                       | Boolean           |
//  | int?, uint?, float?            | float64                    | Number            |
//  | string                         | string                     | String            |
//  | [?]int8                        | []int8                     | Int8Array         |
//  | [?]int16                       | []int16                    | Int16Array        |
//  | [?]int32, [?]int               | []int                      | Int32Array        |
//  | [?]uint8                       | []uint8                    | Uint8Array        |
//  | [?]uint16                      | []uint16                   | Uint16Array       |
//  | [?]uint32, [?]uint, [?]uintptr | []uint                     | Uint32Array       |
//  | [?]float32                     | []float32                  | Float32Array      |
//  | [?]float64                     | []float64                  | Float64Array      |
//  | all other slices and arrays    | []interface{}              | Array             |
//  | functions                      | func(...js.Any) js.Object  | Function          |
//  | time.Time                      | time.Time                  | Date              |
//  | -                              | *js.DOMNode                | instanceof Node   |
//  | maps, structs                  | map[string]interface{}     | instanceof Object |
//
package js

// Object is a container for a native JavaScript object. Calls to its methods are treated specially by GopherJS and translated directly to their JavaScript syntax. Nil is equal to JavaScript's "null".
// Object can not be used as a map key and it can only be converted to Any, but no other interface type, including interface{}. This means that you can't pass an Object obj to fmt.Println(obj), but using the println(obj) built-in is possible.
type Object interface {

	// Get returns the object's property with the given key.
	Get(key string) Object

	// Set assigns the value to the object's property with the given key.
	Set(key string, value Any)

	// Delete removes the object's property with the given key.
	Delete(key string)

	// Get returns the object's "length" property, converted to int.
	Length() int

	// Index returns the i'th element of an array.
	Index(i int) Object

	// SetIndex sets the i'th element of an array.
	SetIndex(i int, value Any)

	// Call calls the object's method with the given name.
	Call(name string, args ...Any) Object

	// Invoke calls the object itself. This will fail if it is not a function.
	Invoke(args ...Any) Object

	// New creates a new instance of this type object. This will fail if it not a function (constructor).
	New(args ...Any) Object

	// Bool returns the object converted to bool according to JavaScript type conversions.
	Bool() bool

	// String returns the object converted to string according to JavaScript type conversions.
	String() string

	// Int returns the object converted to int according to JavaScript type conversions (parseInt).
	Int() int

	// Int64 returns the object converted to int64 according to JavaScript type conversions (parseInt).
	Int64() int64

	// Uint64 returns the object converted to uint64 according to JavaScript type conversions (parseInt).
	Uint64() uint64

	// Float returns the object converted to float64 according to JavaScript type conversions (parseFloat).
	Float() float64

	// Interface returns the object converted to interface{}. See GopherJS' README for details.
	Interface() interface{}

	// Unsafe returns the object as an uintptr, which can be converted via unsafe.Pointer. Not intended for public use.
	Unsafe() uintptr
}

// Any may contain a JavaScript object or some Go value. Any can not be used as a map key and it can not be converted to some other interface type, including interface{}.
type Any interface{}

// DOMNode is used for encapsulating DOM nodes in a proper Go value. It is not feasible to convert a DOM node into a map[string]interface{}.
type DOMNode struct {
	Object
}

// Error encapsulates JavaScript errors. Those are turned into a Go panic and may be rescued, giving an *Error that holds the JavaScript error object.
type Error struct {
	Object
}

// Error returns the message of the encapsulated JavaScript error object.
func (err *Error) Error() string {
	return "JavaScript error: " + err.Get("message").String()
}

// Stack returns the stack property of the encapsulated JavaScript error object.
func (err *Error) Stack() string {
	return err.Get("stack").String()
}

// Global gives JavaScript's global object ("window" for browsers and "GLOBAL" for Node.js). Set this to a mock for testing with pure Go.
var Global Object

// This gives the value of JavaScript's "this" keyword. It can be used when passing Go functions to JavaScript as callbacks. Set this to a mock for testing with pure Go.
var This Object

// Arguments gives the value of JavaScript's "arguments" keyword. It can be used when passing Go functions to JavaScript as callbacks. Set this to a mock for testing with pure Go.
var Arguments []Object

// Module gives the value of the "module" variable set by Node.js. Hint: Set a module export with 'js.Module.Get("exports").Set("exportName", ...)'.
var Module Object

// Undefined gives the JavaScript value "undefined".
var Undefined Object

// Debugger gets compiled to JavaScript's "debugger;" statement.
func Debugger() {}

// InternalObject returns the internal JavaScript object that represents i. Not intended for public use.
func InternalObject(i interface{}) Object {
	return nil
}

// Keys returns the keys of the given JavaScript object.
func Keys(o Object) []string {
	if o == Undefined || o == nil {
		return nil
	}
	a := Global.Get("Object").Call("keys", o)
	s := make([]string, a.Length())
	for i := 0; i < a.Length(); i++ {
		s[i] = a.Index(i).String()
	}
	return s
}

// MakeWrapper creates a JavaScript object which has wrappers for the exported methods of i. This can be used to provide getter and setter methods for Go fields to JavaScript.
func MakeWrapper(i interface{}) Object {
	v := InternalObject(i)
	o := Global.Get("Object").New()
	methods := v.Get("constructor").Get("methods")
	for i := 0; i < methods.Length(); i++ {
		m := methods.Index(i)
		if m.Index(2).String() != "" { // not exported
			continue
		}
		o.Set(m.Index(1).String(), func(args ...Any) Object {
			return v.Call(m.Index(0).String(), args...)
		})
	}
	return o
}

// M is a simple map type. It is intended as a shorthand for JavaScript objects (before conversion).
type M map[string]Any

// S is a simple slice type. It is intended as a shorthand for JavaScript arrays (before conversion).
type S []Any

func init() {
	// avoid dead code elimination
	e := Error{}
	n := DOMNode{}
	_, _ = e, n
}
<|endoftext|>


<commit_before>// godbs project godbs.go
package godbs

import (
	"bytes"
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/tealeg/xlsx"

	//_ "github.com/mattn/go-oci8"
	//_ "github.com/mattn/go-sqlite3"
)

func (this *GoDBS) opendb(driver, dsn string, maxOpen, maxIdle int) error {
	ctx, _ := context.WithTimeout(context.Background(), 30*time.Second)

	var err error
	this.db, err = sql.Open(driver, dsn)
	if err != nil {
		return err
	}

	this.db.SetMaxOpenConns(maxOpen)
	this.db.SetMaxIdleConns(maxIdle)

	err = this.db.Ping()
	if err != nil {
		return err
	}

	select {
	case <-ctx.Done():
		return ctx.Err()
	default:
	}
	return nil
}

func (this *GoDBS) Query(timeout time.Duration, query string, args ...interface{}) (*sql.Rows, error) {
	ctx, _ := context.WithTimeout(context.Background(), timeout*time.Second)

	rows, err := this.db.Query(query, args...)
	//rows, err := td.mydb.Query(query)
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}
	return rows, err
}

func (this *GoDBS) Exec(timeout time.Duration, strsql string, args ...interface{}) (RowsAffected int64, ok bool) {
	ctx, _ := context.WithTimeout(context.Background(), timeout*time.Second)

	rst, err := this.db.Exec(strsql, args...)
	if err != nil {
		return 0, false
	}

	rowCount, err := rst.RowsAffected()
	if err != nil {
		return -1, false
	}

	select {
	case <-ctx.Done():
		return -2, false
	default:
	}
	return rowCount, true
}

func (this *GoDBS) Query2Json(timeout time.Duration, buf *bytes.Buffer, query string, args ...interface{}) error {
	ctx, _ := context.WithTimeout(context.Background(), timeout*time.Second)
	rows, err := this.db.Query(query, args...)
	if err != nil {
		return err
	}
	defer rows.Close()
	buf.Reset()

	columns, err := rows.Columns()
	if err != nil {
		return err
	}

	//fix bug time.Time nil
	//values := make([]sql.RawBytes, len(columns))
	values := make([]sql.NullString, len(columns))
	scans := make([]interface{}, len(columns))

	for i := range values {
		scans[i] = &values[i]
	}

	type Jitem struct {
		Item string `json:"e"`
	}
	var jitem Jitem
	buf.WriteByte('[')

	for rows.Next() {
		err = rows.Scan(scans...)
		if err != nil {
			fmt.Println(err.Error())
			return err
		}

		buf.WriteByte('{')
		for i, col := range values {
			jitem.Item = col.String
			bs, _ := json.Marshal(&jitem)
			buf.WriteString(fmt.Sprintf(`"%v":"%v",`, columns[i], string(bs[6:len(bs)-2])))
		}

		buf.Bytes()[buf.Len()-1] = '}'
		buf.WriteByte(',')
	}

	if buf.Len() > 1 {
		buf.Bytes()[buf.Len()-1] = ']'
	} else {
		buf.WriteByte(']')
	}

	select {
	case <-ctx.Done():
		return ctx.Err()
	default:
	}
	return nil
}

func (td *GoDBS) addRow2Sheet(s *xlsx.Sheet, args ...string) {
	row := s.AddRow()
	cell := row.AddCell()
	cell.Value = ""

	for _, v := range args {
		cell := row.AddCell()
		cell.Value = v
	}
}

func (this *GoDBS) Query2Xlsx(timeout time.Duration, buf *bytes.Buffer, query string, args ...interface{}) error {
	ctx, _ := context.WithTimeout(context.Background(), timeout*time.Second)
	rows, err := this.db.Query(query, args...)
	if err != nil {
		return err
	}
	defer rows.Close()
	buf.Reset()

	f := xlsx.NewFile()
	sheet, err := f.AddSheet("Sheet1")
	if err != nil {
		return err
	}

	columns, err := rows.Columns()
	if err != nil {
		return err
	}
	this.addRow2Sheet(sheet, columns[0:]...)

	values := make([]sql.NullString, len(columns))
	scans := make([]interface{}, len(columns))
	cv := make([]string, len(columns))

	for i := range values {
		scans[i] = &values[i]
	}

	for rows.Next() {
		err = rows.Scan(scans...)
		if err != nil {
			return err
		}

		for i, col := range values {
			cv[i] = col.String
		}
		this.addRow2Sheet(sheet, cv[0:]...)
	}

	if err != nil {
		return err
	}

	err = f.Write(buf)

	select {
	case <-ctx.Done():
		return ctx.Err()
	default:
	}
	return err
}

func (this *GoDBS) initService() {
	strSql := `
		CREATE TABLE IF NOT EXISTS godbs
		(
			sn			VARCHAR(64)		PRIMARY KEY NOT NULL,
    		content		VARCHAR(4096) 	NOT NULL,
			name		VARCHAR(128) 	DEFAULT NULL,
    		create_time	TIMESTAMP		NOT NULL DEFAULT CURRENT_TIMESTAMP
		);`

	this.Exec(30, strSql)
	this.Exec(30, `insert into godbs (sn,content,name) values('test','select * from information_schema.columns where table_name=''#tn#'' ','测试')`)
}

func (this *GoDBS) loadService() {
	strSql := "select sn,content from godbs"
	rows, err := this.Query(10, strSql)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer rows.Close()

	strSN, strContent := "", ""
	for rows.Next() {
		err = rows.Scan(&strSN, &strContent)
		if err != nil {
			fmt.Println(err.Error())
			return
		}
		this.mapService.Store(strings.ToLower(strSN), strContent)
	}
}
<commit_msg>fix code<commit_after>// godbs project godbs.go
package godbs

import (
	"bytes"
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/tealeg/xlsx"

	//_ "github.com/mattn/go-oci8"
	//_ "github.com/mattn/go-sqlite3"
)

func (this *GoDBS) opendb(driver, dsn string, maxOpen, maxIdle int) error {
	ctx, _ := context.WithTimeout(context.Background(), 30*time.Second)

	var err error
	this.db, err = sql.Open(driver, dsn)
	if err != nil {
		return err
	}

	this.db.SetMaxOpenConns(maxOpen)
	this.db.SetMaxIdleConns(maxIdle)

	err = this.db.Ping()
	if err != nil {
		return err
	}

	select {
	case <-ctx.Done():
		return ctx.Err()
	default:
	}
	return nil
}

func (this *GoDBS) Query(timeout time.Duration, query string, args ...interface{}) (*sql.Rows, error) {
	ctx, _ := context.WithTimeout(context.Background(), timeout*time.Second)

	rows, err := this.db.Query(query, args...)
	//rows, err := td.mydb.Query(query)
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}
	return rows, err
}

func (this *GoDBS) Exec(timeout time.Duration, strsql string, args ...interface{}) (RowsAffected int64, ok bool) {
	ctx, _ := context.WithTimeout(context.Background(), timeout*time.Second)

	rst, err := this.db.Exec(strsql, args...)
	if err != nil {
		return 0, false
	}

	rowCount, err := rst.RowsAffected()
	if err != nil {
		return -1, false
	}

	select {
	case <-ctx.Done():
		return -2, false
	default:
	}
	return rowCount, true
}

func (this *GoDBS) Query2Json(timeout time.Duration, outBuf *bytes.Buffer, query string, args ...interface{}) error {
	ctx, _ := context.WithTimeout(context.Background(), timeout*time.Second)
	rows, err := this.db.Query(query, args...)
	if err != nil {
		return err
	}
	defer rows.Close()
	outBuf.Reset()

	columns, err := rows.Columns()
	if err != nil {
		return err
	}

	//fix bug time.Time nil
	//values := make([]sql.RawBytes, len(columns))
	values := make([]sql.NullString, len(columns))
	scans := make([]interface{}, len(columns))

	for i := range values {
		scans[i] = &values[i]
	}

	type Jitem struct {
		Item string `json:"e"`
	}
	var jitem Jitem
	outBuf.WriteByte('[')

	for rows.Next() {
		err = rows.Scan(scans...)
		if err != nil {
			fmt.Println(err.Error())
			return err
		}

		outBuf.WriteByte('{')
		for i, col := range values {
			jitem.Item = col.String
			bs, _ := json.Marshal(&jitem)
			outBuf.WriteString(fmt.Sprintf(`"%v":"%v",`, columns[i], string(bs[6:len(bs)-2])))
		}

		outBuf.Bytes()[outBuf.Len()-1] = '}'
		outBuf.WriteByte(',')
	}

	if outBuf.Len() > 1 {
		outBuf.Bytes()[outBuf.Len()-1] = ']'
	} else {
		outBuf.WriteByte(']')
	}

	select {
	case <-ctx.Done():
		return ctx.Err()
	default:
	}
	return nil
}

func (td *GoDBS) addRow2Sheet(s *xlsx.Sheet, args ...string) {
	row := s.AddRow()
	cell := row.AddCell()
	cell.Value = ""

	for _, v := range args {
		cell := row.AddCell()
		cell.Value = v
	}
}

func (this *GoDBS) Query2Xlsx(timeout time.Duration, outBuf *bytes.Buffer, query string, args ...interface{}) error {
	ctx, _ := context.WithTimeout(context.Background(), timeout*time.Second)
	rows, err := this.db.Query(query, args...)
	if err != nil {
		return err
	}
	defer rows.Close()
	outBuf.Reset()

	f := xlsx.NewFile()
	sheet, err := f.AddSheet("Sheet1")
	if err != nil {
		return err
	}

	columns, err := rows.Columns()
	if err != nil {
		return err
	}
	this.addRow2Sheet(sheet, columns[0:]...)

	values := make([]sql.NullString, len(columns))
	scans := make([]interface{}, len(columns))
	cv := make([]string, len(columns))

	for i := range values {
		scans[i] = &values[i]
	}

	for rows.Next() {
		err = rows.Scan(scans...)
		if err != nil {
			return err
		}

		for i, col := range values {
			cv[i] = col.String
		}
		this.addRow2Sheet(sheet, cv[0:]...)
	}

	if err != nil {
		return err
	}

	err = f.Write(outBuf)

	select {
	case <-ctx.Done():
		return ctx.Err()
	default:
	}
	return err
}

func (this *GoDBS) initService() {
	strSql := `
		CREATE TABLE IF NOT EXISTS godbs
		(
			sn			VARCHAR(64)		PRIMARY KEY NOT NULL,
    		content		VARCHAR(4096) 	NOT NULL,
			name		VARCHAR(128) 	DEFAULT NULL,
    		create_time	TIMESTAMP		NOT NULL DEFAULT CURRENT_TIMESTAMP
		);`

	this.Exec(30, strSql)
	this.Exec(30, `insert into godbs (sn,content,name) values('test','select * from information_schema.columns where table_name=''#tn#'' ','测试')`)
}

func (this *GoDBS) loadService() {
	strSql := "select sn,content from godbs"
	rows, err := this.Query(10, strSql)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer rows.Close()

	strSN, strContent := "", ""
	for rows.Next() {
		err = rows.Scan(&strSN, &strContent)
		if err != nil {
			fmt.Println(err.Error())
			return
		}
		this.mapService.Store(strings.ToLower(strSN), strContent)
	}
}
<|endoftext|>


<commit_before>package junos

import (
	"fmt"
	"github.com/Juniper/go-netconf/netconf"
	"log"
)

type Session struct {
	Conn *netconf.Session
}

func NewSession(host, user, password string) *Session {
    s, err := netconf.DialSSH(host, netconf.SSHConfigPassword(user, password))
    if err != nil {
        log.Fatal(err)
    }

    return &Session{
        Conn: s,
    }
}

func (s *Session) Lock() {
	resp, err := s.Conn.Exec("<rpc><lock><target><candidate/></target></lock></rpc>")
	if err != nil {
		fmt.Printf("Error: %+v\n", err)
	}

    fmt.Println(resp)
}

func (s *Session) Unlock() {
	resp, err := s.Conn.Exec("<rpc><unlock><target><candidate/></target></unlock></rpc>")
	if err != nil {
		fmt.Printf("Error: %+v\n", err)
	}

    fmt.Println(resp)
}

func (s *Session) Close() {
    s.Conn.Close()
}<commit_msg>Testing functions<commit_after>package junos

import (
	"fmt"
	"github.com/Juniper/go-netconf/netconf"
	"log"
)

type Session struct {
	Conn *netconf.Session
}

func NewSession(host, user, password string) *Session {
    s, err := netconf.DialSSH(host, netconf.SSHConfigPassword(user, password))
    if err != nil {
        log.Fatal(err)
    }

    return &Session{
        Conn: s,
    }
}

func (s *Session) Lock() {
	resp, err := s.Conn.Exec("<rpc><lock><target><candidate/></target></lock></rpc>")
	if err != nil {
		fmt.Printf("Error: %+v\n", err)
	}

    fmt.Println(resp.Data)
}

func (s *Session) Unlock() {
	resp, err := s.Conn.Exec("<rpc><unlock><target><candidate/></target></unlock></rpc>")
	if err != nil {
		fmt.Printf("Error: %+v\n", err)
	}

    fmt.Println(resp.Data)
}

func (s *Session) Close() {
    s.Conn.Close()
}<|endoftext|>


<commit_before><commit_msg>Expect(len(X)).To(Equal(Y))” to “Expect(X).To(HaveLen(Y))<commit_after><|endoftext|>