Skip to content

Commit

Permalink
minor changes in as package
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonWaldherr committed Jul 23, 2024
1 parent 9489af9 commit 06dd220
Show file tree
Hide file tree
Showing 2 changed files with 287 additions and 0 deletions.
103 changes: 103 additions & 0 deletions as/as.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
package as

import (
"encoding/json"
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -490,3 +492,104 @@ func DBTypeMultiple(val []string) string {
}
return regex[typeint].typ
}

// HexToRGB converts a hex color string to its RGB components.
func HexToRGB(hex string) (int, int, int, error) {
hex = strings.TrimPrefix(hex, "#")
if len(hex) != 6 {
return 0, 0, 0, fmt.Errorf("invalid hex color length")
}
r, err := strconv.ParseInt(hex[0:2], 16, 64)
if err != nil {
return 0, 0, 0, err
}
g, err := strconv.ParseInt(hex[2:4], 16, 64)
if err != nil {
return 0, 0, 0, err
}
b, err := strconv.ParseInt(hex[4:6], 16, 64)
if err != nil {
return 0, 0, 0, err
}
return int(r), int(g), int(b), nil
}

// RGBToHex converts RGB components to a hex color string.
func RGBToHex(r, g, b int) string {
return fmt.Sprintf("#%02x%02x%02x", r, g, b)
}

// MapToStruct converts a map to a struct based on the given struct type.
func MapToStruct(m map[string]interface{}, result interface{}) error {
for k, v := range m {
structValue := reflect.ValueOf(result).Elem()
structFieldValue := structValue.FieldByName(strings.Title(k))
if !structFieldValue.IsValid() {
continue
}
if !structFieldValue.CanSet() {
continue
}
val := reflect.ValueOf(v)
if structFieldValue.Type() != val.Type() {
return fmt.Errorf("provided value type didn't match struct field type")
}
structFieldValue.Set(val)
}
return nil
}

// StructToMap converts a struct to a map.
func StructToMap(input interface{}) map[string]interface{} {
output := make(map[string]interface{})
val := reflect.ValueOf(input)
typ := reflect.TypeOf(input)
for i := 0; i < val.NumField(); i++ {
output[typ.Field(i).Name] = val.Field(i).Interface()
}
return output
}

// IsEmailValid validates an email address using a regex.
func IsEmailValid(email string) bool {
re := regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,}$`)
return re.MatchString(email)
}

// IsURLValid validates a URL using a regex.
func IsURLValid(url string) bool {
re := regexp.MustCompile(`^(https?://)?([a-z0-9.-]+)\.([a-z.]{2,6})([/\w .-]*)*/?$`)
return re.MatchString(url)
}

// IsCreditCardValid validates a credit card number using the Luhn algorithm.
func IsCreditCardValid(cardNumber string) bool {
var sum int
alt := false
for i := len(cardNumber) - 1; i > -1; i-- {
n, _ := strconv.Atoi(string(cardNumber[i]))
if alt {
n *= 2
if n > 9 {
n -= 9
}
}
sum += n
alt = !alt
}
return sum%10 == 0
}

// ToJSON converts a Go value to a JSON string.
func ToJSON(value interface{}) (string, error) {
jsonBytes, err := json.Marshal(value)
if err != nil {
return "", err
}
return string(jsonBytes), nil
}

// FromJSON converts a JSON string to a Go value.
func FromJSON(jsonStr string, result interface{}) error {
return json.Unmarshal([]byte(jsonStr), result)
}
184 changes: 184 additions & 0 deletions as/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,187 @@ func ExampleType_json() {
// email: [email protected]
// price: 15€
}

func ExampleHexToRGB() {
values := []string{"#ff5733", "#00ff00", "#0000ff", "123456"}

fmt.Println("as.HexToRGB()")
for _, v := range values {
r, g, b, err := as.HexToRGB(v)
if err != nil {
fmt.Printf("%v => error: %v\n", v, err)
} else {
fmt.Printf("%v => R: %d, G: %d, B: %d\n", v, r, g, b)
}
}

// Output:
// as.HexToRGB()
// #ff5733 => R: 255, G: 87, B: 51
// #00ff00 => R: 0, G: 255, B: 0
// #0000ff => R: 0, G: 0, B: 255
// 123456 => R: 18, G: 52, B: 86
}

