{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE QuantifiedConstraints #-} {-# LANGUAGE ImpredicativeTypes #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE AllowAmbiguousTypes #-} module Conftrack.Source (ConfigSource(..), SomeSource(..)) where import Conftrack.Value (Key, Value(..), ConfigError(..)) import Control.Monad.State (StateT (..)) import Data.Text (Text) -- | An abstraction over "config sources". This might mean file formats, -- environment variables, or any other kind of format that can be seen as a -- key-value store. class ConfigSource s where -- | Some sources require state, e.g. to keep track of which values were -- already read. type SourceState s -- | read a single value from the source. fetchValue :: Key -> s -> StateT (SourceState s) IO (Either ConfigError (Value, Text)) -- | given @s@, determine if any keys are "left over" and were not used. -- This is used to produce warnings for unknown configuration options; -- since not all sources can support this, this function's return type -- includes @Maybe@ and sources are free to return @Nothing@ if they -- cannot determine if any unknown keys are present. leftovers :: s -> StateT (SourceState s) IO (Maybe [Key]) -- | An opaque type for any kind of config sources. Values of this type can be -- acquired from they @Conftrack.Source.*@ modules, or by implementing the -- 'ConfigSource' type class. data SomeSource = forall source. ConfigSource source => SomeSource (source, SourceState source)