{"id":23447533,"url":"https://github.com/cmstar/go-conv","last_synced_at":"2025-07-07T21:08:58.067Z","repository":{"id":57639764,"uuid":"390910072","full_name":"cmstar/go-conv","owner":"cmstar","description":"Convert between Go types, including bool, string, numbers, time, map, struct, slice.","archived":false,"fork":false,"pushed_at":"2025-03-31T07:12:26.000Z","size":82,"stargazers_count":6,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-13T16:12:21.832Z","etag":null,"topics":["conversion","convert","go","go-library","golang","typeconversion","typeconverter"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cmstar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-30T02:54:44.000Z","updated_at":"2025-03-31T07:08:14.000Z","dependencies_parsed_at":"2025-03-05T11:25:33.905Z","dependency_job_id":"16774a22-5509-4933-9938-58bf067fd5a4","html_url":"https://github.com/cmstar/go-conv","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmstar%2Fgo-conv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmstar%2Fgo-conv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmstar%2Fgo-conv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmstar%2Fgo-conv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cmstar","download_url":"https://codeload.github.com/cmstar/go-conv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248741195,"owners_count":21154255,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["conversion","convert","go","go-library","golang","typeconversion","typeconverter"],"created_at":"2024-12-23T21:18:07.272Z","updated_at":"2025-04-13T16:12:26.661Z","avatar_url":"https://github.com/cmstar.png","language":"Go","readme":"# conv - A Go package for type conversion\n\n[![GoDoc](https://godoc.org/github.com/cmstar/go-conv?status.svg)](https://pkg.go.dev/github.com/cmstar/go-conv)\n[![Go](https://github.com/cmstar/go-conv/workflows/Go/badge.svg)](https://github.com/cmstar/go-conv/actions?query=workflow%3AGo)\n[![codecov](https://codecov.io/gh/cmstar/go-conv/branch/master/graph/badge.svg)](https://codecov.io/gh/cmstar/go-conv)\n[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://opensource.org/licenses/MIT)\n[![GoVersion](https://img.shields.io/github/go-mod/go-version/cmstar/go-conv)](https://github.com/cmstar/go-conv/blob/main/go.mod)\n[![Go Report Card](https://goreportcard.com/badge/github.com/cmstar/go-conv)](https://goreportcard.com/report/github.com/cmstar/go-conv)\n\nFeatures:\n\n- Supports conversion between numbers, string, time.\n- Supports converting from `slice` to `slice`.\n- Supports converting between `struct` and `map[string]interface{}`.\n- Overflow checking when converting integers.\n- Match field names case-insensitively, or in the camel-case manner.\n- Case-insensitive JSON unmarshalling using a `map` as the middleware.\n- Deep-clone.\n- Support pointers.\n- No third party dependency. All features are implemented using the standard library.\n\nSome features are still under development, the APIs may change in the future.\n\n## Quick start\n\nInstallation:\n```\ngo get -u github.com/cmstar/go-conv@latest\n```\n\nSimple usage, the code below comes from the example_test.go:\n```go\n// There is a group of shortcut functions for converting from/to simple types.\n// All conversion functions returns the converted value and an error.\nfmt.Println(conv.Int(\"123\"))         // -\u003e 123\nfmt.Println(conv.String(3.14))       // -\u003e \"3.14\"\nfmt.Println(conv.Float64(\"invalid\")) // -\u003e get an error\n\n// When converting integers, overflow-checking is applied.\nfmt.Println(conv.Int8(1000)) // -\u003e overflow\n\n// A zero value of number is converted to false; a non-zero value is converted to true.\nfmt.Println(conv.Bool(float32(0.0))) // -\u003e false\nfmt.Println(conv.Bool(float64(0.1))) // -\u003e true\nfmt.Println(conv.Bool(-1))           // -\u003e true\n\n// strconv.ParseBool() is used for string-to-bool conversion.\nfmt.Println(conv.Bool(\"true\"))  // -\u003e true\nfmt.Println(conv.Bool(\"false\")) // -\u003e false\n\n// Numbers can be converted time.Time, they're treated as UNIX timestamp.\n// For more information, see the example in go-doc.\nt, err := conv.Time(3600) // An hour later after 1970-01-01T00:00:00Z.\n// By default time.Time is converted to string with the RFC3339 format.\nfmt.Println(conv.String(t.UTC())) // -\u003e 1970-01-01T01:00:00Z\n\n// ConvertType() is the core function in the package. In fact all conversion can be done via\n// this function. For complex types, there is no shortcut, we can use ConvertType() directly.\n// It receives the source value and the destination type.\n\n// Convert from a slice to another. ConvertType() is applied to each element.\nsliceOfInt, err := conv.ConvertType([]string{\"1\", \"2\", \"3\"}, reflect.TypeOf([]int{}))\nfmt.Println(sliceOfInt, err) // -\u003e []int{1, 2, 3}\n\n// Convert from a map[string]interface{} to a struct. ConvertType() is applied to each field.\nuser := DemoUser{Name: \"Bob\", MailAddr: \"bob@example.org\", Age: 51}\nout, err := conv.ConvertType(user, reflect.TypeOf(map[string]interface{}{}))\nfmt.Println(out, err) // -\u003e map[string]interface{}{\"Age\":51, \"MailAddr\":\"bob@example.org\", \"Name\":\"Bob\", \"IsVip\":false}\n\n// From map to struct.\nm := map[string]interface{}{\"Name\": \"Alice\", \"Age\": \"27\", \"IsVip\": 1}\nout, err = conv.ConvertType(m, reflect.TypeOf(user))\nfmt.Printf(\"%+v\\n\", out) // -\u003e DemoUser{Name: \"Alice\", MailAddr: \"\", Age: 27, IsVip:true}\n\n// Deep-clone a struct.\nout, err = conv.ConvertType(user, reflect.TypeOf(user))\nfmt.Printf(\"%+v\\n\", out) // -\u003e DemoUser{Name: \"Bob\", MailAddr: \"bob@example.org\", Age: 51}\n\n// Convert() is similar to ConvertType(), but receive a pointer instead of a type.\n// It's more like some functions in the standard library such as json.Unmarshal().\nclone := DemoUser{}\nconv.Convert(user, \u0026clone)\nfmt.Printf(\"%+v\\n\", clone) // -\u003e DemoUser{Name: \"Bob\", MailAddr: \"bob@example.org\", Age: 51}\n```\n\nOutput:\n```\n// 123 \u003cnil\u003e\n// 3.14 \u003cnil\u003e\n// 0 strconv.ParseFloat: parsing \"invalid\": invalid syntax\n// 0 value overflow when converting 1000 (int) to int8\n// false \u003cnil\u003e\n// true \u003cnil\u003e\n// true \u003cnil\u003e\n// true \u003cnil\u003e\n// false \u003cnil\u003e\n// 1970-01-01T01:00:00Z \u003cnil\u003e\n// [1 2 3] \u003cnil\u003e\n// map[Age:51 IsVip:false MailAddr:bob@example.org Name:Bob] \u003cnil\u003e\n// {Name:Alice MailAddr: Age:27 IsVip:true}\n// {Name:Bob MailAddr:bob@example.org Age:51 IsVip:false}\n// {Name:Bob MailAddr:bob@example.org Age:51 IsVip:false}\n```\n\nDeep into the Conv instance:\n```go\n// The Conv struct providers the underlying features for all shortcuts functions.\n// You can use it directly. A zero value has the default behavior.\nc := new(conv.Conv)\n\n// It has a field named Conf which is used to customize the conversion.\n// By default, we get an error when converting to a slice from a string that is a group of\n// elements separated by some characters.\nfmt.Println(c.ConvertType(\"1,2,3\", reflect.TypeOf([]int{}))) // -\u003e error\n\n// Conf.StringSplitter is a function that defines how to convert from a string to a slice.\nc.Conf.StringSplitter = func(v string) []string { return strings.Split(v, \",\") }\n// After configure, the conversion should be OK.\nfmt.Println(c.ConvertType(\"1,2,3\", reflect.TypeOf([]int{}))) // -\u003e []int{1, 2, 3}\n\n// Conf.FieldMatcherCreator define how to match names from a struct when converting from\n// a map or another struct.\n// Here we demonstrate how to make snake-case names match the field names automatically,\n// using the build-in FieldMatcherCreator named SimpleMatcherCreator.\nc.Conf.FieldMatcherCreator = conv.SimpleMatcherCreator{\n\tConf: conv.SimpleMatcherConfig{\n\t\tCamelSnakeCase: true,\n\t},\n}\n// When then CamelSnakeCase option is true, 'mailAddr' can match the field MailAddr, 'is_vip' can match IsVip.\nm := map[string]interface{}{\"name\": \"Bob\", \"age\": \"51\", \"mailAddr\": \"bob@example.org\", \"is_vip\": \"true\"}\nuser := DemoUser{}\n_ = c.Convert(m, \u0026user)\nfmt.Printf(\"%+v\\n\", user) // -\u003e DemoUser{Name: \"Bob\", MailAddr: \"bob@example.org\", Age: 51, IsVip: true})\n\n// The json package of the standard library does not support matching fields in case-insensitive manner.\n// We have to use field tag to specify the name of JSON properties.\n// With FieldMatcherCreator, we can unmarshal JSON in case-insensitive manner, using a map as a middleware.\n// Thou the performance is not good, but it works :) .\nmiddleware := make(map[string]interface{})\n_ = json.Unmarshal([]byte(`{\"name\":\"Alice\", \"mailAddr\":\"alice@example.org\", \"isVip\": true, \"age\":27}`), \u0026middleware)\n_ = c.Convert(middleware, \u0026user)\nfmt.Printf(\"%+v\\n\", user) // -\u003e DemoUser{Name: \"Alice\", MailAddr: \"alice@example.org\", Age: 27, IsVip: true})\n```\n\nOutput:\n```\n// \u003cnil\u003e conv.ConvertType: conv.StringToSlice: cannot convert to []int, at index 0: conv.SimpleToSimple: strconv.ParseInt: parsing \"1,2,3\": invalid syntax\n// [1 2 3] \u003cnil\u003e\n// {Name:Bob MailAddr:bob@example.org Age:51 IsVip:true}\n// {Name:Alice MailAddr:alice@example.org Age:27 IsVip:true}\n```\n\n## Performance\n\nNot good. The code use reflect heavily, be aware if you are care for the performance.\n\n## Known issues\n\n- The field tags are not processed when converting from `struct` to `map` or to other `struct`.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmstar%2Fgo-conv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcmstar%2Fgo-conv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmstar%2Fgo-conv/lists"}