{"id":16389615,"url":"https://github.com/yuce/go-jacl","last_synced_at":"2025-10-15T12:32:38.165Z","repository":{"id":57652404,"uuid":"194532801","full_name":"yuce/go-jacl","owner":"yuce","description":"A module which implements Jacl, a straightforward, easy to write and easy to understand configuration language.","archived":false,"fork":false,"pushed_at":"2022-06-05T08:51:45.000Z","size":75,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-31T19:09:14.140Z","etag":null,"topics":["configuration","go","golang","jacl","language"],"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/yuce.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-06-30T15:38:52.000Z","updated_at":"2022-05-19T20:39:06.000Z","dependencies_parsed_at":"2022-08-25T16:02:17.178Z","dependency_job_id":null,"html_url":"https://github.com/yuce/go-jacl","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Fgo-jacl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Fgo-jacl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Fgo-jacl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Fgo-jacl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yuce","download_url":"https://codeload.github.com/yuce/go-jacl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238328522,"owners_count":19453844,"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":["configuration","go","golang","jacl","language"],"created_at":"2024-10-11T04:33:47.732Z","updated_at":"2025-10-15T12:32:33.131Z","avatar_url":"https://github.com/yuce.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://travis-ci.org/yuce/go-jacl\"\u003e\u003cimg src=\"https://api.travis-ci.org/yuce/go-jacl.svg?branch=master\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\u003ca href=\"https://coveralls.io/github/yuce/go-jacl?branch=master\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/yuce/go-jacl/badge.svg?branch=master\" alt=\"Coverage Status\" /\u003e\u003c/a\u003e\n\n# Go-Jacl\n\nThis module implements the base and the extended specifications of the [Jacl configuration language](https://github.com/yuce/jacl).\n\n## Change Log\n\n### 0.2.0 (2019-07-06)\n\n* Added `jacl.UnmarshalStruct` function, which unmarshals a struct from a `map[string]interface{}`. This is used to achieve [default struct values](#default-struct-values) and [unmarshaling from multiple texts](#unmarshaling-from-multiple-texts).\n* Added underflow and overflow checks for signed/unsigned integers and floats. See: [Field Underflow/Overflow](#field-underflow/overflow).\n\n### 0.1.0 (2019-06-30)\n\n* Initial release.\n\n## Installation\n\nRequirements:\n\n* Go 1.12 or better (not tried with versions below).\n\nThe following should be enough to install it:\n\n    go get github.com/yuce/go-jacl\n\n## Jacl Specification\n\nSee the [Jacl configuration language](https://github.com/yuce/jacl) for information about the configuration language.\n\n## Usage\n\nGo-Jacl has a single function, `jacl.Unmarshal`, to decode configuration from text into a `map[string]interface{}` or a pointer to a struct.\n\nExample:\n\n```go\ntext := `\n    // Sample configuration\n\n    bind: \"https://01.pilosa.local:10101\"\n    data-dir: \"/tmp/data\"\n\n    cluster: {\n        coordinator: true    \n    }\n\n    tls: {\n        certificate: \"pilosa.local.crt\"\n        key: \"pilosa.local.key\"\n        skip-verify: true\n    }\n\n    gossip: {\n        seeds: [\n            \"01.pilosa.local:15000\"\n            \"02.pilosa.local:15000\"\n        ]\n        port: 15000\n        key: \"pilosa.local.gossip32\"\n    }\n`\n\n// Decode to a map\nconfig := map[string]interface{}{}\nerr := jacl.Unmarshal(text, \u0026config)\nif err != nil {\n    // handle the error\n}\n\n// Decode to a struct\ntype ClusterConfig struct {\n    Coordinator     bool   `jacl:\"coordinator\"`\n    SomeLegacyField string `jacl:\"-\"` // This field is skipped.\n}\n\ntype TLSConfig struct {\n    CertificatePath string `jacl:\"certificate\"`\n    KeyPath         string `jacl:\"key\"`\n    SkipVerify      bool   `jacl:\"skip-verify\"`\n}\n\ntype GossipConfig struct {\n    Seeds   []string `jacl:\"seeds\"`\n    Port    int      `jacl:\"port\"`\n    KeyPath string   `jacl:\"key\"`\n}\n\ntype Config struct {\n    DataDir string        `jacl:\"data-dir\"`\n    Bind    string        `jacl:\"bind\"`\n    Cluster ClusterConfig `jacl:\"cluster\"`\n    TLS     TLSConfig     `jacl:\"tls\"`\n    Gossip  GossipConfig  `jacl:\"gossip\"`\n}\n\nconfig := Config{}\nerr := jacl.Unmarshal(text, \u0026config)\nif err != nil {\n    // handle the error\n}\n```\n\n## Decoding Into Structs\n\nWhen decoding into structs:\n\n* Only exported fields of the struct are considered.\n* All fields of the struct must have corresponding values in the configuration, otherwise an error is returned.\n* The field name must match the property/map key, unless `jacl:\"KEY_NAME\"` used in the field definition. In that case the configuration key `KEY_NAME` is matched to the corresponding field.\n* Use `jacl:\"-\"` in order to skip a field.\n\n### Supported Go Data Types\n\nThe following are the Go data types which are mapped from their Jacl counterparts. Note that trying to unmarshal to a field with a different type (e.g., a signed integer to `uint` vice versa, or a float to `int`) returns an error:\n\nJacl Type        | Go Type                | Allowed Field Types\n-----------------|------------------------|--------------------\nString           | string                 | string\nUnsigned integer | uint64                 | uint, uint8, uint16, uint32, uint64\nSigned integer   | int64                  | int, int8, int16, int32, int64\nFloat            | float64                | float32, float64\nBoolean          | bool                   | bool\nArray            | []interface{}          | []interface{}, []T\nMap              | map[string]interface{} | map[string]interface{}, map[string]T\n\nIn the table above `T` is one of `bool`, `string`, `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `float32`, `float64`.\n\n### Field Underflow/Overflow\n\nIf unmarshalling to a field underflows or overflows the chosen data type, then an error is returned:\n\n```go\ntype Config struct {\n    Number int8\n}\nconfig := Config{}\nerr := jacl.Unmarshal(\"Number: 128\", \u0026config)\n```\n\n`err` above is not `nil`, since 128 is bigger than math.MaxInt8.\n\n### Default Struct Values\n\nGo-Jacl requires every field of a struct to be set on unmarshal unless a field is skipped with `jacl:\"-\"`. So, if a property is missing in the configuration `jacl.Unmarshal` would return an error.\n\nConsider the following struct:\n\n```go\ntype C struct {\n    F1 string\n    F2 int\n}\n```\n\nIn order to have defaults for fields `F1` and `F2`, you can pass a map with defaults to `jacl.Unmarshal`:\n\n```go\ndefaults := map[string]interface{}{\n    \"F1\": \"default string\",\n    \"F2\": 54,\n}\n\ntext := `\n    F1: \"modified string\"\n`\nerr := jacl.Unmarshal(text, \u0026defaults)\nif err != nil {\n    // handle the error\n}\n```\n\nThe `defaults` map contains the following values after unmarshalling:\n\n```go\nmap[string]interface{}{\n    \"F1\": \"modified string\",\n    \"F2\": int64(54),\n}\n```\n\nSince the properties for all fields are set, we can pass that map to `jacl.UnmarshalStruct`:\n\n```go\nconfig := C{}\nerr = jacl.UnmarshalStruct(defaults, \u0026config)\nif err != nil {\n    t.Fatal(err)\n}\n```\n\nThe value of `config` is:\n\n```go\nC{\n    F1: \"modified string\",\n    F2: 54,\n}\n```\n\n### Unmarshaling From Multiple Texts\n\nSuppose we separated our configuration into multiple files since there are lots of properties to be set. Instead of having separate structs for each file, we want to have a single struct. We can use the same `jack.UnmarshalStruct` technique in the previous section to accomplish that.\n\nThis is the sample struct:\n\n```go\ntype C struct {\n    F1 string\n    F2 string\n    // ...\n    F9 string\n}\n```\n\nThese are the contents of the configuration files:\n\n```go\ntexts := []string{\n    `F1: \"field 1\"`,\n    `F2: \"field 2\"`,\n    // ...\n    `F9: \"field 9\"`,\n}\n```\n\nWe use the same map to unmarshal each text:\n\n```go\nprops := map[string]interface{}{}\nfor _, text := range texts {\n    err := jacl.Unmarshal(text, \u0026props)\n    if err != nil {\n        // handle the error\n    }\n}\n```\n\nFinally, unmarshal the map to a struct:\n\n```go\nconfig := C{}\nerr := jacl.UnmarshalStruct(props, \u0026config)\nif err != nil {\n    // handle the error\n}\n```\n\n## TODO\n\n* Maps of typed slices and slices of typed maps are not yet supported when unmarshalling struct fields. E.g., `Field1 []map[string]interface{}` is OK, but `Field2 []map[string]int` is not supported yet.\n\n## License\n\nCopyright (c) 2019-2021 Yuce Tekol. Licensed under [MIT](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuce%2Fgo-jacl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuce%2Fgo-jacl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuce%2Fgo-jacl/lists"}