structx

package
v0.4.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2023 License: MIT Imports: 3 Imported by: 2

Documentation

Overview

Functions used to manipulate structs.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CallMethod

func CallMethod[S any](target S, method string, args ...any) []any

Calls the method of the target struct.

This function panics if the given method doesn't exist.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext"
	"github.com/ayonli/goext/structx"
)

type Person struct {
	Name   string
	Email  string
	Gender string
}

func (self Person) GetName() string {
	return self.Name
}

func (self *Person) Greet(verb string) string {
	return verb + ", " + self.Name
}

func main() {
	person := &Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	returns1 := structx.CallMethod(person, "GetName")
	returns2 := structx.CallMethod(person, "Greet", "Hello")
	_, err := goext.Try(func() []any { return structx.CallMethod(person, "GetEmail") })

	fmt.Println(returns1...)
	fmt.Println(returns2...)
	fmt.Println(err)
}
Output:
A-yon Lee
Hello, A-yon Lee
method GetEmail() doesn't exist on *structx_test.Person

func Fields

func Fields[S any](target S) []string

Returns the fields of the given struct.

This function only collects the exported fields, it panics if the given argument is not a struct.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	person := Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	fields := structx.Fields(person)

	fmt.Println(fields)
}
Output:
[Name Email]
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	person := &Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	fields := structx.Fields(person)

	fmt.Println(fields)
}
Output:
[Name Email]

func ForEach

func ForEach[V any](target any, fn func(value V, field string))

Executes a provided function once for each field-value pair.

This function only loops the exported fields, it panics if the given argument is not a struct.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	person := Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}

	structx.ForEach[string](person, func(value, key string) {
		fmt.Println(key, "=>", value)
	})
}
Output:
Name => A-yon Lee
Email => the@ayon.li
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	person := &Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}

	structx.ForEach[string](person, func(value, key string) {
		fmt.Println(key, "=>", value)
	})
}
Output:
Name => A-yon Lee
Email => the@ayon.li

func FromMap

func FromMap[V any, S any](m map[string]V) S

Creates a struct based on the given map.

This function only supports the exported fields.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	record := map[string]string{
		"Name":  "A-yon Lee",
		"Email": "the@ayon.li",
	}
	person := structx.FromMap[string, Person](record)

	fmt.Printf("%#v\n", person)
}
Output:
structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li"}
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	record := map[string]string{
		"Name":  "A-yon Lee",
		"Email": "the@ayon.li",
	}
	person := structx.FromMap[string, *Person](record)

	fmt.Printf("%#v\n", person)
}
Output:
&structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li"}

func Get

func Get[V any](target any, field string) (V, bool)

Returns the value of the specified field of the struct.

This function only supports the exported fields, it panics if the given argument is not a struct.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name   string
		Email  string
		Gender string
	}

	person := Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	name, ok1 := structx.Get[string](person, "Name")
	gender, ok2 := structx.Get[string](person, "Gender")
	age, ok3 := structx.Get[int](person, "Age")

	fmt.Println(name, ok1)
	fmt.Println(gender, ok2)
	fmt.Println(age, ok3)
}
Output:
A-yon Lee true
 true
0 false
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name   string
		Email  string
		Gender string
	}

	person := &Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	name, ok1 := structx.Get[string](person, "Name")
	gender, ok2 := structx.Get[string](person, "Gender")
	age, ok3 := structx.Get[int](person, "Age")

	fmt.Println(name, ok1)
	fmt.Println(gender, ok2)
	fmt.Println(age, ok3)
}
Output:
A-yon Lee true
 true
0 false

func Has

func Has[S any](target S, field string) bool
Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name   string
		Email  string
		Gender string
	}

	person := Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	ok1 := structx.Has(person, "Name")
	ok2 := structx.Has(person, "Gender")
	ok3 := structx.Has(person, "Age")

	fmt.Println(ok1)
	fmt.Println(ok2)
	fmt.Println(ok3)
}
Output:
true
true
false
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name   string
		Email  string
		Gender string
	}

	person := &Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	ok1 := structx.Has(person, "Name")
	ok2 := structx.Has(person, "Gender")
	ok3 := structx.Has(person, "Age")

	fmt.Println(ok1)
	fmt.Println(ok2)
	fmt.Println(ok3)
}
Output:
true
true
false

