{"id":19095709,"url":"https://github.com/insei/fmap","last_synced_at":"2025-04-30T14:09:45.668Z","repository":{"id":240926437,"uuid":"803804064","full_name":"Insei/fmap","owner":"Insei","description":" FMap is a simple library for working with structs as storage of fields. Switch case and reflect based.","archived":false,"fork":false,"pushed_at":"2024-10-11T08:36:35.000Z","size":44,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-30T16:46:41.557Z","etag":null,"topics":["go","golang","map-fields","reflect","reflection","struct-as-map"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Insei.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":"2024-05-21T12:17:28.000Z","updated_at":"2024-10-11T08:36:22.000Z","dependencies_parsed_at":"2024-05-21T13:38:29.189Z","dependency_job_id":"c5539b8f-2dc7-4961-94bb-915ad5e58ecc","html_url":"https://github.com/Insei/fmap","commit_stats":null,"previous_names":["insei/fmap"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Insei%2Ffmap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Insei%2Ffmap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Insei%2Ffmap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Insei%2Ffmap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Insei","download_url":"https://codeload.github.com/Insei/fmap/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249514338,"owners_count":21284527,"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":["go","golang","map-fields","reflect","reflection","struct-as-map"],"created_at":"2024-11-09T03:34:51.787Z","updated_at":"2025-04-18T15:33:16.314Z","avatar_url":"https://github.com/Insei.png","language":"Go","readme":"[![codecov](https://codecov.io/github/Insei/fmap/branch/main/graph/badge.svg?token=S8EDJENDSI)](https://codecov.io/github/Insei/fmap) \r\n[![build](https://github.com/insei/fmap/actions/workflows/go.yml/badge.svg)](https://github.com/Insei/fmap/actions/workflows/go.yml)\r\n[![Goreport](https://goreportcard.com/badge/github.com/insei/fmap)](https://goreportcard.com/report/github.com/insei/fmap)\r\n[![GoDoc](https://godoc.org/github.com/insei/fmap?status.svg)](https://godoc.org/github.com/insei/fmap)\r\n# FMap \r\nFMap is a simple library for working with structs as a storage of fields. Switch case and reflect based.\r\nThis is unsafe library, be careful while use.\r\n\r\n# Installation\r\nInstall via go get. Note that Go 1.18 or newer is required.\r\n```sh\r\ngo get github.com/insei/fmap/v3@latest\r\n```\r\n\r\n# Description\r\n`fmap.GetFrom(obj any)` and `fmap.Get[T any]()` creates new fmap.Storage. This storage manage access to fmap.Field by field path like in struct.\r\n\r\n```go\r\ntype Storage interface {\r\n    // Find returns the Field object and a boolean value indicating if the field with the given path was found.\r\n    // The path parameter represents the path of the field in the struct.\r\n    // If the field is found, the method returns the Field object and true.\r\n    // If the field is not found, the method returns a nil Field object and false.\r\n    Find(path string) (Field, bool)\r\n    \r\n    // MustFind returns the Field object for the field with the given path in the struct.\r\n    // If the Field is not found, MustFind panics.\r\n    MustFind(path string) Field\r\n    \r\n    // GetAllPaths returns a slice containing all paths of fields in the struct.\r\n    GetAllPaths() []string\r\n}\r\n```\r\n\r\nfmap.Field is an advanced abstraction level for reflect.StructField with some advanced methods:\r\n```go\r\ntype Field interface {\r\n    // GetName returns the name of the field.\r\n    GetName() string\r\n    \r\n    // GetPkgPath returns the package import path of the Field struct type.\r\n    GetPkgPath() string\r\n    \r\n    // GetType returns the reflect.Type of the field.\r\n    GetType() reflect.Type\r\n    \r\n    // GetTag returns the reflect.StructTag of the field. The reflect.StructTag is a string.\r\n    GetTag() reflect.StructTag\r\n    \r\n    // GetOffset returns the offset of the field in memory relative to the start of the struct.\r\n    GetOffset() uintptr\r\n    \r\n    // GetIndex returns the index of the field within its containing struct as a slice of integers.\r\n    GetIndex() []int\r\n    \r\n    // GetAnonymous returns a boolean value indicating whether the field is anonymous.\r\n    GetAnonymous() bool\r\n    \r\n    // IsExported checks if a field is exported by checking its PkgPath property.\r\n    IsExported() bool\r\n    \r\n    // Extended Methods\r\n    \r\n    // Get returns the value of the storage in the provided object.\r\n    // It takes a parameter `obj` of type `interface{}`, representing the object.\r\n    // It returns the value of the storage as an `interface{}`.\r\n    Get(obj any) any\r\n    \r\n    // GetPtr returns the pointer to the field's value in the provided object.\r\n    // It takes a parameter `obj` of type `any`, representing the pointer to object.\r\n    // It returns the pointer to the field's value as an `any`.\r\n    GetPtr(obj any) any\r\n    \r\n    // Set updates the value of the storage in the provided object with the provided value.\r\n    // It takes two parameters:\r\n    //   - obj: interface{}, representing the object pointer containing the field.\r\n    //   - val: interface{}, representing the new value for the field.\r\n    Set(obj any, val any)\r\n    \r\n    // GetStructPath returns the struct path of the field.\r\n    // It returns the struct path as a string.\r\n    GetStructPath() string\r\n    \r\n    // GetTagPath returns the path of the field's tag value with the given tag name.\r\n    // It takes two parameters:\r\n    //   - tag: string, representing the tag name.\r\n    //   - ignoreParentTagMissing: bool, representing whether to ignore the missing parent tags or not.\r\n    // It returns the tag value path as a string.\r\n    GetTagPath(tag string, ignoreParentTagMissing bool) string\r\n    \r\n    // GetParent returns the parent field of the current field, if not exist return nil.\r\n    GetParent() Field\r\n    \r\n    // GetDereferencedType returns the dereferenced type of the field.\r\n    // It returns the dereferenced type as a reflect.Type.\r\n    GetDereferencedType() reflect.Type\r\n    \r\n    // GetDereferenced - uses reflect package for casting field value from obj to direct field value, i.e. dereferenced value.\r\n    GetDereferenced(obj any) (any, bool)\r\n}\r\n```\r\n# Example\r\n\r\n```go\r\npackage main\r\n\r\nimport (\r\n\t\"time\"\r\n\t\"fmt\"\r\n\r\n\t\"github.com/insei/fmap/v3\"\r\n)\r\n\r\ntype City struct {\r\n\tName string `json:\"name\"`\r\n}\r\n\r\ntype People struct {\r\n\tName     string\r\n\tAge      uint8\r\n\tBirthday time.Time\r\n\tCity City `json:\"city\"`\r\n}\r\n\r\nfunc main() {\r\n\tp := \u0026People{}\r\n\tfields := fmap.Get[People]() // or fmap.GetFrom(p)\r\n\tfields.MustFind(\"Name\").Set(p, \"Test\")\r\n\tfields.MustFind(\"Age\").Set(p, uint8(5))\r\n\tfields.MustFind(\"Birthday\").Set(p, time.Now())\r\n\tfields.MustFind(\"City.Name\").Set(p, \"DefaultCity\")\r\n\tjsonPath := fields.MustFind(\"City.Name\").GetTagPath(\"json\", false) // city.name\r\n\tcityField := fields.MustFind(\"City.Name\").GetParent()\r\n\tcityStruct := cityField.Get(p)\r\n\tfmt.Print(*p, jsonPath, cityStruct)\r\n}\r\n```\r\n\r\nMore examples in `field_test.go`, like slice fields, nested structs, pointers etc.\r\n\r\n# Benchmarks\r\n`fmap.GetFrom(obj any) map[string]Field`\r\n```\r\nBenchmarkGetFrom\r\nBenchmarkGetFrom-16     93002347                12.62 ns/op            0 B/op          0 allocs/op\r\n```\r\n\r\n`Field.Get(obj any) any`\r\n```\r\nBenchmarkFieldGet\r\nBenchmarkFieldGet-16            88818492                14.05 ns/op            0 B/op          0 allocs/op\r\n```\r\n\r\n`Raw access to field from struct :)`\r\n```\r\nBenchmarkRawFieldGet\r\nBenchmarkRawFieldGet-16         1000000000               0.2350 ns/op          0 B/op          0 allocs/op\r\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finsei%2Ffmap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finsei%2Ffmap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finsei%2Ffmap/lists"}