From 3f746398a502d947c6e4fc30469964ad2f9efdc1 Mon Sep 17 00:00:00 2001 From: Raed Shomali Date: Sun, 19 Nov 2023 00:06:32 -0500 Subject: [PATCH] Proper --- README.md | 34 ++++++++++++++++++++++++ examples/example.go | 22 ++++++++++++++++ go.mod | 11 ++++++++ go.sum | 10 +++++++ properties.go | 64 +++++++++++++++++++++++++++++++++++++++++++++ properties_test.go | 62 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 203 insertions(+) create mode 100644 README.md create mode 100644 examples/example.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 properties.go create mode 100644 properties_test.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..46c5c19 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# proper [![Build Status](https://travis-ci.com/slack-io/proper.svg?branch=master)](https://travis-ci.com/slack-io/proper) [![Go Report Card](https://goreportcard.com/badge/github.com/slack-io/proper)](https://goreportcard.com/report/github.com/slack-io/proper) [![GoDoc](https://godoc.org/github.com/slack-io/proper?status.svg)](https://godoc.org/github.com/slack-io/proper) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +A `map[string]string` decorator offering a collection of helpful functions to extract the values in different types + +## Features + +* Retrieve data from a string map, in String, Integer, Float and Boolean types. +* Return a default value in case of missing keys or invalid types + +# Examples + +```go +package main + +import ( + "fmt" + "github.com/slack-io/proper" +) + +func main() { + parameters := make(map[string]string) + parameters["boolean"] = "true" + parameters["float"] = "1.2" + parameters["integer"] = "11" + parameters["string"] = "value" + + properties := proper.NewProperties(parameters) + + fmt.Println(properties.BooleanParam("boolean", false)) // true + fmt.Println(properties.FloatParam("float", 0)) // 1.2 + fmt.Println(properties.IntegerParam("integer", 0)) // 11 + fmt.Println(properties.StringParam("string", "")) // value +} +``` \ No newline at end of file diff --git a/examples/example.go b/examples/example.go new file mode 100644 index 0000000..5814e82 --- /dev/null +++ b/examples/example.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + + "github.com/slack-io/proper" +) + +func main() { + parameters := make(map[string]string) + parameters["boolean"] = "true" + parameters["float"] = "1.2" + parameters["integer"] = "11" + parameters["string"] = "value" + + properties := proper.NewProperties(parameters) + + fmt.Println(properties.BooleanParam("boolean", false)) + fmt.Println(properties.FloatParam("float", 0)) + fmt.Println(properties.IntegerParam("integer", 0)) + fmt.Println(properties.StringParam("string", "")) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3c70377 --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module github.com/slack-io/proper + +go 1.21.4 + +require github.com/stretchr/testify v1.8.4 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..fa4b6e6 --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/properties.go b/properties.go new file mode 100644 index 0000000..f287890 --- /dev/null +++ b/properties.go @@ -0,0 +1,64 @@ +package proper + +import "strconv" + +// NewProperties creates a new Properties object +func NewProperties(m map[string]string) *Properties { + return &Properties{propertyMap: m} +} + +// Properties is a string map decorator +type Properties struct { + propertyMap map[string]string +} + +// StringParam attempts to look up a string value by key. If not found, return the default string value +func (p *Properties) StringParam(key string, defaultValue string) string { + value, ok := p.propertyMap[key] + if !ok { + return defaultValue + } + return value +} + +// BooleanParam attempts to look up a boolean value by key. If not found, return the default boolean value +func (p *Properties) BooleanParam(key string, defaultValue bool) bool { + value, ok := p.propertyMap[key] + if !ok { + return defaultValue + } + + integerValue, err := strconv.ParseBool(value) + if err != nil { + return defaultValue + } + return integerValue +} + +// IntegerParam attempts to look up a integer value by key. If not found, return the default integer value +func (p *Properties) IntegerParam(key string, defaultValue int) int { + value, ok := p.propertyMap[key] + if !ok { + return defaultValue + } + + integerValue, err := strconv.Atoi(value) + if err != nil { + return defaultValue + } + return integerValue +} + +// FloatParam attempts to look up a float value by key. If not found, return the default float value +func (p *Properties) FloatParam(key string, defaultValue float64) float64 { + value, ok := p.propertyMap[key] + if !ok { + return defaultValue + } + + integerValue, err := strconv.ParseFloat(value, 64) + if err != nil { + return defaultValue + } + return integerValue +} diff --git a/properties_test.go b/properties_test.go new file mode 100644 index 0000000..fe22bb5 --- /dev/null +++ b/properties_test.go @@ -0,0 +1,62 @@ +package proper + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestBooleanParam(t *testing.T) { + parameters := make(map[string]string) + parameters["boolean"] = "true" + parameters["integer"] = "1" + parameters["bad"] = "bad" + + emptyProperties := &Properties{} + properties := NewProperties(parameters) + + assert.Equal(t, emptyProperties.BooleanParam("boolean", false), false) + assert.Equal(t, properties.BooleanParam("boolean", false), true) + assert.Equal(t, properties.BooleanParam("integer", false), true) + assert.Equal(t, properties.BooleanParam("bad", false), false) +} + +func TestFloatParam(t *testing.T) { + parameters := make(map[string]string) + parameters["integer"] = "11" + parameters["float"] = "1.2" + parameters["bad"] = "bad" + + emptyProperties := &Properties{} + properties := NewProperties(parameters) + + assert.Equal(t, emptyProperties.FloatParam("float", 0), float64(0)) + assert.Equal(t, properties.FloatParam("integer", 0), float64(11)) + assert.Equal(t, properties.FloatParam("float", 0), float64(1.2)) + assert.Equal(t, properties.FloatParam("bad", 0), float64(0)) +} + +func TestIntegerParam(t *testing.T) { + parameters := make(map[string]string) + parameters["integer"] = "11" + parameters["float"] = "1.2" + parameters["bad"] = "bad" + + emptyProperties := &Properties{} + properties := NewProperties(parameters) + + assert.Equal(t, emptyProperties.IntegerParam("integer", 0), 0) + assert.Equal(t, properties.IntegerParam("integer", 0), 11) + assert.Equal(t, properties.IntegerParam("float", 0), 0) + assert.Equal(t, properties.IntegerParam("bad", 0), 0) +} + +func TestStringParam(t *testing.T) { + parameters := make(map[string]string) + parameters["string"] = "value" + + emptyProperties := &Properties{} + properties := NewProperties(parameters) + + assert.Equal(t, emptyProperties.StringParam("string", ""), "") + assert.Equal(t, properties.StringParam("string", ""), "value") +}