Skip to content

Commit

Permalink
Import code from github.com/lestrrat-go/jwx
Browse files Browse the repository at this point in the history
  • Loading branch information
lestrrat committed Apr 2, 2021
1 parent 4e3f45c commit 370527f
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 1 deletion.
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: CI
on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
go: [ '1.15', '1.16' ]
name: Go ${{ matrix.go }} test
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Go stable version
if: matrix.go != 'tip'
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go }}
- name: Install Go tip
if: matrix.go == 'tip'
run: |
git clone --depth=1 https://go.googlesource.com/go $HOME/gotip
cd $HOME/gotip/src
./make.bash
echo "::set-env name=GOROOT::$HOME/gotip"
echo "::add-path::$HOME/gotip/bin"
echo "::add-path::$(go env GOPATH)/bin"
- name: Test
run: go test -v -race ./...
- name: Upload code coverage to codecov
if: matrix.go == '1.16'
uses: codecov/codecov-action@v1
with:
file: ./coverage.out

11 changes: 11 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: lint
on: [push, pull_request]
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: golangci/golangci-lint-action@v2
with:
version: v1.39.0
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# blackmagic
Reflect-based black magic

Reflect-based black magic. YMMV, and use with caution
55 changes: 55 additions & 0 deletions blackmagic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package blackmagic

import (
"reflect"

"github.com/pkg/errors"
)

// AssignIfCompatible is a convenience function to safely
// assign arbitrary values. dst must be a pointer to an
// empty interface, or it must be a pointer to a compatible
// variable type that can hold src.
func AssignIfCompatible(dst, src interface{}) error {
orv := reflect.ValueOf(src) // save this value for error reporting
result := orv

// t can be a pointer or a slice, and the code will slightly change
// depending on this
var isSlice bool
switch result.Kind() {
case reflect.Ptr:
// no op
case reflect.Slice:
isSlice = true
default:
return errors.Errorf("argument t to AssignIfCompatible must be a pointer or a slice: %T", src)
}

rv := reflect.ValueOf(dst)
if rv.Kind() != reflect.Ptr {
return errors.Errorf(`argument to AssignIfCompatible() must be a pointer: %T`, dst)
}

actualDst := rv.Elem()
switch actualDst.Kind() {
case reflect.Interface:
// If it's an interface, we can just assign the pointer to the interface{}
default:
// If it's a pointer to the struct we're looking for, we need to set
// the de-referenced struct
if !isSlice {
result = result.Elem()
}
}
if !result.Type().AssignableTo(actualDst.Type()) {
return errors.Errorf(`argument to AssignIfCompatible() must be compatible with %T (was %T)`, orv.Interface(), dst)
}

if !actualDst.CanSet() {
return errors.Errorf(`argument to AssignIfCompatible() must be settable`)
}
actualDst.Set(result)

return nil
}
61 changes: 61 additions & 0 deletions blackmagic_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package blackmagic_test

import (
"testing"

"github.com/lestrrat-go/blackmagic"
"github.com/stretchr/testify/assert"
)

func TestAssignment(t *testing.T) {
testcases := []struct {
Name string
Error bool
Value interface{}
Destination func() interface{}
}{
{
Name: `empty struct`,
Error: true,
Value: struct{}{},
Destination: func() interface{} {
var v interface{}
return &v
},
},
{
Name: `non pointer destination`,
Error: true,
Value: &struct{}{},
},
{
Name: `assign empty struct to int`,
Error: true,
Value: &struct{}{},
Destination: func() interface{} {
var v int
return &v
},
},
}

for _, tc := range testcases {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
var dst interface{}
if dstFunc := tc.Destination; dstFunc != nil {
dst = dstFunc()
}
err := blackmagic.AssignIfCompatible(dst, tc.Value)
if tc.Error {
if !assert.Error(t, err, `blackmagic.AssignIfCompatible should fail`) {
return
}
} else {
if !assert.NoError(t, err, `blackmagic.AssignIfCompatible should succeed`) {
return
}
}
})
}
}
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/lestrrat-go/blackmagic

go 1.16

require (
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.0
)
13 changes: 13 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 comments on commit 370527f

Please sign in to comment.