### Complete Application Configuration Example Source: https://github.com/kowainik/tomland/blob/main/_autodocs/generic-codec.md This example demonstrates a full application configuration setup, including leaf types, collection types, and the root type, with all necessary `HasCodec` and `HasItemCodec` instances derived generically. It also shows how to decode a TOML file. ```haskell # LANGUAGE DeriveGeneric # LANGUAGE OverloadedStrings import GHC.Generics (Generic) import Data.Text (Text) import Data.Time (Day) import qualified Toml -- Leaf types data Credentials = Credentials { username :: Text , password :: Text } deriving (Generic) instance Toml.HasCodec Credentials where hasCodec = Toml.table Toml.genericCodec -- Collection type data Server = Server { hostname :: Text , port :: Int } deriving (Generic) instance Toml.HasItemCodec Server where hasItemCodec = Right Toml.genericCodec -- Root type data ApplicationConfig = ApplicationConfig { appName :: Text , version :: String , credentials :: Credentials , servers :: [Server] , launchDate :: Day } deriving (Generic) instance Toml.HasCodec ApplicationConfig where hasCodec = Toml.table Toml.genericCodec -- Use it appCodec :: Toml.TomlCodec ApplicationConfig appCodec = Toml.genericCodec main :: IO () main = do tomlText <- readFile "app.toml" case Toml.decode appCodec tomlText of Left errs -> putStrLn $ Toml.prettyTomlDecodeErrors errs Right config -> print config ``` -------------------------------- ### Encoding and Decoding Examples Source: https://github.com/kowainik/tomland/blob/main/_autodocs/README.md Demonstrates decoding TOML from text and a file, and encoding to text and a file using a defined codec. ```haskell -- Decode from text case Toml.decode userCodec tomlText of Left errs -> putStrLn $ "Errors: " ++ show errs Right user -> print user -- Decode from file user <- Toml.decodeFile userCodec "config.toml" -- Encode to text let tomlText = Toml.encode userCodec user -- Encode to file Toml.encodeToFile userCodec "config.toml" user ``` -------------------------------- ### Compose BiMaps Example Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Demonstrates how to compose two BiMap instances using the (.) operator, creating a combined mapping from the composition of individual mappings. ```haskell -- Compose bimaps let combined = mapB . mapA ``` -------------------------------- ### TOML Configuration Example Source: https://github.com/kowainik/tomland/blob/main/README.md This TOML file defines a server configuration with nested tables and arrays of tables, including various data types like integers, strings, booleans, and dates. ```toml server.port = 8080 server.codes = [ 5, 10, 42 ] server.description = """ This is production server. Don't touch it! """ [mail] host = "smtp.gmail.com" send-if-inactive = false [[user]] guestId = 42 [[user]] guestId = 114 [[user]] login = "Foo Bar" createdAt = 2020-05-19 ``` -------------------------------- ### Invert BiMap Example Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Shows how to use the 'invert' function to create a reverse mapping. This example inverts a BiMap that converts Int to Text, resulting in a BiMap that converts Text to Int. ```haskell -- If you have a bimap from Int to Text intToText :: BiMap e Int Text -- Create the reverse textToInt :: BiMap e Text Int textToInt = Toml.invert intToText ``` -------------------------------- ### TOML Input for Composition Example Source: https://github.com/kowainik/tomland/blob/main/_autodocs/examples-and-patterns.md This is the TOML input corresponding to the nested structure defined in the 'Composition' example. ```toml port = 8080 [logger] level = "debug" [cache] ttl = 3600 ``` -------------------------------- ### Customizing Field Names with Manual Codec Source: https://github.com/kowainik/tomland/blob/main/_autodocs/generic-codec.md Illustrates how to customize TOML keys when generic codecs use exact field names. This example shows a manual HasCodec instance to map 'myField' to 'my-field'. ```haskell data Config = Config { myField :: Int } deriving (Generic) -- Default: key is "myField" -- To use key "my-field": instance HasCodec Config where hasCodec = Toml.table (Config <$> Toml.int "my-field" .= myField ) "config" ``` -------------------------------- ### Provide HasCodec Instance for Complex Types Source: https://github.com/kowainik/tomland/blob/main/_autodocs/generic-codec.md When working with types that do not have built-in `HasCodec` or `HasItemCodec` instances, you must provide them manually. This example shows how to define a codec for `Data.Time.Day`. ```haskell import Data.Time (Day) data Event = Event { name :: String , date :: Day } deriving (Generic) instance Toml.HasCodec Event where hasCodec = Toml.table (Event <$> Toml.string "name" .= name <*> Toml.day "date" .= date ) "event" ``` -------------------------------- ### Manual Codec Definition Source: https://github.com/kowainik/tomland/blob/main/_autodocs/generic-codec.md Example of manually defining a codec for a User type. This is the boilerplate that generic codecs aim to eliminate. ```haskell userCodec :: TomlCodec User userCodec = User <$> Toml.text "name" .= name <*> Toml.int "age" .= age <*> Toml.text "email" .= email ``` -------------------------------- ### Performing a TOML Encode/Decode Round-Trip Test Source: https://github.com/kowainik/tomland/blob/main/_autodocs/examples-and-patterns.md This example demonstrates how to test the integrity of a TOML codec by encoding a value and then decoding it back. It verifies that the encoding and decoding process is symmetrical. ```haskell {-# LANGUAGE OverloadedStrings #} import qualified Toml import Data.Text (pack) data Config = Config { port :: Int } deriving (Eq, Show) configCodec :: Toml.TomlCodec Config configCodec = Config <$> Toml.int "port" .= port roundTripTest :: Config -> Bool roundTripTest cfg = case Toml.decode configCodec (Toml.encode configCodec cfg) of Right cfg' -> cfg' == cfg Left _ -> False main :: IO () main = do let cfg = Config 8080 if roundTripTest cfg then putStrLn "Round-trip test passed" else putStrLn "Round-trip test failed" ``` -------------------------------- ### Generic Codec Definition Source: https://github.com/kowainik/tomland/blob/main/_autodocs/generic-codec.md Example of defining a codec for a User type using the genericCodec function. This significantly reduces boilerplate. ```haskell userCodec :: TomlCodec User userCodec = genericCodec ``` -------------------------------- ### Haskell Language Extensions and Imports Source: https://github.com/kowainik/tomland/blob/main/README.md Specifies necessary language extensions and imports for a literate Haskell file using the tomland library. Ensure all required packages are installed. ```haskell {-# OPTIONS -Wno-unused-top-binds #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} import Control.Applicative ((<|>)) import Data.Text (Text) import Data.Time (Day) import Toml (TomlCodec, (.=)) import qualified Data.Text.IO as TIO import qualified Toml ``` -------------------------------- ### Preventing Typos with Type Safety Source: https://github.com/kowainik/tomland/blob/main/_autodocs/errors-reference.md Illustrates how to prevent errors caused by string key typos during codec definition. Using lenses or prisms (as shown in the 'Good' example) allows for compile-time checking of field names. ```haskell -- Bad: String keys prone to typos myCodec = MyType <*> Toml.int "port" .= port <*> Toml.int "prot" .= protocol -- Typo! -- Good: Catch at compile time with lenses/prisms myCodec = MyType <*> Toml.int "port" .= port <*> Toml.int "protocol" .= protocol ``` -------------------------------- ### Applying Default Values to TOML Configuration Source: https://github.com/kowainik/tomland/blob/main/_autodocs/examples-and-patterns.md Demonstrates how to load TOML configuration while applying default values for missing fields. The `dioptional` combinator is recommended for handling optional fields gracefully. ```haskell {-# LANGUAGE OverloadedStrings #} import qualified Toml data Config = Config { timeout :: Int , retries :: Int } deriving (Show) configCodec :: Toml.TomlCodec Config configCodec = Config <$> Toml.int "timeout" .= timeout <*> Toml.int "retries" .= retries withDefaults :: Config -> Config -> Config withDefaults defaults partial = Config { timeout = timeout partial , retries = retries partial } loadConfigWithDefaults :: String -> Config -> Either [Toml.TomlDecodeError] Config loadConfigWithDefaults toml defaults = Toml.decode configCodec toml main :: IO () main = do let defaults = Config 30 3 let userToml = "timeout = 60" -- Only override timeout -- Note: This won't work directly because retries is required -- Better to use Maybe + dioptional: let betterCodec = Config <$> Toml.int "timeout" .= timeout <*> Toml.dioptional (Toml.int "retries") .= (const defaults . retries) ``` ```haskell data ConfigInput = ConfigInput { timeoutMaybe :: Maybe Int , retriesMaybe :: Maybe Int } configInputCodec :: Toml.TomlCodec ConfigInput configInputCodec = ConfigInput <$> Toml.dioptional (Toml.int "timeout") .= timeoutMaybe <*> Toml.dioptional (Toml.int "retries") .= retriesMaybe applyDefaults :: Config -> ConfigInput -> Config applyDefaults defaults input = Config { timeout = maybe (timeout defaults) id (timeoutMaybe input) , retries = maybe (retries defaults) id (retriesMaybe input) } ``` -------------------------------- ### Qualified Import for Tomland Library Source: https://github.com/kowainik/tomland/blob/main/README.md Demonstrates the recommended way to import the tomland library for qualified usage. Optional imports for TomlBiMap and Key can be added. ```haskell import Toml (TomlCodec, (.=)) -- add 'TomlBiMap' and 'Key' here optionally import qualified Toml ``` -------------------------------- ### Load and Save Configuration with Error Handling Source: https://github.com/kowainik/tomland/blob/main/_autodocs/examples-and-patterns.md Loads configuration from a TOML file, handling potential loading errors by providing default values. Saves the configuration back to a file. ```haskell {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} import Control.Exception (catch) import qualified Toml import GHC.Generics (Generic) data Config = Config { port :: Int, host :: String } deriving (Show, Generic) configCodec :: Toml.TomlCodec Config configCodec = Config <*> Toml.int "port" .= port <*> Toml.string "host" .= host loadConfig :: FilePath -> IO Config loadConfig path = Toml.decodeFile configCodec path `catch` \(Toml.LoadTomlException file msg) -> do putStrLn $ "Failed to load " ++ file putStrLn $ "Error: " ++ show msg return $ Config 8080 "localhost" saveConfig :: FilePath -> Config -> IO () saveConfig path cfg = do content <- Toml.encodeToFile configCodec path cfg putStrLn $ "Saved config to " ++ path main :: IO () main = do cfg <- loadConfig "config.toml" putStrLn $ "Loaded: " ++ show cfg saveConfig "config.toml" cfg ``` -------------------------------- ### Using Codecs vs. Direct AST Processing Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Compares the recommended method of decoding TOML using codecs with the direct AST processing approach. Codecs are preferred for working with typed values. ```haskell -- Instead of: case Toml.parse text of Right ast -> ...process AST... -- Do this: case Toml.decode codec text of Right value -> ...process typed value... ``` -------------------------------- ### Validating at Codec Level Source: https://github.com/kowainik/tomland/blob/main/_autodocs/errors-reference.md Integrates validation directly into the TOML codec definition. The `emailCodec` example shows how to use `Toml.validate` to enforce format constraints on text fields. ```haskell emailCodec :: Key -> TomlCodec Text emailCodec key = let validate email = if "@" `isInfixOf` email then Right email else Left "Invalid email format" in Toml.validate validate (Toml.text key) ``` -------------------------------- ### pretty Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Pretty-print TOML AST to text using default formatting options. ```APIDOC ## pretty ### Description Pretty-print TOML AST to text using default formatting options. ### Signature ```haskell pretty :: TOML -> Text ``` ### Parameters #### Path Parameters - **toml** (TOML) - Description: TOML AST to print #### Returns - **Text** - Description: Formatted TOML text ### Example ```haskell import qualified Toml import Data.Text.IO (putStr) main = do case Toml.parse tomlText of Right ast -> putStr $ Toml.pretty ast Left err -> print err ``` ``` -------------------------------- ### Basic Configuration Decoding Source: https://github.com/kowainik/tomland/blob/main/_autodocs/examples-and-patterns.md Demonstrates decoding a simple TOML string into a Haskell data structure using a custom codec. Ensure the ServerConfig data type and its codec are defined. ```haskell {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} import Data.Text (Text) import qualified Toml import GHC.Generics (Generic) data ServerConfig = ServerConfig { host :: String , port :: Int , enableSSL :: Bool , maxConnections :: Int } deriving (Show, Generic) configCodec :: Toml.TomlCodec ServerConfig configCodec = ServerConfig <*> Toml.string "host" .= host <*> Toml.int "port" .= port <*> Toml.bool "enableSSL" .= enableSSL <*> Toml.int "maxConnections" .= maxConnections main :: IO () main = do let toml = "host = \"localhost\"\nport = 8080\nenableSSL = false\nmaxConnections = 100" case Toml.decode configCodec toml of Left errs -> putStrLn $ "Decode error: " ++ show errs Right cfg -> print cfg ``` -------------------------------- ### prettyOptions Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Pretty-print TOML with custom formatting options. ```APIDOC ## prettyOptions ### Description Pretty-print TOML with custom formatting options. ### Signature ```haskell prettyOptions :: PrintOptions -> TOML -> Text ``` ### Parameters #### Path Parameters - **options** (PrintOptions) - Description: Formatting configuration - **toml** (TOML) - Description: TOML AST to print #### Returns - **Text** - Description: Formatted TOML text ``` -------------------------------- ### Using BiMaps Directly with match Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Demonstrates a common pattern for using BiMaps directly by employing the `match` combinator from `Toml.Codec.Combinator.Common`. ```haskell import Toml.Codec.Combinator.Common (match) customCodec :: Key -> TomlCodec CustomType customCodec = match _CustomType -- Where _CustomType is a TomlBiMap CustomType AnyValue ``` -------------------------------- ### Sum Type Decoding Source: https://github.com/kowainik/tomland/blob/main/_autodocs/examples-and-patterns.md Illustrates decoding TOML into Haskell sum types (also known as discriminated unions). This example decodes a 'Logger' type which can be either 'Console' or 'File', based on a 'type' field. ```haskell {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} import Data.Text (Text) import qualified Toml data LogLevel = Debug | Info | Warning | Error data Logger = Console { level :: LogLevel } | File { path :: String, level :: LogLevel } matchConsole :: Logger -> Maybe LogLevel matchConsole (Console l) = Just l matchConsole _ = Nothing matchFile :: Logger -> Maybe (String, LogLevel) matchFile (File p l) = Just (p, l) matchFile _ = Nothing logLevelCodec :: Toml.Key -> Toml.TomlCodec LogLevel logLevelCodec key = Toml.enumBounded key consoleCodec :: Toml.TomlCodec Logger consoleCodec = Toml.dimatch matchConsole Console (logLevelCodec "level") fileCodec :: Toml.TomlCodec Logger fileCodec = Toml.dimatch matchFile (\(p, l) -> File p l) ((\(p, l) -> (p, l)) <*> Toml.string "path" .= fst <*> logLevelCodec "level" .= snd ) loggerCodec :: Toml.TomlCodec Logger loggerCodec = consoleCodec <|> fileCodec main :: IO () main = do let toml1 = "type = \"Console\"\nlevel = \"Info\"" case Toml.decode loggerCodec toml1 of Left errs -> print errs Right logger -> print logger ``` -------------------------------- ### Composing TOML Codecs for Nested Structures Source: https://github.com/kowainik/tomland/blob/main/_autodocs/examples-and-patterns.md Demonstrates how to compose smaller codecs into a larger one to parse nested TOML structures. This pattern is effective for organizing complex configurations. ```haskell {-# LANGUAGE OverloadedStrings #} import qualified Toml import Data.Bifunctor (bimap) data Logger = Logger { level :: String } data Cache = Cache { ttl :: Int } data App = App { logger :: Logger , cache :: Cache , port :: Int } loggerCodec :: Toml.TomlCodec Logger loggerCodec = Logger <$> Toml.string "level" .= level cacheCodec :: Toml.TomlCodec Cache cacheCodec = Cache <$> Toml.int "ttl" .= ttl appCodec :: Toml.TomlCodec App appCodec = App <$> Toml.table loggerCodec "logger" .= logger <*> Toml.table cacheCodec "cache" .= cache <*> Toml.int "port" .= port main :: IO () main = do let toml = "port = 8080\n[logger]\nlevel = \"debug\"\n[cache]\nttl = 3600" case Toml.decode appCodec toml of Left errs -> print errs Right app -> print app ``` -------------------------------- ### Nested Type Codec Derivation Source: https://github.com/kowainik/tomland/blob/main/_autodocs/generic-codec.md Shows how to derive codecs for nested types like Address and Person. Basic types get primitive codecs, while aggregate types use Toml.table with Toml.genericCodec. The main codec is also derived generically. ```haskell #{-# LANGUAGE DeriveGeneric #-} import GHC.Generics (Generic) import Data.Text (Text) import qualified Toml -- Basic types get primitive codecs data Address = Address { street :: Text , city :: Text , country :: Text } deriving (Generic) instance Toml.HasCodec Address where -- Nested in parent as table hasCodec = Toml.table Toml.genericCodec -- Aggregate type data Person = Person { name :: Text , age :: Int , address :: Address } deriving (Generic) instance Toml.HasCodec Person where hasCodec = Toml.table Toml.genericCodec -- Use in main codec mainCodec :: Toml.TomlCodec Person mainCodec = Toml.genericCodec ``` -------------------------------- ### prettyKey Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Format a key as TOML dotted notation. ```APIDOC ## prettyKey ### Description Format a key as TOML dotted notation. ### Signature ```haskell prettyKey :: Key -> Text ``` ### Parameters #### Path Parameters - **key** (Key) - Description: The key to format #### Returns - **Text** - Description: The formatted key string ### Examples - `Key "port" → "port"` - `Key "server" <> Key "port" → "server.port"` ``` -------------------------------- ### Direct Parsing vs. Decoding Source: https://github.com/kowainik/tomland/blob/main/_autodocs/parser-reference.md Illustrates the recommended approach for handling TOML data. It contrasts the direct use of `Toml.parse` followed by `runTomlCodec` with the preferred method of using `Toml.decode` directly, which combines parsing and decoding. ```haskell -- DON'T do this: case Toml.parse tomlText of Left err -> ... Right ast -> runTomlCodec codec ast -- DO this instead: case Toml.decode codec tomlText of Left err -> ... Right value -> ... ``` -------------------------------- ### execTomlCodec Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-core.md Runs the write part of a codec to generate a TOML AST from a value. This is a low-level function. ```APIDOC ## execTomlCodec ### Description Runs the write part of a codec to generate a TOML AST from a value. This is a low-level function. ### Method N/A (Haskell function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | codec | `TomlCodec a` | — | Bidirectional codec for type `a` | | obj | `a` | — | Value to encode | ### Returns `TOML` - Generated TOML AST ``` -------------------------------- ### toListT Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Convert a PrefixTree to a list of key-value pairs. ```APIDOC ## toListT ### Description Convert the PrefixTree into a list of (Key, value) pairs. ### Signature ```haskell ttoListT :: PrefixTree a -> [(Key, a)] ``` ### Parameters #### Path Parameters - **tree** (PrefixTree a) - The PrefixTree to convert. #### Returns - **[(Key, a)]** - A list of key-value pairs. ``` -------------------------------- ### Default PrintOptions Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Provides the default configuration for pretty-printing TOML, including multi-line arrays and 2-space indentation without key sorting. ```haskell data PrintOptions = PrintOptions { printOptionsSorting :: !(Maybe (Key -> Key -> Ordering)), printOptionsIndent :: !Int, printOptionsArrayMode :: !Lines } defaultOptions :: PrintOptions ``` -------------------------------- ### defaultOptions Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Default printing options for pretty-printing TOML. ```APIDOC ## defaultOptions ### Description Default printing options: No sorting (preserve parse order), 2-space indentation, MultiLine arrays. ### Signature ```haskell defaultOptions :: PrintOptions ``` ### Returns - **PrintOptions** - Default printing configuration ``` -------------------------------- ### text Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for strict Data.Text.Text. It takes a TOML key name and returns a codec for Text. ```APIDOC ## text ### Description Codec for strict `Data.Text.Text`. ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (None) ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ``` -------------------------------- ### int Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for fixed-size signed integers. It takes a TOML key name and returns a codec for Haskell Int. ```APIDOC ## int ### Description Codec for fixed-size signed integers. ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (None) ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ``` -------------------------------- ### string Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for Haskell String (list of characters). It takes a TOML key name and returns a codec for String. ```APIDOC ## string ### Description Codec for Haskell `String` (list of characters). ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (None) ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ``` -------------------------------- ### Codec for Sum Types using Pattern Matching Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Creates a codec for sum types by defining how to match and build the different constructors. Uses the Alternative (<|>) operator to combine multiple matching rules. ```haskell data User = Guest Integer | Registered Text matchGuest :: User -> Maybe Integer matchGuest (Guest i) = Just i matchGuest _ = Nothing matchRegistered :: User -> Maybe Text matchRegistered (Registered t) = Just t matchRegistered _ = Nothing userCodec :: TomlCodec User userCodec = Toml.dimatch matchGuest Guest (Toml.integer "id") <|> Toml.dimatch matchRegistered Registered (Toml.text "name") ``` -------------------------------- ### Execute TOML Codec for Writing Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-core.md Runs the write part of a codec to generate a TOML AST from a value. This is a low-level function. ```haskell execTomlCodec :: TomlCodec a -> a -> TOML ``` -------------------------------- ### tShow Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Converts a value with a Show instance to Text. ```APIDOC ## `tShow` ```haskell tShow :: Show a => a -> Text ``` Convert value to Text using Show instance. ``` -------------------------------- ### KeyNotFound Constructor Source: https://github.com/kowainik/tomland/blob/main/_autodocs/errors-reference.md Indicates that a required key is missing from the TOML input. ```haskell KeyNotFound !Key ``` ```haskell -- TOML file is empty -- Codec expects: int "port" -- Error: KeyNotFound (Key "port") ``` -------------------------------- ### Codec for Types with Read and Show Instances Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Creates a TOML codec for any type that has instances of the Show and Read typeclasses. ```haskell read :: (Show a, Read a) => Key -> TomlCodec a ``` -------------------------------- ### Pretty Print TOML AST with Custom Options Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Pretty-prints a TOML AST to text using custom formatting options. Allows for fine-grained control over the output format. ```haskell prettyOptions :: PrintOptions -> TOML -> Text ``` -------------------------------- ### runTomlCodec Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-core.md Runs the read part of a codec against a TOML AST. This is a low-level function; normally, `decode` should be used instead. ```APIDOC ## runTomlCodec ### Description Runs the read part of a codec against a TOML AST. This is a low-level function; normally, `decode` should be used instead. ### Method N/A (Haskell function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | codec | `TomlCodec a` | — | Bidirectional codec for type `a` | | toml | `TOML` | — | Parsed TOML AST | ### Returns `Validation [TomlDecodeError] a` - Decoded value or errors ``` -------------------------------- ### Custom BiMap Constructors Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Provides constructors for creating custom TomlBiMap instances based on specific conversion functions or type classes. ```haskell _TextBy :: (a -> Text) -> (Text -> Either Text a) -> TomlBiMap a AnyValue _Read :: (Show a, Read a) => TomlBiMap a AnyValue _EnumBounded :: (Enum a, Bounded a, Show a) => TomlBiMap a AnyValue _Validate :: (a -> Either Text a) -> TomlBiMap a AnyValue -> TomlBiMap a AnyValue _Hardcoded :: a -> TomlBiMap a AnyValue ``` -------------------------------- ### Custom Type Serialization with Toml.textBy Source: https://github.com/kowainik/tomland/blob/main/_autodocs/examples-and-patterns.md Illustrates how to define custom codecs for types like `Email` by providing parsing and showing functions. This allows for specific validation and representation of custom types within TOML data. ```haskell {-# LANGUAGE OverloadedStrings #-} import Data.Text (Text, pack, unpack) import qualified Toml newtype Email = Email { unEmail :: Text } deriving (Show, Eq) parseEmail :: Text -> Either Text Email parseEmail t | "@" `elem` unpack t = Right (Email t) | otherwise = Left "Invalid email format" showEmail :: Email -> Text showEmail = unEmail emailCodec :: Toml.Key -> Toml.TomlCodec Email emailCodec = Toml.textBy showEmail parseEmail data User = User { email :: Email, verified :: Bool } deriving (Show) userCodec :: Toml.TomlCodec User userCodec = User <*> emailCodec "email" .= email <*> Toml.bool "verified" .= verified main :: IO () main = do let toml = "email = \"user@example.com\"\nverified = true" case Toml.decode userCodec toml of Left errs -> print errs Right user -> print user ``` -------------------------------- ### dimatch: Sum Type Codec with Pattern Matching Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Creates a codec for sum types using pattern matching for decoding and a constructor function for encoding. Use with `(<|>)` for trying multiple branches. ```haskell dimatch :: (a -> Maybe b) -> (b -> a) -> TomlCodec b -> TomlCodec a ``` ```haskell data User = Guest Integer | Registered Text Email matchGuest :: User -> Maybe Integer matchGuest (Guest i) = Just i matchGuest _ = Nothing matchRegistered :: User -> Maybe (Text, Email) matchRegistered (Registered name email) = Just (name, email) matchRegistered _ = Nothing guestCodec :: TomlCodec User guestCodec = Toml.dimatch matchGuest Guest (Toml.integer "id") registeredCodec :: TomlCodec User registeredCodec = Toml.dimatch matchRegistered (\(name, email) -> Registered name email) registeredPairCodec userCodec :: TomlCodec User userCodec = guestCodec <|> registeredCodec ``` -------------------------------- ### String Codec Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for Haskell String (list of characters). Takes a TOML key name and returns a String codec. ```Haskell string :: Key -> TomlCodec String ``` -------------------------------- ### List and Array Decoding Source: https://github.com/kowainik/tomland/blob/main/_autodocs/examples-and-patterns.md Demonstrates decoding TOML arrays of integers and arrays of tables into Haskell lists. The 'servers' field is a list of 'Server' records, and 'ports' is a list of integers. ```haskell {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} import Data.Text (Text) import qualified Toml import GHC.Generics (Generic) data Server = Server { sName :: String , sUrl :: String } deriving (Show, Generic) data Config = Config { servers :: [Server] , ports :: [Int] } deriving (Show, Generic) serverCodec :: Toml.TomlCodec Server serverCodec = Server <*> Toml.string "name" .= sName <*> Toml.string "url" .= sUrl configCodec :: Toml.TomlCodec Config configCodec = Config <*> Toml.list serverCodec "servers" .= servers <*> Toml.arrayOf Toml._Int "ports" .= ports main :: IO () main = do let toml = "ports = [8080, 8081, 8082]\n\n[[servers]]\nname = \"server1\"\nurl = \"http://srv1.com\"\n\n[[servers]]\nname = \"server2\"\nurl = \"http://srv2.com\"" case Toml.decode configCodec toml of Left errs -> print errs Right cfg -> print cfg ``` -------------------------------- ### Text BiMaps for TOML Conversion Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Offers pre-built 'TomlBiMap' instances for various text and byte string types, facilitating their conversion to and from 'AnyValue' in TOML. ```haskell _Text :: TomlBiMap Text AnyValue _String :: TomlBiMap String AnyValue _LText :: TomlBiMap LazyText AnyValue _ByteString :: TomlBiMap ByteString AnyValue _LByteString :: TomlBiMap LazyByteString AnyValue ``` -------------------------------- ### Machine-Size Unsigned Integer Codec Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for machine-size unsigned integers. Takes a TOML key name and returns a Word codec. ```Haskell word :: Key -> TomlCodec Word ``` -------------------------------- ### Time of Day Codec Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for time of day, formatted as '04:32:00'. Takes a TOML key and returns a TimeOfDay codec. ```Haskell timeOfDay :: Key -> TomlCodec TimeOfDay ``` -------------------------------- ### day Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for calendar date. It takes a TOML key name and returns a codec for Day. Format: 2020-05-16 ```APIDOC ## day ### Description Codec for calendar date. Format: `2020-05-16` ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (None) ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ``` -------------------------------- ### Codec for Set via Table Arrays Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Builds a codec for sets where each element is represented as a table within a TOML table array. Requires the element type to be orderable. ```haskell set :: (Ord a) => TomlCodec a -> Key -> TomlCodec (Set a) ``` -------------------------------- ### Key Pattern Matching Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Pattern for matching and constructing keys with a head piece and a tail key. ```APIDOC ## Key Pattern Matching ### `(:||)` Pattern #### Description Pattern for matching and constructing keys with a head piece and a tail key. #### Signature ```haskell pattern (:||) :: Piece -> Key -> Key ``` ``` -------------------------------- ### intMap Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for integer maps represented as arrays. Takes codecs for keys and values, and a TOML key. ```APIDOC ## intMap ### Description Codec for integer maps as arrays. ### Method N/A (Function Signature) ### Endpoint N/A (Function Signature) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### nonEmpty Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for non-empty array of tables. Ensures that the array of tables is not empty. ```APIDOC ## nonEmpty ### Description Codec for non-empty array of tables. ### Method N/A (Function Signature) ### Endpoint N/A (Function Signature) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### word Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for machine-size unsigned integers. It takes a TOML key name and returns a codec for Haskell Word. ```APIDOC ## word ### Description Codec for machine-size unsigned integers. ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (None) ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ``` -------------------------------- ### Run TOML Codec for Reading Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-core.md Executes the read part of a codec against a TOML AST. This is a low-level function; `decode` is typically used instead. ```haskell runTomlCodec :: TomlCodec a -> TOML -> Validation [TomlDecodeError] a ``` -------------------------------- ### Category Instance for BiMap Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md The Category instance for BiMap allows composition of bidirectional mappings using the (.) operator. ```APIDOC ## Category Instance ```haskell instance Category (BiMap e) where id = BiMap Right Right (.) = composition ``` Enables composition with `(.)` operator: ```haskell -- Compose bimaps let combined = mapB . mapA ``` ``` -------------------------------- ### iso Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Creates a BiMap from two pure functions, representing a total bidirectional isomorphism. ```APIDOC ## `iso` ```haskell iso :: (a -> b) -> (b -> a) -> BiMap e a b ``` Create a bidirectional isomorphism from two pure functions. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | f | `a -> b` | — | Forward conversion | | g | `b -> a` | — | Backward conversion | | Returns | `BiMap e a b` | — | Bidirectional mapping | ``` -------------------------------- ### list Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for array of tables (table array in TOML). It takes a codec for each table item and a TOML table array name, returning a codec for a list of items. ```APIDOC ## list ### Description Codec for array of tables (table array in TOML). ### Method N/A (Function Signature) ### Endpoint N/A (Function Signature) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```haskell data User = User { name :: Text, age :: Int } userCodec :: TomlCodec User userCodec = User <*> Toml.text "name" .= name <*> Toml.int "age" .= age -- In parent: Toml.list userCodec "user" .= users ``` ### Response #### Success Response (200) N/A #### Response Example ```toml [[user]] name = "Alice" age = 30 [[user]] name = "Bob" age = 25 ``` ``` -------------------------------- ### Exception Handling with catch Source: https://github.com/kowainik/tomland/blob/main/_autodocs/errors-reference.md Handles potential `LoadTomlException` errors during file loading using `catch`. This pattern is useful for isolating error handling logic for specific exceptions. ```haskell import Control.Exception (catch, SomeException) import qualified Toml main :: IO () main = do config <- Toml.decodeFile configCodec "config.toml" `catch` \(Toml.LoadTomlException path msg) -> do putStrLn $ "Failed to load " ++ path putStrLn $ Text.unpack msg exitFailure ``` -------------------------------- ### ParseError Constructor Source: https://github.com/kowainik/tomland/blob/main/_autodocs/errors-reference.md Thrown when the TOML text syntax is invalid and cannot be parsed. ```haskell ParseError !TomlParseError ``` ```toml # Missing closing bracket port = [8080 # Error: ParseError (TomlParseError "expected ']' at line 1") ``` -------------------------------- ### lazyByteString Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for lazy Data.ByteString.Lazy.ByteString. It takes a TOML key name and returns a codec for LazyByteString. ```APIDOC ## lazyByteString ### Description Codec for lazy `Data.ByteString.Lazy.ByteString`. ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (None) ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ``` -------------------------------- ### word8 Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for 8-bit unsigned integers. It takes a TOML key name and returns a codec for Haskell Word8. ```APIDOC ## word8 ### Description Codec for 8-bit unsigned integers. ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (None) ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ``` -------------------------------- ### Standalone Generic Instance Derivation Source: https://github.com/kowainik/tomland/blob/main/_autodocs/generic-codec.md This is the recommended method for deriving generic instances. It involves defining a standalone `HasCodec` and `HasItemCodec` instance that uses `Toml.genericCodec`. ```haskell # LANGUAGE DeriveGeneric data Config = Config { ... } deriving (Generic) instance Toml.HasCodec Config where hasCodec = Toml.table Toml.genericCodec instance Toml.HasItemCodec Config where hasItemCodec = Right Toml.genericCodec ``` -------------------------------- ### Local Time Codec Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for local time without timezone, formatted as '2020-05-16T04:32:00'. Takes a TOML key and returns a LocalTime codec. ```Haskell localTime :: Key -> TomlCodec LocalTime ``` -------------------------------- ### Time BiMaps Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Pre-built TomlBiMap instances for various time-related types like ZonedTime, LocalTime, Day, and TimeOfDay, mapping them to AnyValue. ```APIDOC ## Time BiMaps ```haskell _ZonedTime :: TomlBiMap ZonedTime AnyValue _LocalTime :: TomlBiMap LocalTime AnyValue _Day :: TomlBiMap Day AnyValue _TimeOfDay :: TomlBiMap TimeOfDay AnyValue ``` ``` -------------------------------- ### dimatch Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Provides a codec for sum types using pattern matching and constructor building. It takes a pattern matcher and a constructor function. ```APIDOC ## dimatch ### Description Codec for sum types using pattern matching and constructor building. ### Method `dimatch` ### Signature ```haskell dimatch :: (a -> Maybe b) -> (b -> a) -> TomlCodec b -> TomlCodec a ``` ### Parameters #### Function Parameters - **match** (`a -> Maybe b`) - Pattern matcher. - **build** (`b -> a`) - Constructor. - **codec** (`TomlCodec b`) - Inner codec. ### Returns - `TomlCodec a` - Sum type codec. ### Example ```haskell data User = Guest Integer | Registered Text Email matchGuest :: User -> Maybe Integer matchGuest (Guest i) = Just i matchGuest _ = Nothing matchRegistered :: User -> Maybe (Text, Email) matchRegistered (Registered name email) = Just (name, email) matchRegistered _ = Nothing guestCodec :: TomlCodec User guestCodec = Toml.dimatch matchGuest Guest (Toml.integer "id") registeredCodec :: TomlCodec User registeredCodec = Toml.dimatch matchRegistered (\(name, email) -> Registered name email) registeredPairCodec userCodec :: TomlCodec User userCodec = guestCodec <|> registeredCodec ``` ``` -------------------------------- ### natural Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for natural numbers (non-negative integers). It takes a TOML key name and returns a codec for Haskell Natural. ```APIDOC ## natural ### Description Codec for natural numbers (non-negative integers). ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (None) ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ``` -------------------------------- ### lazyText Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for lazy Data.Text.Lazy.Text. It takes a TOML key name and returns a codec for LazyText. ```APIDOC ## lazyText ### Description Codec for lazy `Data.Text.Lazy.Text`. ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (None) ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ``` -------------------------------- ### Define a User TomlCodec in Haskell Source: https://github.com/kowainik/tomland/blob/main/_autodocs/api-overview.md Defines a bidirectional codec for a User type, mapping TOML keys 'name' and 'age' to Haskell fields userName and userAge. Requires importing Toml and using combinators like Toml.text and Toml.int. ```haskell userCodec :: TomlCodec User userCodec = User <$> Toml.text "name" .= userName <*> Toml.int "age" .= userAge ``` -------------------------------- ### Primitive BiMaps Source: https://github.com/kowainik/tomland/blob/main/_autodocs/bimap-and-di.md Pre-built TomlBiMap instances for common primitive types like Bool, Integer, Float, etc., mapping them to AnyValue. ```APIDOC ## Primitive BiMaps ```haskell _Bool :: TomlBiMap Bool AnyValue _Integer :: TomlBiMap Integer AnyValue _Int :: TomlBiMap Int AnyValue _Natural :: TomlBiMap Natural AnyValue _Word :: TomlBiMap Word AnyValue _Word8 :: TomlBiMap Word8 AnyValue _Double :: TomlBiMap Double AnyValue _Float :: TomlBiMap Float AnyValue ``` ``` -------------------------------- ### Integer Codec Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for arbitrary-precision integers. Takes a TOML key name and returns an Integer codec. ```Haskell integer :: Key -> TomlCodec Integer ``` -------------------------------- ### differenceWithT Source: https://github.com/kowainik/tomland/blob/main/_autodocs/type-module-reference.md Compute the difference between two PrefixTrees using a merge function. ```APIDOC ## differenceWithT ### Description Computes the difference between two PrefixTrees. For keys present in both trees, a merge function is used to determine the resulting value. ### Signature ```haskell differenceWithT :: (a -> b -> Maybe a) -> PrefixTree a -> PrefixTree b -> PrefixTree a ``` ### Parameters #### Path Parameters - **mergeFn** ((a -> b -> Maybe a)) - A function that takes values from the first and second tree and returns `Just` the new value or `Nothing` to remove the key. - **tree1** (PrefixTree a) - The first PrefixTree. - **tree2** (PrefixTree b) - The second PrefixTree. #### Returns - **PrefixTree a** - A new PrefixTree representing the difference. ``` -------------------------------- ### bool Source: https://github.com/kowainik/tomland/blob/main/_autodocs/codec-combinators.md Codec for TOML boolean values. It takes a TOML key name and returns a codec for Haskell Bool. ```APIDOC ## bool ### Description Codec for TOML boolean values. ### Method (Not applicable, this is a Haskell function signature) ### Endpoint (Not applicable, this is a Haskell function signature) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example ```haskell Toml.bool "enabled" .= isEnabled ``` ### Response #### Success Response (200) (Not applicable, this is a Haskell function signature) #### Response Example (None) ```