{"id":13413803,"url":"https://github.com/epiclabs-io/elastic","last_synced_at":"2025-03-14T20:30:34.913Z","repository":{"id":51145899,"uuid":"243089494","full_name":"epiclabs-io/elastic","owner":"epiclabs-io","description":"Converts go types no matter what","archived":false,"fork":false,"pushed_at":"2021-05-21T12:32:58.000Z","size":11,"stargazers_count":24,"open_issues_count":1,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-07-31T20:52:54.225Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/epiclabs-io.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}},"created_at":"2020-02-25T19:55:00.000Z","updated_at":"2023-12-28T06:43:55.000Z","dependencies_parsed_at":"2022-08-27T22:30:54.058Z","dependency_job_id":null,"html_url":"https://github.com/epiclabs-io/elastic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epiclabs-io%2Felastic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epiclabs-io%2Felastic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epiclabs-io%2Felastic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epiclabs-io%2Felastic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/epiclabs-io","download_url":"https://codeload.github.com/epiclabs-io/elastic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243641952,"owners_count":20323940,"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":[],"created_at":"2024-07-30T20:01:49.735Z","updated_at":"2025-03-14T20:30:34.628Z","avatar_url":"https://github.com/epiclabs-io.png","language":"Go","funding_links":[],"categories":["Serialization","序列化","安全领域相关库","Go","Relational Databases"],"sub_categories":["HTTP Clients","HTTP客户端","查询语"],"readme":"# elastic\n[![Build Status](https://travis-ci.org/epiclabs-io/elastic.svg?branch=master)](https://travis-ci.org/epiclabs-io/elastic)\n[![GoDoc](https://godoc.org/github.com/epiclabs-io/elastic?status.svg)](https://godoc.org/github.com/epiclabs-io/elastic)\n\n\nConverts go types no matter what\n\n`elastic` is a simple library that converts any type to another the best way possible. This is useful when the type is only known at run-time, which usually happens when serializing data. `elastic` allows your code to be flexible regarding type conversion if that is what you're looking for.\n\nIt is also capable of seeing through alias types and converting slices and maps to and from other types of slices and maps, providing there is some logical way to convert them.\n\nDefault conversion can be overridden by providing custom conversion functions for specific types.\nStruct types can also implement the `ConverterTo` interface to help with conversion to and from specific types.\n\n\n## Quick examples:\n\n### convert value types:\n\n```go\n\t// note that using elastic wouldn't make sense if you are certain\n    // f is a float64 at compile time.\n    var f interface{} = float64(5.5)\n\tvar i int\n    \n    err := elastic.Set(\u0026i, f)\n\tif err != nil {\n\t\tlog.Fatal(f)\n\t}\n\n\tfmt.Println(i) // prints 5\n```\n\n### convert slices:\n\n```go\n\tvar ints []int\n\terr = elastic.Set(\u0026ints, []interface{}{1, 2, 3, \"4\", float64(5), 6})\n\tif err != nil {\n\t\tlog.Fatal(f)\n\t}\n\n\tfmt.Println(ints) // prints [1 2 3 4 5 6]\n```\n\n### convert maps:\n\n```go\n\tsomeMap := map[string]interface{}{\n\t\t\"1\": \"uno\",\n\t\t\"2\": \"dos\",\n\t\t\"3\": \"tres\",\n\t}\n\n\tintmap := make(map[int]string)\n\terr = elastic.Set(\u0026intmap, someMap)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(intmap) // prints map[1:uno 2:dos 3:tres]\n```\n\n# Simple API:\n\n## `elastic.Convert()`\nConverts the passed value to the target type\n#### Syntax:\n`elastic.Convert(source interface{}, targetType reflect.Type) (interface{}, error)`\n\n* `source`: value to convert\n* `targetType` the type you want to convert `source` to\n\n#### Returns\nThe converted value or an error if it fails.\n\n## `elastic.Set()`\nSets the given variable to the passed value\n#### Syntax:\n`elastic.Set(target, source interface{}) error`\n* `target`: value to set. Must be a pointer.\n* `source` the value to convert\n\n#### Returns\nOnly an error if it fails.\n\n# Advanced API:\n\nYou can create different instances of the elastic conversion engine so that you can customize conversions independently\n\n## `elastic.New()`\nReturns a new conversion engine. It has a `.Set()` and `.Convert()` as above that will work according to the rules set for this engine\n\n## `AddSourceConverter() and AddTargetConverter()`\nRegisters a conversion function for the given type, either when the type is found on the source side or the target side.\n\nThese are useful when you do not control the type you whish to make convertible\n\n#### Syntax:\n`engine.AddSourceConverter(sourceType reflect.Type, f ConverterFunc)`\n* `sourceType`: type you want to set a custom conversion function for\n* `f`: Conversion function to invoke when this type is found as a source\n\n`engine.AddTargetConverter(targetType reflect.Type, f ConverterFunc)`\n* `targetType`: type you want to set a custom conversion function for\n* `f`: Conversion function to invoke when this type is found as a target\n\nThe value returned by your function does not have to be *exactly* of type `targetType`. For example if a `float64` is requested and you return an integer, `elastic` will deal with it.\n\n#### Example:\n```go\npackage main\n\ntype Vector struct {\n\tX float64\n\tY float64\n}\n\nfunc main() {\n\n\t// Add a custom converter to convert Vector to float64 or int\n\t// (Calculates the modulus of the vector)\n\telastic.Default.AddSourceConverter(reflect.TypeOf(Vector{}), func(source interface{}, targetType reflect.Type) (interface{}, error) {\n\t\tvector := source.(Vector)\n\t\tswitch targetType.Kind() {\n\t\tcase reflect.Float64, reflect.Int:\n\t\t\treturn math.Sqrt(float64(vector.X*vector.X) + float64(vector.Y*vector.Y)), nil\n\t\tcase reflect.String:\n\t\t\treturn fmt.Sprintf(\"(%g, %g)\", vector.X, vector.Y), nil\n\t\t}\n\t\treturn nil, elastic.ErrNoConversionAvailable\n\n\t})\n\n\tv := Vector{\n\t\tX: 3.0,\n\t\tY: 4.0,\n\t}\n\n\tf, err = elastic.Convert(v, reflect.TypeOf(float64(0)))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(f) // prints 5\n\n\tvar s string\n\telastic.Set(\u0026s, v)\n\tfmt.Println(s) // prints (3, 4)\n\n}\n\n```\n\n## `ConverterTo` interface\n\n```go\ntype ConverterTo interface {\n\tConvertTo(targetType reflect.Type) (interface{}, error)\n}\n```\n\nImplement this interface in your type to provide conversion to another types. This function will be invoked every time your type is on the right-hand side of a conversion.\nThe value returned by your function does not have to be *exactly* of type `targetType`. For example if a `float64` is requested and you return an integer, `elastic` will deal with it.\n\n#### Example:\n\n```go\ntype Vector struct {\n\tX float64\n\tY float64\n}\n\nfunc (v *Vector) ConvertTo(targetType reflect.Type) (interface{}, error) {\n\t\tswitch targetType.Kind() {\n\t\tcase reflect.Float64, reflect.Int:\n\t\t\treturn math.Sqrt(float64(v.X*v.X) + float64(v.Y*v.Y)), nil\n\t\tcase reflect.String:\n\t\t\treturn fmt.Sprintf(\"(%g, %g)\", v.X, v.Y), nil\n\t\t}\n\t\treturn nil, elastic.ErrNoConversionAvailable\n}\n\nfunc main() {\n\tv := Vector{\n\t\tX: 3.0,\n\t\tY: 4.0,\n\t}\n\t\n\tvar i int\n\telastic.Set(\u0026i, v)\n\tfmt.Println(i) // prints 5\n\n\tvar s string\n\telastic.Set(\u0026s, v)\n\tfmt.Println(s) // prints (3, 4)\n}\n\n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fepiclabs-io%2Felastic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fepiclabs-io%2Felastic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fepiclabs-io%2Felastic/lists"}