{"id":16661797,"url":"https://github.com/brandonchinn178/toml-reader","last_synced_at":"2026-03-10T18:32:10.067Z","repository":{"id":38177376,"uuid":"484900112","full_name":"brandonchinn178/toml-reader","owner":"brandonchinn178","description":"Haskell library for parsing v1.0 TOML files","archived":false,"fork":false,"pushed_at":"2025-04-22T05:58:49.000Z","size":166,"stargazers_count":16,"open_issues_count":6,"forks_count":8,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-21T21:56:24.736Z","etag":null,"topics":["haskell","toml"],"latest_commit_sha":null,"homepage":"https://hackage.haskell.org/package/toml-reader","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brandonchinn178.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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,"zenodo":null}},"created_at":"2022-04-24T01:58:37.000Z","updated_at":"2025-04-22T05:48:20.000Z","dependencies_parsed_at":"2025-04-22T05:29:12.764Z","dependency_job_id":"837b0f7f-8e81-4181-8dc7-863a682947b1","html_url":"https://github.com/brandonchinn178/toml-reader","commit_stats":{"total_commits":95,"total_committers":5,"mean_commits":19.0,"dds":"0.052631578947368474","last_synced_commit":"5ca7a154af8ceaf93f37a943d07949dbcf67bc80"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/brandonchinn178/toml-reader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandonchinn178%2Ftoml-reader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandonchinn178%2Ftoml-reader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandonchinn178%2Ftoml-reader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandonchinn178%2Ftoml-reader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brandonchinn178","download_url":"https://codeload.github.com/brandonchinn178/toml-reader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandonchinn178%2Ftoml-reader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30347404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T15:55:29.454Z","status":"ssl_error","status_checked_at":"2026-03-10T15:54:58.440Z","response_time":106,"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":["haskell","toml"],"created_at":"2024-10-12T10:36:08.955Z","updated_at":"2026-03-10T18:32:10.038Z","avatar_url":"https://github.com/brandonchinn178.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# toml-reader\n\n[![GitHub Actions](https://img.shields.io/github/actions/workflow/status/brandonchinn178/toml-reader/ci.yml?branch=main)](https://github.com/brandonchinn178/toml-reader/actions?query=branch%3Amain)\n[![](https://img.shields.io/codecov/c/gh/brandonchinn178/toml-reader)](https://app.codecov.io/gh/brandonchinn178/toml-reader)\n[![](https://img.shields.io/hackage/v/toml-reader)](https://hackage.haskell.org/package/toml-reader)\n\nTOML format parser compliant with [v1.0.0](https://toml.io/en/v1.0.0) (verified with the [`toml-test`](https://github.com/BurntSushi/toml-test) tool).\n\n## Usage\n\n```hs\n{-# LANGUAGE OverloadedStrings #-}\n\nimport TOML (DecodeTOML, tomlDecoder, getField, decodeFile)\n\ndata MyConfig = MyConfig\n  { field1 :: Int\n  , field2 :: Bool\n  } deriving (Show)\n\ninstance DecodeTOML MyConfig where\n  tomlDecoder =\n    MyConfig\n      \u003c$\u003e getField \"field1\"\n      \u003c*\u003e getField \"field2\"\n\nmain :: IO ()\nmain = do\n  result \u003c- decodeFile \"config.toml\"\n  case result of\n    Right cfg -\u003e print (cfg :: MyConfig)\n    Left e -\u003e print e\n```\n\n## Design decisions\n\n* Only supports reading, not writing, since TOML is lossy. For example, a simple `a.b.c = 1` line could be written in a number of ways:\n\n    ```toml\n    a.b.c = 1\n    a.b = { c = 1 }\n    a = { b.c = 1 }\n\n    [a]\n    b.c = 1\n    b = { c = 1 }\n\n    [a.b]\n    c = 1\n    ```\n\n    Since reading/writing isn't an idempotent operation, this library won't even pretend to provide `DecodeTOML`/`EncodeTOML` typeclasses that imply that they're inverses of each other.\n\n    Hopefully some other `toml-writer` library may come along to make it easy to specify how to format your data in TOML (e.g. a combinator for `table` vs `inlineTable`), or you could use [`tomland`](https://github.com/kowainik/tomland).\n\n* This library defines `DecodeTOML` with an opaque `Decoder a` as opposed to a `Value -\u003e DecodeM a` function, like `aeson` does. In my opinion, this makes the common case of decoding config files much more straightforward, especially around nested fields, which are much more common in TOML than JSON. e.g.\n\n    ```hs\n    -- aeson-like\n    instance DecodeTOML MyConfig where\n      decodeTOML :: Value -\u003e DecodeM MyConfig\n      decodeTOML = withObject \"MyConfig\" $ \\o -\u003e\n        MyConfig\n          \u003c$\u003e o .: \"field1\"\n          \u003c*\u003e (o .: \"field2\" \u003e\u003e= (.: \"field3\"))\n    ```\n\n    ```hs\n    -- with toml-parser\n    instance DecodeTOML MyConfig where\n      tomlDecoder :: Decoder MyConfig\n      tomlDecoder =\n        MyConfig\n          \u003c$\u003e getField \"field1\"\n          \u003c*\u003e getFields [\"field2\", \"field3\"]\n    ```\n\n    It also makes it easy to define ad-hoc decoders:\n\n    ```hs\n    instance DecodeTOML MyConfig where\n      tomlDecoder = ...\n\n    alternativeDecoder :: Decoder MyConfig\n    alternativeDecoder = ...\n\n    -- uses tomlDecoder\n    decode \"a = 1\"\n\n    -- uses explicit decoder\n    decodeWith alternativeDecoder \"a = 1\"\n    ```\n\n    As a bonus, it also makes for a less point-free interface when defining a decoder based on another decoder, which is kinda cool:\n\n    ```hs\n    -- aeson-like\n    instance DecodeTOML MyString where\n      decodeTOML = fmap toMyString . decodeTOML\n    ```\n\n    ```hs\n    -- with toml-parser\n    instance DecodeTOML MyString where\n      tomlDecoder = toMyString \u003c$\u003e tomlDecoder\n    ```\n\n    Ultimately, `Decoder` is just a newtype around `Value -\u003e DecodeM a`, so we could always go back to it. Originally, I wanted to do something like [`jordan`](https://hackage.haskell.org/package/jordan), where this interface is required due to the way it parses and deserializes at the same time, but this isn't possible with TOML due to the way TOML needs to be normalized.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandonchinn178%2Ftoml-reader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrandonchinn178%2Ftoml-reader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandonchinn178%2Ftoml-reader/lists"}