func HasMethod

func HasMethod[S any](target S, method string) bool

Checks if the target struct has a method of the given name.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

type Person struct {
	Name   string
	Email  string
	Gender string
}

func (self Person) GetName() string {
	return self.Name
}

func (self *Person) Greet(verb string) string {
	return verb + ", " + self.Name
}

func main() {
	person := Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	ok1 := structx.HasMethod(person, "GetName")
	ok2 := structx.HasMethod(person, "Greet")
	ok3 := structx.HasMethod(person, "GetEmail")

	fmt.Println(ok1)
	fmt.Println(ok2)
	fmt.Println(ok3)
}
Output:
true
false
false
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

type Person struct {
	Name   string
	Email  string
	Gender string
}

func (self Person) GetName() string {
	return self.Name
}

func (self *Person) Greet(verb string) string {
	return verb + ", " + self.Name
}

func main() {
	person := &Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	ok1 := structx.HasMethod(person, "GetName")
	ok2 := structx.HasMethod(person, "Greet")
	ok3 := structx.HasMethod(person, "GetEmail")

	fmt.Println(ok1)
	fmt.Println(ok2)
	fmt.Println(ok3)
}
Output:
true
true
false

func Merge

func Merge[T any](first T, others ...T) T

Performs a shallow merge of two or more structs. The later field-value pairs override the existing ones or the ones before them.

This function only works on the exported fields. If the input arguments are pointers, it mutates the first one and returns it, otherwise, a new struct is created.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	record1 := Person{
		Name:  "A-yon Lee",
		Email: "ayonlys@gmail.com",
	}
	record2 := Person{
		Email: "the@ayon.li",
	}
	record3 := structx.Merge(record1, record2)

	fmt.Printf("%#v\n", record3)
	fmt.Printf("%#v\n", record1) // record1 is not changed
	fmt.Printf("%#v\n", record2) // record2 is not changed
}
Output:
structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li"}
structx_test.Person{Name:"A-yon Lee", Email:"ayonlys@gmail.com"}
structx_test.Person{Name:"", Email:"the@ayon.li"}
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	record1 := &Person{
		Name:  "A-yon Lee",
		Email: "ayonlys@gmail.com",
	}
	record2 := &Person{
		Email: "the@ayon.li",
	}
	record3 := structx.Merge(record1, record2)

	fmt.Printf("%#v\n", record3)
	fmt.Printf("%#v\n", record1) // record1 is also changed
	fmt.Printf("%#v\n", record2) // record2 is not changed
}
Output:
&structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li"}
&structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li"}
&structx_test.Person{Name:"", Email:"the@ayon.li"}

func Omit

func Omit[S any](original S, fields []string) S

Creates a new struct based on the original struct but without the specified fields. Omitted fields will be set to the 0-values of their types.

This function only works on the exported fields.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name   string
		Email  string
		Gender int
		Age    int
	}

	record1 := Person{
		Name:   "A-yon Lee",
		Email:  "the@ayon.li",
		Gender: 1,
		Age:    28,
	}
	record2 := structx.Omit(record1, []string{"Gender", "Age"})

	fmt.Printf("%#v\n", record2)
}
Output:
structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li", Gender:0, Age:0}
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name   string
		Email  string
		Gender int
		Age    int
	}

	record1 := &Person{
		Name:   "A-yon Lee",
		Email:  "the@ayon.li",
		Gender: 1,
		Age:    28,
	}
	record2 := structx.Omit(record1, []string{"Gender", "Age"})

	fmt.Printf("%#v\n", record2)
}
Output:
&structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li", Gender:0, Age:0}

func Patch

func Patch[T any](first T, others ...T) T

Performs a shallow merge of two or more structs, copies the field-value pairs that are presented in the later structs but are missing in the former into it, later pairs are skipped if the same field in the former struct is not the 0-value of its type.

