{"id":39175101,"url":"https://github.com/flusflas/dipper","last_synced_at":"2026-01-17T22:27:31.641Z","repository":{"id":64340944,"uuid":"575116999","full_name":"flusflas/dipper","owner":"flusflas","description":"A Go library to get and set (almost) anything using simple notation","archived":false,"fork":false,"pushed_at":"2024-06-14T13:26:44.000Z","size":62,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-02T12:17:47.585Z","etag":null,"topics":["dot-notation","go","golang","golang-library","golang-package","reflect","reflection"],"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/flusflas.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2022-12-06T19:47:03.000Z","updated_at":"2024-06-17T18:45:43.000Z","dependencies_parsed_at":"2024-06-21T11:44:23.106Z","dependency_job_id":"67049fe8-4b92-42d0-bd7f-e761ad7cd97d","html_url":"https://github.com/flusflas/dipper","commit_stats":{"total_commits":53,"total_committers":1,"mean_commits":53.0,"dds":0.0,"last_synced_commit":"163d0579cb0b1c503ab0096aa86e3523f9305802"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/flusflas/dipper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flusflas%2Fdipper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flusflas%2Fdipper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flusflas%2Fdipper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flusflas%2Fdipper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flusflas","download_url":"https://codeload.github.com/flusflas/dipper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flusflas%2Fdipper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28520484,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T22:11:28.393Z","status":"ssl_error","status_checked_at":"2026-01-17T22:11:27.841Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["dot-notation","go","golang","golang-library","golang-package","reflect","reflection"],"created_at":"2026-01-17T22:27:31.172Z","updated_at":"2026-01-17T22:27:31.635Z","avatar_url":"https://github.com/flusflas.png","language":"Go","readme":"\u003ch3 align=\"center\"\u003e\u003cb\u003edipper\u003c/b\u003e\u003c/h3\u003e\n\u003cp align=\"center\"\u003eA Go library to get and set (almost) anything using simple notation\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/flusflas/dipper/actions/workflows/ci.yaml\"\u003e\u003cimg src=\"https://github.com/flusflas/dipper/actions/workflows/ci.yaml/badge.svg\" alt=\"CI Workflow\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/flusflas/dipper\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/flusflas/dipper\" alt=\"Go Report Card\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/flusflas/dipper\"\u003e\u003cimg src=\"https://codecov.io/gh/flusflas/dipper/branch/master/graph/badge.svg\" alt=\"codecov\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/go%20version-%3E=1.13-F37F40.svg\" alt=\"Go Version\"\u003e\n  \u003ca href=\"https://github.com/flusflas/dipper/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-green.svg\" alt=\"MIT License\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/flusflas/dipper\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/github.com/flusflas/dipper\" alt=\"Go Documentation\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Install\n\n```shell\ngo get github.com/flusflas/dipper\n```\n\n## What is *dipper*?\n\n**dipper** is a simple library that let you use dot notation (or any other\ndelimiter-separated attribute notation) to access values in an object, both for\ngetting and setting, even if they are deeply nested. You can use it with\nstructs, maps and slices.\n\n## How to use it?\n\nYou can create a `Dipper` instance to customize the access options:\n\n```go\nlibrary := Library{\n\tAddress: \"123 Fake Street\",\n\tBooks: []Book{\n\t\t{\n\t\t\tTitle:  \"Dune\",\n\t\t\tYear:   1965,\n\t\t\tGenres: []string{\"Novel\", \"Science fiction\", \"Adventure\"},\n\t\t},\n\t\t{\n\t\t\tTitle:  \"Il nome della rosa\",\n\t\t\tYear:   1980,\n\t\t\tGenres: []string{\"Novel\", \"Mystery\"},\n\t\t},\n\t},\n}\n\nd := dipper.New(dipper.Options{Separator: \"-\u003e\"})\n\nbook := d.Get(library, \"Books-\u003e1\")\nif err := dipper.Error(book); err != nil {\n\treturn err\n}\n```\n\nOr you can use the default functions if you just need dot notation access.\nThis is an example of how to get a nested value from an object:\n\n```go\n\nfield := dipper.Get(library, \"Books[0].Genres[1]\")  // \"Science fiction\"\nif err := dipper.Error(field); err != nil {\n    return err\n}\n``` \n\nYou can also get multiple attributes at once:\n\n```go\nfields := dipper.GetMany(library, []string{\n    \"Address\",\n    \"Books[1].Year\",\n    \"Books[0].Author\",\n})\n\n// fields =\u003e map[string]interface{}{\n//   \"Address\":                       \"123 Fake Street\",\n//   \"Books.1.Year\": 1980,\n//   \"Books.0.Author\":             dipper.ErrNotFound,\n// }\n\nif err := fields.FirstError(); err != nil {\n    //return err // Returns \"dipper: not found\"\n}\n``` \n\nFinally, you can also set values in addressable objects:\n\n```go\n// Replace book\nerr := dipper.Set(\u0026library, \"Books.0\", Book{Title: \"1984\", Year: 1949})\n``` \n\nThere are two special values that can be used in `Set()`:\n- `Zero`, to set the attribute to its zero value.\n- `Delete`, to delete a map key. If the attribute is not a map value, the value\n  will be zeroed.\n\n\n## Expression Syntax\n\n### Accessing Maps\n\nTo access map values, use the map key directly with the separator notation:\n\n- `BookMap.Dune` to access the value associated with the key `\"Dune\"` in a map.\n\n### Accessing Structs\n\nTo access struct fields, use the separator notation:\n\n- `Library.Address` to access the `Address` field of the `Library` struct.\n\n### Accessing Slices\n\nTo access slice elements, you can use either the slice notation with square\nbrackets or the separator notation:\n\n- `Books[0]` or `Books.0` to access the first element of the `Books` slice.\n\n### Filter Expressions\n\nFilter expressions allow you to query slices for elements that match specific\nconditions. They can be used both to get and set the value of the first matching\nelement. The syntax is:\n\n```go\n// Get value with filter\nbook = dipper.Get(library, \"Books[Title='Il nome della rosa']\")\nif err := dipper.Error(book); err != nil {\n    return err\n}\n\n// Get publication year\nyear := dipper.Get(library, \"Books[Title='Il nome della rosa'].Year\")\nif err := dipper.Error(year); err != nil {\n    return err\n}\n```\n\nAny primitive types can be used: string (using simple quotes), integer, float\nand boolean. Some examples:\n- `Books[Title='Dune']`\n- `Books[Year=1949]`\n- `Books[Available=true]`\n\nFilter expressions currently only support the equality operator (`=` or `==`).\n\n## Notes\n\n- This library works with reflection. It has been designed to have a good\n  trade-off between features and performance.\n- The only supported type for map keys is `string`. `map[interface{}]` is also\n  allowed if the underlying value is a `string`.\n- Errors are not returned explicitly in `Get()` and `GetMany()` to support\n  accessing multiple attributes at a time and getting a clear result. Instead,\n  error handling functions are provided.\n- Struct fields have to be exported, both for getting and setting. Trying to\n  access an unexported struct field will return `ErrUnexported`.\n- Using maps with keys containing your Dipper delimiter (or `.` if using the\n  convenience functions) is not supported for obvious reasons. If you're trying\n  to access a map with conflicting characters, use a custom `Dipper` with a\n  different field separator.\n\n### Future ideas\n\n- Case sensitivity option.\n- Tag option for struct fields.\n- Attribute expansion (e.g. `Books.*.Title`).\n- Custom object parser.\n- Option to access unexported fields.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflusflas%2Fdipper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflusflas%2Fdipper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflusflas%2Fdipper/lists"}