func ExampleRGBToHex() {
values := [][]int{{255, 87, 51}, {0, 255, 0}, {0, 0, 255}}

fmt.Println("as.RGBToHex()")
for _, v := range values {
hex := as.RGBToHex(v[0], v[1], v[2])
fmt.Printf("R: %d, G: %d, B: %d => %v\n", v[0], v[1], v[2], hex)
}

// Output:
// as.RGBToHex()
// R: 255, G: 87, B: 51 => #ff5733
// R: 0, G: 255, B: 0 => #00ff00
// R: 0, G: 0, B: 255 => #0000ff
}

func ExampleMapToStruct() {
type Person struct {
Name string
Age int
}

values := []map[string]interface{}{
{"Name": "Alice", "Age": 30},
{"Name": "Bob", "Age": 25},
}

fmt.Println("as.MapToStruct()")
for _, v := range values {
var person Person
err := as.MapToStruct(v, &person)
if err != nil {
fmt.Printf("%v => error: %v\n", v, err)
} else {
fmt.Printf("%v => %+v\n", v, person)
}
}

// Output:
// as.MapToStruct()
// map[Age:30 Name:Alice] => {Name:Alice Age:30}
// map[Age:25 Name:Bob] => {Name:Bob Age:25}
}

func ExampleStructToMap() {
type Person struct {
Name string
Age int
}

values := []Person{
{Name: "Alice", Age: 30},
{Name: "Bob", Age: 25},
}

fmt.Println("as.StructToMap()")
for _, v := range values {
m := as.StructToMap(v)
fmt.Printf("%+v => %v\n", v, m)
}

// Output:
// as.StructToMap()
// {Name:Alice Age:30} => map[Age:30 Name:Alice]
// {Name:Bob Age:25} => map[Age:25 Name:Bob]
}

func ExampleIsEmailValid() {
values := []string{"[email protected]", "invalid-email", "[email protected]", "name@domain"}

fmt.Println("as.IsEmailValid()")
for _, v := range values {
valid := as.IsEmailValid(v)
fmt.Printf("%v => %v\n", v, valid)
}

// Output:
// as.IsEmailValid()
// [email protected] => true
// invalid-email => false
// [email protected] => true
// name@domain => false
}

func ExampleIsURLValid() {
values := []string{"http://example.com", "https://www.google.com", "invalid-url", "ftp://example.com"}

fmt.Println("as.IsURLValid()")
for _, v := range values {
valid := as.IsURLValid(v)
fmt.Printf("%v => %v\n", v, valid)
}

// Output:
// as.IsURLValid()
// http://example.com => true
// https://www.google.com => true
// invalid-url => false
// ftp://example.com => false
}

func ExampleIsCreditCardValid() {
values := []string{"4111111111111111", "5500000000000004", "1234567890123456", "378282246310005"}

fmt.Println("as.IsCreditCardValid()")
for _, v := range values {
valid := as.IsCreditCardValid(v)
fmt.Printf("%v => %v\n", v, valid)
}

// Output:
// as.IsCreditCardValid()
// 4111111111111111 => true
// 5500000000000004 => true
// 1234567890123456 => false
// 378282246310005 => true
}

func ExampleToJSON() {
values := []interface{}{"foobar", 123, true, map[string]interface{}{"key": "value"}}

fmt.Println("as.ToJSON()")
for _, v := range values {
jsonStr, err := as.ToJSON(v)
if err != nil {
fmt.Printf("%v => error: %v\n", v, err)
} else {
fmt.Printf("%v => %v\n", v, jsonStr)
}
}

// Output:
// as.ToJSON()
// foobar => "foobar"
// 123 => 123
// true => true
// map[key:value] => {"key":"value"}
}

func ExampleFromJSON() {
type Person struct {
Name string
Age int
}
values := []string{`{"Name": "Alice", "Age": 30}`, `{"Name": "Bob", "Age": 25}`}

fmt.Println("as.FromJSON()")
for _, v := range values {
var person Person
err := as.FromJSON(v, &person)
if err != nil {
fmt.Printf("%v => error: %v\n", v, err)
} else {
fmt.Printf("%v => %+v\n", v, person)
}
}

// Output:
// as.FromJSON()
// {"Name": "Alice", "Age": 30} => {Name:Alice Age:30}
// {"Name": "Bob", "Age": 25} => {Name:Bob Age:25}
}

0 comments on commit 06dd220

Please sign in to comment.