This function only works on the exported fields. If the input arguments are pointers, it mutates the first one and returns it, otherwise, a new struct is created.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	record1 := Person{
		Name: "A-yon Lee",
	}
	record2 := Person{
		Name:  "John Doe",
		Email: "the@ayon.li",
	}
	record3 := structx.Patch(record1, record2)

	fmt.Printf("%#v\n", record3)
	fmt.Printf("%#v\n", record1) // record1 is not changed
	fmt.Printf("%#v\n", record2) // record2 is not changed
}
Output:
structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li"}
structx_test.Person{Name:"A-yon Lee", Email:""}
structx_test.Person{Name:"John Doe", Email:"the@ayon.li"}
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	record1 := &Person{
		Name: "A-yon Lee",
	}
	record2 := &Person{
		Name:  "John Doe",
		Email: "the@ayon.li",
	}
	record3 := structx.Patch(record1, record2)

	fmt.Printf("%#v\n", record3)
	fmt.Printf("%#v\n", record1) // record1 is also changed
	fmt.Printf("%#v\n", record2) // record2 is not changed
}
Output:
&structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li"}
&structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li"}
&structx_test.Person{Name:"John Doe", Email:"the@ayon.li"}

func Pick

func Pick[S any](original S, fields []string) S

Creates a new struct based on the original struct but only contains the specified fields. Omitted fields will be set to the 0-values of their types.

This function only works on the exported fields.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name   string
		Email  string
		Gender int
		Age    int
	}

	record1 := Person{
		Name:   "A-yon Lee",
		Email:  "the@ayon.li",
		Gender: 1,
		Age:    28,
	}
	record2 := structx.Pick(record1, []string{
		"Name",
		"Email",
		"Other", // unrecognized field is ignored
	})

	fmt.Printf("%#v\n", record2)
}
Output:
structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li", Gender:0, Age:0}
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name   string
		Email  string
		Gender int
		Age    int
	}

	record1 := &Person{
		Name:   "A-yon Lee",
		Email:  "the@ayon.li",
		Gender: 1,
		Age:    28,
	}
	record2 := structx.Pick(record1, []string{"Name", "Email"})

	fmt.Printf("%#v\n", record2)
}
Output:
&structx_test.Person{Name:"A-yon Lee", Email:"the@ayon.li", Gender:0, Age:0}

func Set

func Set[S any](target S, field string, value any) bool

Sets the field of the struct to be the given value.

This function takes a pointer of the struct instead of its value, and it only supports the exported fields of the struct.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	person := Person{}
	ok1 := structx.Set(&person, "Name", "A-yon Lee")
	ok2 := structx.Set(&person, "Gender", "MALE")

	fmt.Printf("%#v\n", person)
	fmt.Println(ok1)
	fmt.Println(ok2)
}
Output:
structx_test.Person{Name:"A-yon Lee", Email:""}
true
false

func ToMap

func ToMap[V any](s any) map[string]V

Creates a map based on the given struct.

This function only collects the exported fields.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	person := Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	record := structx.ToMap[string](person)

	fmt.Println(record)
}
Output:
map[Email:the@ayon.li Name:A-yon Lee]
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	person := &Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	record := structx.ToMap[string](person)

	fmt.Println(record)
}
Output:
map[Email:the@ayon.li Name:A-yon Lee]

func Values

func Values[V any](target any) []V

Returns the values of the given struct.

This function only collects the exported fields, it panics if the given argument is not a struct.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	person := Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	fields := structx.Values[string](person)

	fmt.Println(fields)
}
Output:
[A-yon Lee the@ayon.li]
Example (Pointer)
package main

import (
	"fmt"

	"github.com/ayonli/goext/structx"
)

func main() {
	type Person struct {
		Name  string
		Email string
	}

	person := &Person{
		Name:  "A-yon Lee",
		Email: "the@ayon.li",
	}
	fields := structx.Values[string](person)

	fmt.Println(fields)
}
Output:
[A-yon Lee the@ayon.li]

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL