{"id":38268506,"url":"https://github.com/askretov/mutable","last_synced_at":"2026-01-17T01:48:16.005Z","repository":{"id":144211468,"uuid":"150587399","full_name":"askretov/mutable","owner":"askretov","description":"Mutable package provides object changes tracking features and the way to set values to the struct dynamically by the destination field name (including nested structs)","archived":false,"fork":false,"pushed_at":"2020-05-14T23:32:36.000Z","size":30,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-22T13:06:06.417Z","etag":null,"topics":["analysis","change-detection","change-tracker","golang","mutable","nested-structs"],"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/askretov.png","metadata":{"files":{"readme":"README.md","changelog":"changedField.go","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}},"created_at":"2018-09-27T12:59:52.000Z","updated_at":"2024-12-17T16:12:49.000Z","dependencies_parsed_at":"2023-09-25T00:43:08.406Z","dependency_job_id":null,"html_url":"https://github.com/askretov/mutable","commit_stats":{"total_commits":24,"total_committers":1,"mean_commits":24.0,"dds":0.0,"last_synced_commit":"47c21dc724979a9e6e804fa4b3daf08072deca62"},"previous_names":["askretov/go-mutable"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/askretov/mutable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askretov%2Fmutable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askretov%2Fmutable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askretov%2Fmutable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askretov%2Fmutable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/askretov","download_url":"https://codeload.github.com/askretov/mutable/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askretov%2Fmutable/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28491639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T00:50:05.742Z","status":"ssl_error","status_checked_at":"2026-01-17T00:43:11.982Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["analysis","change-detection","change-tracker","golang","mutable","nested-structs"],"created_at":"2026-01-17T01:48:15.863Z","updated_at":"2026-01-17T01:48:15.978Z","avatar_url":"https://github.com/askretov.png","language":"Go","readme":"# Mutable\n[![Go Report Card](https://goreportcard.com/badge/github.com/askretov/go-mutable)](https://goreportcard.com/report/github.com/askretov/go-mutable)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/1c52c7899e544969b1d83896dbc2b9c4)](https://www.codacy.com/app/askretov/go-mutable?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=askretov/mutable\u0026amp;utm_campaign=Badge_Grade)\n[![codecov](https://codecov.io/gh/askretov/mutable/branch/master/graph/badge.svg)](https://codecov.io/gh/askretov/mutable)\n[![Build Status](https://travis-ci.org/askretov/mutable.svg?branch=master)](https://travis-ci.org/askretov/mutable)\n[![GoDoc](https://godoc.org/github.com/askretov/mutable?status.svg)](https://godoc.org/github.com/askretov/mutable)\n[![Licenses](https://img.shields.io/badge/license-mit-brightgreen.svg)](https://opensource.org/licenses/BSD-3-Clause)\n\n## Introduction\nMutable package provides object changes tracking features and the way to set values to the struct dynamically by a destination field name (including nested structs).\\\nThis package needs Go version 1.9 or later\n\n## Usage\n### Installation\n```go\ngo get github.com/askretov/go-mutable\n```\n### Embedding Mutable\n```go\npackage main\n\nimport \"github.com/askretov/mutable\"\n\ntype NestedStruct struct {\n\tmutable.Mutable\n\tFieldY string\n\tFieldZ []int64\n}\n\ntype MyStruct struct {\n\tmutable.Mutable\n\tFieldA string\n\tFieldB int64        `mutable:\"ignored\"`\n\tFieldC NestedStruct `mutable:\"deep\"`\n}\n\nfunc main() {\n    var m = \u0026MyStruct{}\n    // Mutable state init\n    m.ResetMutableState(m)\n}\n```\n### Tracking changes\n```go\n// Change values\nm.FieldA = \"green\"\nm.FieldC.FieldY = \"stone\"\n// Analyze changes\nfmt.Println(m.AnalyzeChanges())\n```\n*Output:*\n```json\n{\n        \"FieldA\": {\n                \"old_value\": \"\",\n                \"new_value\": \"green\"\n        },\n        \"FieldC\": {\n                \"nested_fields\": {\n                        \"FieldY\": {\n                                \"old_value\": \"\",\n                                \"new_value\": \"stone\"\n                        }\n                }\n        }\n}\n```\n### Set values dynamically\n```go\n// Set values\nm.SetValue(\"FieldA\", \"white\")\nm.SetValue(\"FieldC/FieldZ\", \"[1,2,3]\") // You can set typed value or JSON string as well\n// Analyze changes\nfmt.Println(m.AnalyzeChanges())\n```\n*Output:*\n```json\n{\n        \"FieldA\": {\n                \"old_value\": \"green\",\n                \"new_value\": \"white\"\n        },\n        \"FieldC\": {\n                \"nested_fields\": {\n                        \"FieldZ\": {\n                                \"old_value\": null,\n                                \"new_value\": [1, 2, 3]\n                        }\n                }\n        }\n}\n```\n### Optional settings - Struct tags\nStruct field's tag values should be set within **mutable** tag\n-   ***ignored*** - specifies ignoring of this field changes tracking\n-   ***deep*** - specifies the deep analyze of a field (only for struct kind fields). Instead of regular analysis of a field value itself, every field of nested struct will be analyzed for changes individually.\n\nExample:\n```go\ntype MyStruct struct {\n    mutable.Mutable\n    FieldA string `mutable:\"ignored\"`\n    FieldB AnotherStructType `mutable:\"deep\"`\n}\n```\n\n### Keep in mind\n1.  If you use a pointer to struct as field type and want to be able to use **deep** analysis, you have to embed Mutable for such nested field's struct as well.\n\n    Example:\n    ```go\n    type MyStruct struct {\n        mutable.Mutable\n        FieldA string\n        FieldB *NestedStruct `mutable:\"deep\"`\n    }\n\n    type NestedStruct struct {\n        mutable.Mutable // Mutable as well\n        FieldY string\n        FieldZ string\n    }\n    ```\n2. If you pass a mutable object as an arg to a function, you have to pass it as a pointer to be able to use Mutable features.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskretov%2Fmutable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faskretov%2Fmutable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskretov%2Fmutable/lists"}