{"id":15046118,"url":"https://github.com/lyraproj/dgo","last_synced_at":"2025-10-26T02:31:12.350Z","repository":{"id":56162338,"uuid":"206105183","full_name":"lyraproj/dgo","owner":"lyraproj","description":"Dynamic Type Library for Go","archived":false,"fork":false,"pushed_at":"2020-11-29T13:41:33.000Z","size":1162,"stargazers_count":8,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-31T13:43:30.506Z","etag":null,"topics":["dgo","golang","golang-library","golang-module","golang-package","json","yaml"],"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/lyraproj.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":"2019-09-03T15:03:48.000Z","updated_at":"2022-08-21T23:13:55.000Z","dependencies_parsed_at":"2022-08-15T13:50:47.089Z","dependency_job_id":null,"html_url":"https://github.com/lyraproj/dgo","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyraproj%2Fdgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyraproj%2Fdgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyraproj%2Fdgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyraproj%2Fdgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lyraproj","download_url":"https://codeload.github.com/lyraproj/dgo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238247984,"owners_count":19440879,"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":["dgo","golang","golang-library","golang-module","golang-package","json","yaml"],"created_at":"2024-09-24T20:52:43.952Z","updated_at":"2025-10-26T02:31:11.856Z","avatar_url":"https://github.com/lyraproj.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dgo (Dynamic Go)\n\n[![](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![](https://goreportcard.com/badge/github.com/lyraproj/dgo)](https://goreportcard.com/report/github.com/lyraproj/dgo)\n[![](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/lyraproj/dgo)\n[![](https://github.com/lyraproj/dgo/workflows/Dgo%20Test/badge.svg)](https://github.com/lyraproj/dgo/actions)\n[![](https://coveralls.io/repos/github/lyraproj/dgo/badge.svg)](https://coveralls.io/github/lyraproj/dgo)\n\nDgo's main objectives are: Type Constraints, Immutability, Collections, Serialization, Encapsulation, Extendability,\nand Performance. It is designed to make working with dynamic values an effortless and type safe task.\n\n## Install\nDgo is a go module and if the Go version is \u003c 1.13, go modules must be enabled. This is done by setting the environment\nvariable GO111MODULE=on before an attempt is made to install:\n```sh\nexport GO111MODULE=on\n```\n### Using dgo as a library\nTo use dgo, first install the latest version of the library:\n```sh\ngo get github.com/lyraproj/dgo\n```\nNext, include needed packages in your application. Pick what you need from the following packages:\n```go\nimport (\n  \"github.com/lyraproj/dgo/dgo\"\n  \"github.com/lyraproj/dgo/typ\"\n  \"github.com/lyraproj/dgo/tf\"\n  \"github.com/lyraproj/dgo/vf\"\n)\n```\n\n## Type Constraints\n\n### Dgo types versus Go's native types\nGo is a typed language but the types are not very descriptive. It is for instance not possible to declare a type\nthat corresponds only to a specific range of integers, a string that must confirm to a specific pattern. All such\nconstraints must be expressed as code wherever a value of the type is assigned. In dgo a type describing a range\nof integers can be declared as `0..15` and a pattern constrained string can be declared as `/^[a-z]+$/`.\n\nIt is also not possible to declare type combinations such as a slice that can contain only integers or floats. If\na value can be of more than one of go's native types, then it must be declared as an `interface{}` which corresponds\nto every possible value in the system. This means that a slice containing ints and floats must be declared as\n`[]interface{}` wich is a declaration of a slice that may contain any type of value. In dgo, such a type can be\ndeclared as `[](int|float)`. Other examples:\n \n- `map[string](string|int)` (string keyed map of string\n- `[]0..15` (slice of integers ranging from 0 - 15).\n- `\"red\"|\"green\"|\"blue\"` (enumeration of strings)\n- `2|8|10|16` (enumeration of integers)\n\nDgo is influenced by restrictive type constraint languages such as:\n- [CUE](https://cue.googlesource.com/cue/+/HEAD/doc/ref/spec.md)\n- [TypeScript](https://www.typescriptlang.org/docs/handbook/basic-types.html)\n- [Python Type Hints](https://www.python.org/dev/peps/pep-0484/)\n- [Puppet Types](/puppetlabs/puppet-specifications/blob/master/language/types_values_variables.md)\n\n### Language syntax\nDgo defines a [type language of its own](docs/types.md) which is designed to be close to Go itself. A parser\nand a stringifier are provided for this syntax. New parsers and stringifiers can be added to support other syntaxes. \n\n### Type Assignability\nAs with go reflect, types can be compared for assignability. A type is assignable from another type if the other\ntype is equally or more restricitive, e.g. the type `int` is assignable from the range `0..10` (and all other\ninteger ranges). The type `string` is assignable from the pattern `/abc/`, the type `\"a\"|\"b\"|\"c\"` or\nany other type that restricts a string. A length constrained `string[10,20]` is assignable from `string[12,17]`, etc.\n\n### Type Instance check\nA type can be used to validate if a value is an instance of that type. The integer `3` is an instance of the\nrange type `1..8`, the string `\"abc\"` is an instance of the pattern type `/b/`, etc.\n\n### The type of a value\nAll values have a type that is backed by the value itself. The type will consider its value, and only that value,\nto be an instance of itself. E.g. string \"hello\" is represented by the type `\"hello\"`. That type in turn is assignable\nto `string`, `string[5]`, `string[0,10]`, `\"hello\"|\"goodbye\"`, but it is not assignable to `string[0,4]` or\n`\"hi\"|\"bye\"`. In other words, the value type is assignable to another type if the value that it represents is an\ninstance of that other type.\n\n#### Collection types\nThe type of a collection is just a cast of the collection itself and hence, will change dynamically when the collection\nis modified.\n\n## Immutability\n\nNon primitives in Go (array, slice, map, struct) are mutable and it's the programmers responsibility to ensure that\naccess to such values are synchronized when they are accessed from multiple go routines.\n\nDgo guarantees that all values can be 100% immutable by exposing all values through interfaces and hiding the\nimplementation, thus enabling concurrency safe coding without the need to synchronized use of shared resources\nusing mutexes.\n\nAn`Array` or a `Map` can be created as a mutable collection but can be made immutable by calling the method `Freeze()`\nor `Copy(true)` (argument `true` requests a frozen copy). Both calls are recursive and ensures that the collection\nand all its contained values are frozen. `Freeze` performs an in-place recursive freeze of all values while `Copy`\nwill copy unfrozen objects before freezing them to ensure that the original and all its contained values\nare not frozen as a consequence of the call.\n\nA frozen object can never be unfrozen. The only way to resume mutability is to do `Copy(false)` which returns a\nmutable copy.\n\n## Serialization\nSupport for JSON is built in to Dgo. YAML support is provided by the [dgoyaml](https://github.com/lyraproj/dgoyaml)\nmodule which also provides a CLI validate parameter types. Support for [gob](https://golang.org/pkg/encoding/gob/) is in\nthe pipeline.\n\nTransformations between dgo and [cty](https://github.com/zclconf/go-cty) is provided by the\n[dgocty](https://github.com/lyraproj/dgocty) module \n\nTransformations between dgo and [pcore](https://github.com/lyraproj/pcore) is provided by the\n[pcore](https://github.com/lyraproj/dgopcore) module \n\n## Encapsulation\n\nIt's often desirable to encapsulate common behavior of values in a way that relieves the programmer from trivial\nconcerns. For instance:\n\n- In Go, you cannot define a generic behavior for equality comparison. It's either `==` or `reflect.DeepEqual()`\n and both have limitations. `==` cannot compare slices or structs containing slices. The DeepEqual method compares\n _all_ fields of a struct, exported and unexported. Dgo solves this by letting all values implement the `Equals()`\n method. This method is then used throughout the Dgo framework.\n- Go has no concept of a hash code. Keys in hashes may only be values that are considered comparable on Go. Dgo\nsolves this by letting all values implement the `HashCode()` method. The hash code can be used for several purposes,\nincluding map keys and computing unique sets of values.\n- Since Go has generic value (besides the `interface{}`, it provides no way to specify generic natural ordering. Dgo\n provides a `Comparable` interface.\n\n## Extendability\n\nThe functionality of the Dgo basic types is exposed through interfaces to enable the type/value system to be expanded.\n\n## Performance\n\nDgo is designed with performance in mind. The Map implementation is, although it's generic, actually faster\nthan a `map[string]interface{}`. It is a lot faster than a `map[interface{}]interface{}` required if you want to\nuse dynamic keyes with Go. Nevertheless, the Dgo Map can use any value as a key, even arrays, maps, and types.\n\nThe dgo.Value implementation for primitives like Bool, Integer, and Float are just redefined Go types, and as such,\nthey consume the same amount of memory and reuses the same logic i.e.: \n```go\ntype integer int64 // implements dgo.Integer\ntype float float64 // implements dgo.Float\ntype boolean bool  // implements dgo.Boolean\n```\n\nThe dgo.String is different because it caches the hash code once it has been computed. A string is stored as:\n```go\ntype hstring struct {\n  s string\n  h int\n}\n```\n\n## How to get involved\nWe value your opinion very much. Please don't hesitate to reach out. Opinions, ideas, and contributions are more\nthan welcome. Ping us on the [Puppet Cloudnative Slack](https://app.slack.com/client/T0AQJ2CTU/CHPSJ9L4F), create\nan [issue](../../issues), or file a [PR](../../pulls). \n\n## Pipeline\n- dgo annotations for go struct members, e.g.\n    ```go\n    type Input struct {\n      Variables map[string]interface{} `dgo:\"map[string]dgo\"`\n      Parameters map[string]interface{} `dgo:\"map[string]{name: string[1], type: dgo, required?: bool}\"`\n    }\n    ```\n- Go [gob](https://golang.org/pkg/encoding/gob/) support to enable full binary exchange of values and types.\n- Distributed type aliases (aliases using URI reference)\n- Type extension, i.e. how a type such as a map with explicit associations can be extended by another type.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyraproj%2Fdgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flyraproj%2Fdgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyraproj%2Fdgo/lists"}