Skip to content

Commit

Permalink
AWS module; codec registration
Browse files Browse the repository at this point in the history
  • Loading branch information
myzie committed Jun 22, 2023
1 parent 9091265 commit 0db5098
Show file tree
Hide file tree
Showing 13 changed files with 785 additions and 43 deletions.
108 changes: 66 additions & 42 deletions builtins/codecs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,59 @@ import (
"encoding/csv"
"encoding/hex"
"encoding/json"
"errors"
"net/url"
"sort"
"sync"

"github.com/cloudcmds/tamarin/v2/internal/arg"
"github.com/cloudcmds/tamarin/v2/object"
)

var (
mutex sync.RWMutex
codecs = map[string]*Codec{}
)

// Codec contains an Encode and a Decode function
type Codec struct {
Encode func(context.Context, object.Object) object.Object
Decode func(context.Context, object.Object) object.Object
}

func init() {
RegisterCodec("base64", &Codec{Encode: encodeBase64, Decode: decodeBase64})
RegisterCodec("base32", &Codec{Encode: encodeBase32, Decode: decodeBase32})
RegisterCodec("hex", &Codec{Encode: encodeHex, Decode: decodeHex})
RegisterCodec("json", &Codec{Encode: encodeJSON, Decode: decodeJSON})
RegisterCodec("csv", &Codec{Encode: encodeCsv, Decode: decodeCsv})
RegisterCodec("urlquery", &Codec{Encode: encodeUrlQuery, Decode: decodeUrlQuery})
}

// RegisterCodec registers a new codec
func RegisterCodec(name string, codec *Codec) error {
mutex.Lock()
defer mutex.Unlock()

if _, exists := codecs[name]; exists {
return errors.New("codec already registered: " + name)
}
codecs[name] = codec
return nil
}

// GetCodec retrieves a codec by its name
func GetCodec(name string) (*Codec, error) {
mutex.RLock()
defer mutex.RUnlock()

codec, exists := codecs[name]
if !exists {
return nil, errors.New("codec not found: " + name)
}
return codec, nil
}

