Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/glguy/toml-parser
Haskell parser and printer for the TOML 1.0.0 file format
https://github.com/glguy/toml-parser
haskell toml
Last synced: 3 months ago
JSON representation
Haskell parser and printer for the TOML 1.0.0 file format
- Host: GitHub
- URL: https://github.com/glguy/toml-parser
- Owner: glguy
- License: isc
- Created: 2017-05-03T06:27:38.000Z (over 7 years ago)
- Default Branch: main
- Last Pushed: 2024-07-10T03:58:46.000Z (7 months ago)
- Last Synced: 2024-10-13T10:44:32.215Z (4 months ago)
- Topics: haskell, toml
- Language: Haskell
- Homepage: https://hackage.haskell.org/package/toml-parser
- Size: 399 KB
- Stars: 25
- Watchers: 7
- Forks: 7
- Open Issues: 0
-
Metadata Files:
- Readme: README.lhs
- Changelog: ChangeLog.md
- License: LICENSE
Awesome Lists containing this project
README
# TOML Parser
This package implements a validating parser for [TOML 1.0.0](https://toml.io/en/v1.0.0).
This package uses an [alex](https://haskell-alex.readthedocs.io/en/latest/)-generated
lexer and [happy](https://haskell-happy.readthedocs.io/en/latest/)-generated parser.It also provides a pair of classes for serializing into and out of TOML.
## Package Structure
```mermaid
---
title: Package Structure
---
stateDiagram-v2
classDef important font-weight:bold;TOML:::important --> ApplicationTypes:::important : decode
ApplicationTypes --> TOML : encode
TOML --> [Token]: Lexer
[Token] --> [Expr]: Parser
[Expr] --> Table : Semantics
Table --> ApplicationTypes : FromValue
ApplicationTypes --> Table : ToValue
Table --> TOML : Pretty
```Most users will only need to import **Toml** or **Toml.Schema**. Other top-level
modules are for low-level hacking on the TOML format itself. All modules below
these top-level modules are exposed to provide direct access to library implementation
details.- **Toml** - Basic encoding and decoding TOML
- **Toml.Schema** - TOML schemas for application types
- **Toml.Semantics** - Low-level semantic operations on TOML syntax
- **Toml.Syntax** - Low-level parsing of text into TOML raw syntax## Examples
This file uses [markdown-unlit](https://hackage.haskell.org/package/markdown-unlit)
to ensure that its code typechecks and stays in sync with the rest of the package.```haskell
{-# Language OverloadedStrings #-}
import Data.Text (Text)
import GHC.Generics (Generic)
import QuoteStr (quoteStr)
import Test.Hspec (Spec, hspec, it, shouldBe)
import Toml
import Toml.Schemamain :: IO ()
main = hspec (parses >> decodes >> encodes >> warns >> errors)
```### Using the raw parser
Consider this sample TOML text from the TOML specification.
```haskell
fruitStr :: Text
fruitStr = [quoteStr|
``````toml
[[fruits]]
name = "apple"[fruits.physical] # subtable
color = "red"
shape = "round"[[fruits.varieties]] # nested array of tables
name = "red delicious"[[fruits.varieties]]
name = "granny smith"[[fruits]]
name = "banana"[[fruits.varieties]]
name = "plantain"
``````haskell
|]
```Parsing using this package generates the following unstructured value
```haskell
parses :: Spec
parses = it "parses" $
forgetTableAnns <$> parse fruitStr
`shouldBe`
Right (table [
("fruits", List [
Table (table [
("name", Text "apple"),
("physical", Table (table [
("color", Text "red"),
("shape", Text "round")])),
("varieties", List [
Table (table [("name", Text "red delicious")]),
Table (table [("name", Text "granny smith")])])]),
Table (table [
("name", Text "banana"),
("varieties", List [
Table (table [("name", Text "plantain")])])])])])
```### Defining a schema
We can define a schema for our TOML format in the form of instances of
`FromValue`, `ToValue`, and `ToTable` in order to read TOML directly
into structured data form. This example manually derives some of the
instances as a demonstration.```haskell
newtype Fruits = Fruits { fruits :: [Fruit] }
deriving (Eq, Show, Generic)
deriving (ToTable, ToValue, FromValue) via GenericTomlTable Fruitsdata Fruit = Fruit { name :: String, physical :: Maybe Physical, varieties :: [Variety] }
deriving (Eq, Show, Generic)
deriving (ToTable, ToValue, FromValue) via GenericTomlTable Fruitdata Physical = Physical { color :: String, shape :: String }
deriving (Eq, Show, Generic)
deriving (ToTable, ToValue, FromValue) via GenericTomlTable Physicalnewtype Variety = Variety String
deriving (Eq, Show)instance FromValue Variety where
fromValue = parseTableFromValue (Variety <$> reqKey "name")
instance ToValue Variety where
toValue = defaultTableToValue
instance ToTable Variety where
toTable (Variety x) = table ["name" .= x]```
We can run this example on the original value to deserialize it into domain-specific datatypes.
```haskell
decodes :: Spec
decodes = it "decodes" $
decode fruitStr
`shouldBe`
Success [] (Fruits [
Fruit
"apple"
(Just (Physical "red" "round"))
[Variety "red delicious", Variety "granny smith"],
Fruit "banana" Nothing [Variety "plantain"]])encodes :: Spec
encodes = it "encodes" $
show (encode (Fruits [Fruit
"apple"
(Just (Physical "red" "round"))
[Variety "red delicious", Variety "granny smith"]]))
`shouldBe` [quoteStr|
[[fruits]]
name = "apple"[fruits.physical]
color = "red"
shape = "round"[[fruits.varieties]]
name = "red delicious"[[fruits.varieties]]
name = "granny smith"|]
```### Useful errors and warnings
This package takes care to preserve source information as much as possible
in order to provide useful feedback to users. These examples show a couple
of the message that can be generated when things don't go perfectly.```haskell
warns :: Spec
warns = it "warns" $
decode [quoteStr|
name = "simulated"
typo = 10|]
`shouldBe`
Success
["2:1: unexpected key: typo in "] -- warnings
(Variety "simulated")errors :: Spec
errors = it "errors" $
decode [quoteStr|
# Physical characteristics table
color = "blue"
shape = []|]
`shouldBe`
(Failure
["3:9: expected string but got array in shape"]
:: Result String Physical)
```## More Examples
A demonstration of using this package at a more realistic scale
can be found in [HieDemoSpec](test/HieDemoSpec.hs). The various unit
test files demonstrate what you can do with this library and what
outputs you can expect.See the low-level operations used to build a TOML syntax highlighter
in [TomlHighlighter](test-drivers/highlighter/Main.hs).