brandonchinn178 / toml-reader

Haskell library for parsing v1.0 TOML files
https://hackage.haskell.org/package/toml-reader
BSD 3-Clause "New" or "Revised" License
13 stars 6 forks source link

Make it easy to get unused fields #12

Open brandonchinn178 opened 1 year ago

brandonchinn178 commented 1 year ago

Make it easy to get the fields in a Table that aren't used. Something like

decodeFoo :: Text -> IO Foo
decodeFoo doc =
  case decodeWith (withUnusedFields tomlDecoder) doc of
    Left e -> error $ show e
    Right (a, []) -> pure a
    Right (_, kvs) -> error $ "Found unknown keys: " ++ show (Map.keys kvs)

data Bar = Bar { a :: Bool, b :: Bool, extra :: Map Text Int }
instance DecodeTOML Bar where
  tomlDecoder = do
    (bar, unused) <- withUnusedFields $ Bar <$> getField "a" <*> getField "b" <*> pure Map.empty
    -- https://github.com/brandonchinn178/toml-reader/issues/11
    extra <- toDecoder $ mapM (runDecoder tomlDecoder) unused
    pure bar{extra = extra}

withUnusedFields :: Decoder a -> Decoder (a, Map Text Value)

One possible implementation:

  1. Make Decoder a return DecodeM (a, [Text]), storing the keys in the table that have been used
  2. Make Applicative/Monad instance combine the [Text] (like WriterT)
  3. Change getFieldsOptWith to add the path being queried to the list (just the first key)

Possibly have withUnusedFields return any DecodeTOML instance?