func Encode(ctx context.Context, args ...object.Object) object.Object {
if err := arg.Require("encode", 2, args); err != nil {
return err
Expand All @@ -23,49 +69,38 @@ func Encode(ctx context.Context, args ...object.Object) object.Object {
if err != nil {
return err
}
switch encoding {
case "base64":
return encodeBase64(args[0])
case "base32":
return encodeBase32(args[0])
case "hex":
return encodeHex(args[0])
case "json":
return encodeJSON(args[0])
case "csv":
return encodeCsv(args[0])
case "urlquery":
return encodeUrlQuery(args[0])
default:
return object.Errorf("value error: encode() does not support %q", encoding)
codec, codecErr := GetCodec(encoding)
if codecErr != nil {
return object.NewError(codecErr)
}
return codec.Encode(ctx, args[0])
}

func encodeBase64(obj object.Object) object.Object {
func encodeBase64(ctx context.Context, obj object.Object) object.Object {
data, err := object.AsBytes(obj)
if err != nil {
return err
}
return object.NewString(base64.StdEncoding.EncodeToString(data))
}

func encodeBase32(obj object.Object) object.Object {
func encodeBase32(ctx context.Context, obj object.Object) object.Object {
data, err := object.AsBytes(obj)
if err != nil {
return err
}
return object.NewString(base32.StdEncoding.EncodeToString(data))
}

func encodeHex(obj object.Object) object.Object {
func encodeHex(ctx context.Context, obj object.Object) object.Object {
data, err := object.AsBytes(obj)
if err != nil {
return err
}
return object.NewString(hex.EncodeToString(data))
}

func encodeJSON(obj object.Object) object.Object {
func encodeJSON(ctx context.Context, obj object.Object) object.Object {
nativeObject := obj.Interface()
if nativeObject == nil {
return object.Errorf("value error: encode() does not support %T", obj)
Expand All @@ -77,7 +112,7 @@ func encodeJSON(obj object.Object) object.Object {
return object.NewString(string(jsonBytes))
}

func encodeUrlQuery(obj object.Object) object.Object {
func encodeUrlQuery(ctx context.Context, obj object.Object) object.Object {
str, err := object.AsString(obj)
if err != nil {
return err
Expand Down Expand Up @@ -118,7 +153,7 @@ func csvStringListFromMap(m *object.Map, keys []string) ([]string, *object.Error
return result, nil
}

func encodeCsv(obj object.Object) object.Object {
func encodeCsv(ctx context.Context, obj object.Object) object.Object {
list, ok := obj.(*object.List)
if !ok {
return object.Errorf("type error: encode(obj, \"csv\") requires a list (got %s)", obj.Type())
Expand Down Expand Up @@ -175,25 +210,14 @@ func Decode(ctx context.Context, args ...object.Object) object.Object {
if err != nil {
return err
}
switch encoding {
case "base64":
return decodeBase64(args[0])
case "base32":
return decodeBase32(args[0])
case "hex":
return decodeHex(args[0])
case "json":
return decodeJSON(args[0])
case "csv":
return decodeCsv(args[0])
case "urlquery":
return decodeUrlQuery(args[0])
default:
return object.Errorf("value error: decode() does not support %q", encoding)
codec, codecErr := GetCodec(encoding)
if codecErr != nil {
return object.NewError(codecErr)
}
return codec.Decode(ctx, args[0])
}

func decodeBase64(obj object.Object) object.Object {
func decodeBase64(ctx context.Context, obj object.Object) object.Object {
data, err := object.AsBytes(obj)
if err != nil {
return err
Expand All @@ -207,7 +231,7 @@ func decodeBase64(obj object.Object) object.Object {
return object.NewBSlice(dst[:count])
}

func decodeBase32(obj object.Object) object.Object {
func decodeBase32(ctx context.Context, obj object.Object) object.Object {
data, err := object.AsBytes(obj)
if err != nil {
return err
Expand All @@ -221,7 +245,7 @@ func decodeBase32(obj object.Object) object.Object {
return object.NewBSlice(dst[:count])
}

func decodeHex(obj object.Object) object.Object {
func decodeHex(ctx context.Context, obj object.Object) object.Object {
data, err := object.AsBytes(obj)
if err != nil {
return err
Expand All @@ -234,7 +258,7 @@ func decodeHex(obj object.Object) object.Object {
return object.NewBSlice(dst[:count])
}

func decodeJSON(obj object.Object) object.Object {
func decodeJSON(ctx context.Context, obj object.Object) object.Object {
data, err := object.AsBytes(obj)
if err != nil {
return err
Expand All @@ -246,7 +270,7 @@ func decodeJSON(obj object.Object) object.Object {
return object.FromGoType(result)
}

func decodeCsv(obj object.Object) object.Object {
func decodeCsv(ctx context.Context, obj object.Object) object.Object {
data, err := object.AsBytes(obj)
if err != nil {
return err
Expand All @@ -268,7 +292,7 @@ func decodeCsv(obj object.Object) object.Object {
}

// decodeUrlQuery wraps url.QueryUnescape
func decodeUrlQuery(obj object.Object) object.Object {
func decodeUrlQuery(ctx context.Context, obj object.Object) object.Object {
data, err := object.AsString(obj)
if err != nil {
return err
Expand Down
44 changes: 44 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,34 @@ go 1.19
require (
atomicgo.dev/keyboard v0.2.8
github.com/anthonynsimon/bild v0.13.0
github.com/aws/aws-sdk-go-v2 v1.18.1
github.com/aws/aws-sdk-go-v2/config v1.18.27
github.com/aws/aws-sdk-go-v2/credentials v1.13.26
github.com/aws/aws-sdk-go-v2/service/cloudformation v1.30.0
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.26.8
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.27.1
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.26.2
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.19.10
github.com/aws/aws-sdk-go-v2/service/ebs v1.16.14
github.com/aws/aws-sdk-go-v2/service/ec2 v1.101.0
github.com/aws/aws-sdk-go-v2/service/ecr v1.18.13
github.com/aws/aws-sdk-go-v2/service/ecs v1.27.4
github.com/aws/aws-sdk-go-v2/service/eks v1.27.14
github.com/aws/aws-sdk-go-v2/service/elasticache v1.27.2
github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.19.2
github.com/aws/aws-sdk-go-v2/service/glue v1.51.0
github.com/aws/aws-sdk-go-v2/service/iam v1.20.3
github.com/aws/aws-sdk-go-v2/service/kinesis v1.17.14
github.com/aws/aws-sdk-go-v2/service/kms v1.22.2
github.com/aws/aws-sdk-go-v2/service/lambda v1.35.2
github.com/aws/aws-sdk-go-v2/service/rds v1.45.2
github.com/aws/aws-sdk-go-v2/service/redshift v1.27.13
github.com/aws/aws-sdk-go-v2/service/route53 v1.28.3
github.com/aws/aws-sdk-go-v2/service/s3 v1.35.0
github.com/aws/aws-sdk-go-v2/service/sfn v1.17.13
github.com/aws/aws-sdk-go-v2/service/sns v1.20.13
github.com/aws/aws-sdk-go-v2/service/sqs v1.23.2
github.com/aws/aws-sdk-go-v2/service/wafv2 v1.35.1
github.com/fatih/color v1.13.0
github.com/gofrs/uuid v4.3.1+incompatible
github.com/hashicorp/go-multierror v1.1.1
Expand All @@ -15,11 +43,27 @@ require (
)

require (
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.28 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 // indirect
github.com/aws/smithy-go v1.13.5 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
Expand Down
Loading

0 comments on commit 0db5098

Please sign in to comment.