{-# LANGUAGE CPP #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Data.Ini.Config.Bidir
(
Ini,
ini,
getIniValue,
iniValueL,
getRawIni,
parseIni,
serializeIni,
updateIni,
setIniUpdatePolicy,
UpdatePolicy (..),
UpdateCommentPolicy (..),
defaultUpdatePolicy,
IniSpec,
SectionSpec,
section,
allOptional,
FieldDescription,
(.=),
(.=?),
field,
flag,
comment,
placeholderValue,
optional,
FieldValue (..),
text,
string,
number,
bool,
readable,
listWithSeparator,
pairWithSeparator,
(&),
Lens,
)
where
import Control.Monad.Trans.State.Strict (State, modify, runState)
import qualified Control.Monad.Trans.State.Strict as State
import qualified Data.Foldable as F
#if __GLASGOW_HASKELL__ >= 710
import Data.Function ((&))
#endif
import Data.Ini.Config.Raw
import Data.Monoid ((<>))
import Data.Sequence (Seq, ViewL (..), ViewR (..), (<|))
import qualified Data.Sequence as Seq
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Traversable as F
import Data.Typeable (Proxy (..), Typeable, typeRep)
import GHC.Exts (IsList (..))
import Text.Read (readMaybe)
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
newtype I a = I {forall a. I a -> a
fromI :: a}
instance Functor I where fmap :: forall a b. (a -> b) -> I a -> I b
fmap a -> b
f (I a
x) = forall a. a -> I a
I (a -> b
f a
x)
set :: Lens s t a b -> b -> s -> t
set :: forall s t a b. Lens s t a b -> b -> s -> t
set Lens s t a b
lns b
x s
a = forall a. I a -> a
fromI (Lens s t a b
lns (forall a b. a -> b -> a
const (forall a. a -> I a
I b
x)) s
a)
newtype C a b = C {forall a b. C a b -> a
fromC :: a}
instance Functor (C a) where fmap :: forall a b. (a -> b) -> C a a -> C a b
fmap a -> b
_ (C a
x) = forall a b. a -> C a b
C a
x
get :: Lens s t a b -> s -> a
get :: forall s t a b. Lens s t a b -> s -> a
get Lens s t a b
lns s
a = forall a b. C a b -> a
fromC (Lens s t a b
lns forall a b. a -> C a b
C s
a)
lkp :: NormalizedText -> Seq (NormalizedText, a) -> Maybe a
lkp :: forall a. NormalizedText -> Seq (NormalizedText, a) -> Maybe a
lkp NormalizedText
t = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
F.find (\(NormalizedText
t', a
_) -> NormalizedText
t' forall a. Eq a => a -> a -> Bool
== NormalizedText
t)
rmv :: NormalizedText -> Seq (Field s) -> Seq (Field s)
rmv :: forall s. NormalizedText -> Seq (Field s) -> Seq (Field s)
rmv NormalizedText
n = forall a. (a -> Bool) -> Seq a -> Seq a
Seq.filter (\Field s
f -> forall s. Field s -> NormalizedText
fieldName Field s
f forall a. Eq a => a -> a -> Bool
/= NormalizedText
n)
#if __GLASGOW_HASKELL__ < 710
(&) :: a -> (a -> b) -> b
a & f = f a
infixl 1 &
#endif
data Ini s = Ini
{ forall s. Ini s -> Spec s
iniSpec :: Spec s,
forall s. Ini s -> s
iniCurr :: s,
forall s. Ini s -> s
iniDef :: s,
forall s. Ini s -> Maybe RawIni
iniLast :: Maybe RawIni,
forall s. Ini s -> UpdatePolicy
iniPol :: UpdatePolicy
}
ini :: s -> IniSpec s () -> Ini s
ini :: forall s. s -> IniSpec s () -> Ini s
ini s
def (IniSpec BidirM (Section s) ()
spec) =
Ini
{ iniSpec :: Spec s
iniSpec = forall s a. BidirM s a -> Seq s
runBidirM BidirM (Section s) ()
spec,
iniCurr :: s
iniCurr = s
def,
iniDef :: s
iniDef = s
def,
iniLast :: Maybe RawIni
iniLast = forall a. Maybe a
Nothing,
iniPol :: UpdatePolicy
iniPol = UpdatePolicy
defaultUpdatePolicy
}
getIniValue :: Ini s -> s
getIniValue :: forall s. Ini s -> s
getIniValue = forall s. Ini s -> s
iniCurr
mkLens :: (a -> b) -> (b -> a -> a) -> Lens a a b b
mkLens :: forall a b. (a -> b) -> (b -> a -> a) -> Lens a a b b
mkLens a -> b
get' b -> a -> a
set' b -> f b
f a
a = (b -> a -> a
`set'` a
a) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` b -> f b
f (a -> b
get' a
a)
iniValueL :: Lens (Ini s) (Ini s) s s
iniValueL :: forall s. Lens (Ini s) (Ini s) s s
iniValueL = forall a b. (a -> b) -> (b -> a -> a) -> Lens a a b b
mkLens forall s. Ini s -> s
iniCurr (\s
i Ini s
v -> Ini s
v {iniCurr :: s
iniCurr = s
i})
serializeIni :: Ini s -> Text
serializeIni :: forall s. Ini s -> Text
serializeIni = RawIni -> Text
printRawIni forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s. Ini s -> RawIni
getRawIni
getRawIni :: Ini s -> RawIni
getRawIni :: forall s. Ini s -> RawIni
getRawIni Ini {iniLast :: forall s. Ini s -> Maybe RawIni
iniLast = Just RawIni
raw} = RawIni
raw
getRawIni
Ini
{ iniCurr :: forall s. Ini s -> s
iniCurr = s
s,
iniSpec :: forall s. Ini s -> Spec s
iniSpec = Spec s
spec
} =
forall s. s -> Spec s -> RawIni
emitIniFile s
s Spec s
spec
parseIni :: Text -> Ini s -> Either String (Ini s)
parseIni :: forall s. Text -> Ini s -> Either String (Ini s)
parseIni
Text
t
i :: Ini s
i@Ini
{ iniSpec :: forall s. Ini s -> Spec s
iniSpec = Spec s
spec,
iniCurr :: forall s. Ini s -> s
iniCurr = s
def
} = do
RawIni Seq (NormalizedText, IniSection)
raw <- Text -> Either String RawIni
parseRawIni Text
t
s
s <- forall s.
s
-> ViewL (Section s)
-> Seq (NormalizedText, IniSection)
-> Either String s
parseSections s
def (forall a. Seq a -> ViewL a
Seq.viewl Spec s
spec) Seq (NormalizedText, IniSection)
raw
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
Ini s
i
{ iniCurr :: s
iniCurr = s
s,
iniLast :: Maybe RawIni
iniLast = forall a. a -> Maybe a
Just (Seq (NormalizedText, IniSection) -> RawIni
RawIni Seq (NormalizedText, IniSection)
raw)
}
updateIni :: s -> Ini s -> Ini s
updateIni :: forall s. s -> Ini s -> Ini s
updateIni s
new Ini s
i =
case forall s. s -> Ini s -> Either String (Ini s)
doUpdateIni s
new Ini s
i of
Left String
err -> forall a. HasCallStack => String -> a
error String
err
Right Ini s
i' -> Ini s
i'
setIniUpdatePolicy :: UpdatePolicy -> Ini s -> Ini s
setIniUpdatePolicy :: forall s. UpdatePolicy -> Ini s -> Ini s
setIniUpdatePolicy UpdatePolicy
pol Ini s
i = Ini s
i {iniPol :: UpdatePolicy
iniPol = UpdatePolicy
pol}
data FieldValue a = FieldValue
{
forall a. FieldValue a -> Text -> Either String a
fvParse :: Text -> Either String a,
forall a. FieldValue a -> a -> Text
fvEmit :: a -> Text
}
type BidirM s a = State (Seq s) a
runBidirM :: BidirM s a -> Seq s
runBidirM :: forall s a. BidirM s a -> Seq s
runBidirM = forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall s a. State s a -> s -> (a, s)
runState forall a. Seq a
Seq.empty
type Spec s = Seq (Section s)
newtype IniSpec s a = IniSpec (BidirM (Section s) a)
deriving (forall a b. a -> IniSpec s b -> IniSpec s a
forall a b. (a -> b) -> IniSpec s a -> IniSpec s b
forall s a b. a -> IniSpec s b -> IniSpec s a
forall s a b. (a -> b) -> IniSpec s a -> IniSpec s b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> IniSpec s b -> IniSpec s a
$c<$ :: forall s a b. a -> IniSpec s b -> IniSpec s a
fmap :: forall a b. (a -> b) -> IniSpec s a -> IniSpec s b
$cfmap :: forall s a b. (a -> b) -> IniSpec s a -> IniSpec s b
Functor, forall s. Functor (IniSpec s)
forall a. a -> IniSpec s a
forall s a. a -> IniSpec s a
forall a b. IniSpec s a -> IniSpec s b -> IniSpec s a
forall a b. IniSpec s a -> IniSpec s b -> IniSpec s b
forall a b. IniSpec s (a -> b) -> IniSpec s a -> IniSpec s b
forall s a b. IniSpec s a -> IniSpec s b -> IniSpec s a
forall s a b. IniSpec s a -> IniSpec s b -> IniSpec s b
forall s a b. IniSpec s (a -> b) -> IniSpec s a -> IniSpec s b
forall a b c.
(a -> b -> c) -> IniSpec s a -> IniSpec s b -> IniSpec s c
forall s a b c.
(a -> b -> c) -> IniSpec s a -> IniSpec s b -> IniSpec s c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. IniSpec s a -> IniSpec s b -> IniSpec s a
$c<* :: forall s a b. IniSpec s a -> IniSpec s b -> IniSpec s a
*> :: forall a b. IniSpec s a -> IniSpec s b -> IniSpec s b
$c*> :: forall s a b. IniSpec s a -> IniSpec s b -> IniSpec s b
liftA2 :: forall a b c.
(a -> b -> c) -> IniSpec s a -> IniSpec s b -> IniSpec s c
$cliftA2 :: forall s a b c.
(a -> b -> c) -> IniSpec s a -> IniSpec s b -> IniSpec s c
<*> :: forall a b. IniSpec s (a -> b) -> IniSpec s a -> IniSpec s b
$c<*> :: forall s a b. IniSpec s (a -> b) -> IniSpec s a -> IniSpec s b
pure :: forall a. a -> IniSpec s a
$cpure :: forall s a. a -> IniSpec s a
Applicative, forall s. Applicative (IniSpec s)
forall a. a -> IniSpec s a
forall s a. a -> IniSpec s a
forall a b. IniSpec s a -> IniSpec s b -> IniSpec s b
forall a b. IniSpec s a -> (a -> IniSpec s b) -> IniSpec s b
forall s a b. IniSpec s a -> IniSpec s b -> IniSpec s b
forall s a b. IniSpec s a -> (a -> IniSpec s b) -> IniSpec s b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> IniSpec s a
$creturn :: forall s a. a -> IniSpec s a
>> :: forall a b. IniSpec s a -> IniSpec s b -> IniSpec s b
$c>> :: forall s a b. IniSpec s a -> IniSpec s b -> IniSpec s b
>>= :: forall a b. IniSpec s a -> (a -> IniSpec s b) -> IniSpec s b
$c>>= :: forall s a b. IniSpec s a -> (a -> IniSpec s b) -> IniSpec s b
Monad)
newtype SectionSpec s a = SectionSpec (BidirM (Field s) a)
deriving (forall a b. a -> SectionSpec s b -> SectionSpec s a
forall a b. (a -> b) -> SectionSpec s a -> SectionSpec s b
forall s a b. a -> SectionSpec s b -> SectionSpec s a
forall s a b. (a -> b) -> SectionSpec s a -> SectionSpec s b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> SectionSpec s b -> SectionSpec s a
$c<$ :: forall s a b. a -> SectionSpec s b -> SectionSpec s a
fmap :: forall a b. (a -> b) -> SectionSpec s a -> SectionSpec s b
$cfmap :: forall s a b. (a -> b) -> SectionSpec s a -> SectionSpec s b
Functor, forall s. Functor (SectionSpec s)
forall a. a -> SectionSpec s a
forall s a. a -> SectionSpec s a
forall a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s a
forall a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s b
forall a b.
SectionSpec s (a -> b) -> SectionSpec s a -> SectionSpec s b
forall s a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s a
forall s a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s b
forall s a b.
SectionSpec s (a -> b) -> SectionSpec s a -> SectionSpec s b
forall a b c.
(a -> b -> c)
-> SectionSpec s a -> SectionSpec s b -> SectionSpec s c
forall s a b c.
(a -> b -> c)
-> SectionSpec s a -> SectionSpec s b -> SectionSpec s c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s a
$c<* :: forall s a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s a
*> :: forall a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s b
$c*> :: forall s a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s b
liftA2 :: forall a b c.
(a -> b -> c)
-> SectionSpec s a -> SectionSpec s b -> SectionSpec s c
$cliftA2 :: forall s a b c.
(a -> b -> c)
-> SectionSpec s a -> SectionSpec s b -> SectionSpec s c
<*> :: forall a b.
SectionSpec s (a -> b) -> SectionSpec s a -> SectionSpec s b
$c<*> :: forall s a b.
SectionSpec s (a -> b) -> SectionSpec s a -> SectionSpec s b
pure :: forall a. a -> SectionSpec s a
$cpure :: forall s a. a -> SectionSpec s a
Applicative, forall s. Applicative (SectionSpec s)
forall a. a -> SectionSpec s a
forall s a. a -> SectionSpec s a
forall a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s b
forall a b.
SectionSpec s a -> (a -> SectionSpec s b) -> SectionSpec s b
forall s a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s b
forall s a b.
SectionSpec s a -> (a -> SectionSpec s b) -> SectionSpec s b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> SectionSpec s a
$creturn :: forall s a. a -> SectionSpec s a
>> :: forall a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s b
$c>> :: forall s a b. SectionSpec s a -> SectionSpec s b -> SectionSpec s b
>>= :: forall a b.
SectionSpec s a -> (a -> SectionSpec s b) -> SectionSpec s b
$c>>= :: forall s a b.
SectionSpec s a -> (a -> SectionSpec s b) -> SectionSpec s b
Monad)
section :: Text -> SectionSpec s () -> IniSpec s ()
section :: forall s. Text -> SectionSpec s () -> IniSpec s ()
section Text
name (SectionSpec BidirM (Field s) ()
mote) = forall s a. BidirM (Section s) a -> IniSpec s a
IniSpec forall a b. (a -> b) -> a -> b
$ do
let fields :: Seq (Field s)
fields = forall s a. BidirM s a -> Seq s
runBidirM BidirM (Field s) ()
mote
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify (forall a. Seq a -> a -> Seq a
Seq.|> forall s. NormalizedText -> Seq (Field s) -> Bool -> Section s
Section (Text -> NormalizedText
normalize Text
name) Seq (Field s)
fields (forall s. Seq (Field s) -> Bool
allFieldsOptional Seq (Field s)
fields))
allFieldsOptional :: Seq (Field s) -> Bool
allFieldsOptional :: forall s. Seq (Field s) -> Bool
allFieldsOptional = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall {s}. Field s -> Bool
isOptional
where
isOptional :: Field s -> Bool
isOptional (Field Lens s s a a
_ FieldDescription a
fd) = forall t. FieldDescription t -> Bool
fdSkipIfMissing FieldDescription a
fd
isOptional (FieldMb Lens s s (Maybe a) (Maybe a)
_ FieldDescription a
_) = Bool
True
allOptional ::
(SectionSpec s () -> IniSpec s ()) ->
(SectionSpec s () -> IniSpec s ())
allOptional :: forall s.
(SectionSpec s () -> IniSpec s ())
-> SectionSpec s () -> IniSpec s ()
allOptional SectionSpec s () -> IniSpec s ()
k SectionSpec s ()
spec = forall s a. BidirM (Section s) a -> IniSpec s a
IniSpec forall a b. (a -> b) -> a -> b
$ do
let IniSpec BidirM (Section s) ()
comp = SectionSpec s () -> IniSpec s ()
k SectionSpec s ()
spec
BidirM (Section s) ()
comp
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify
( \Seq (Section s)
s -> case forall a. Seq a -> ViewR a
Seq.viewr Seq (Section s)
s of
ViewR (Section s)
EmptyR -> Seq (Section s)
s
Seq (Section s)
rs :> Section NormalizedText
name Seq (Field s)
fields Bool
_ ->
Seq (Section s)
rs forall a. Seq a -> a -> Seq a
Seq.|> forall s. NormalizedText -> Seq (Field s) -> Bool -> Section s
Section NormalizedText
name (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall s. Field s -> Field s
makeOptional Seq (Field s)
fields) Bool
True
)
makeOptional :: Field s -> Field s
makeOptional :: forall s. Field s -> Field s
makeOptional (Field Lens s s a a
l FieldDescription a
d) = forall s a. Eq a => Lens s s a a -> FieldDescription a -> Field s
Field Lens s s a a
l FieldDescription a
d {fdSkipIfMissing :: Bool
fdSkipIfMissing = Bool
True}
makeOptional (FieldMb Lens s s (Maybe a) (Maybe a)
l FieldDescription a
d) = forall s a.
Eq a =>
Lens s s (Maybe a) (Maybe a) -> FieldDescription a -> Field s
FieldMb Lens s s (Maybe a) (Maybe a)
l FieldDescription a
d {fdSkipIfMissing :: Bool
fdSkipIfMissing = Bool
True}
data Section s = Section NormalizedText (Seq (Field s)) Bool
data Field s
= forall a. Eq a => Field (Lens s s a a) (FieldDescription a)
| forall a. Eq a => FieldMb (Lens s s (Maybe a) (Maybe a)) (FieldDescription a)
fieldName :: Field s -> NormalizedText
fieldName :: forall s. Field s -> NormalizedText
fieldName (Field Lens s s a a
_ FieldDescription {fdName :: forall t. FieldDescription t -> NormalizedText
fdName = NormalizedText
n}) = NormalizedText
n
fieldName (FieldMb Lens s s (Maybe a) (Maybe a)
_ FieldDescription {fdName :: forall t. FieldDescription t -> NormalizedText
fdName = NormalizedText
n}) = NormalizedText
n
fieldComment :: Field s -> Seq Text
(Field Lens s s a a
_ FieldDescription {fdComment :: forall t. FieldDescription t -> Seq Text
fdComment = Seq Text
n}) = Seq Text
n
fieldComment (FieldMb Lens s s (Maybe a) (Maybe a)
_ FieldDescription {fdComment :: forall t. FieldDescription t -> Seq Text
fdComment = Seq Text
n}) = Seq Text
n
data FieldDescription t = FieldDescription
{ forall t. FieldDescription t -> NormalizedText
fdName :: NormalizedText,
forall t. FieldDescription t -> FieldValue t
fdValue :: FieldValue t,
:: Seq Text,
forall t. FieldDescription t -> Maybe Text
fdDummy :: Maybe Text,
forall t. FieldDescription t -> Bool
fdSkipIfMissing :: Bool
}
(.=) :: Eq t => Lens s s t t -> FieldDescription t -> SectionSpec s ()
Lens s s t t
l .= :: forall t s.
Eq t =>
Lens s s t t -> FieldDescription t -> SectionSpec s ()
.= FieldDescription t
f = forall s a. BidirM (Field s) a -> SectionSpec s a
SectionSpec forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify (forall a. Seq a -> a -> Seq a
Seq.|> Field s
fd)
where
fd :: Field s
fd = forall s a. Eq a => Lens s s a a -> FieldDescription a -> Field s
Field Lens s s t t
l FieldDescription t
f
(.=?) :: Eq t => Lens s s (Maybe t) (Maybe t) -> FieldDescription t -> SectionSpec s ()
Lens s s (Maybe t) (Maybe t)
l .=? :: forall t s.
Eq t =>
Lens s s (Maybe t) (Maybe t)
-> FieldDescription t -> SectionSpec s ()
.=? FieldDescription t
f = forall s a. BidirM (Field s) a -> SectionSpec s a
SectionSpec forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify (forall a. Seq a -> a -> Seq a
Seq.|> Field s
fd)
where
fd :: Field s
fd = forall s a.
Eq a =>
Lens s s (Maybe a) (Maybe a) -> FieldDescription a -> Field s
FieldMb Lens s s (Maybe t) (Maybe t)
l FieldDescription t
f
comment :: [Text] -> FieldDescription t -> FieldDescription t
[Text]
cmt FieldDescription t
fd = FieldDescription t
fd {fdComment :: Seq Text
fdComment = forall a. [a] -> Seq a
Seq.fromList [Text]
cmt}
placeholderValue :: Text -> FieldDescription t -> FieldDescription t
placeholderValue :: forall t. Text -> FieldDescription t -> FieldDescription t
placeholderValue Text
t FieldDescription t
fd = FieldDescription t
fd {fdDummy :: Maybe Text
fdDummy = forall a. a -> Maybe a
Just Text
t}
optional :: FieldDescription t -> FieldDescription t
optional :: forall t. FieldDescription t -> FieldDescription t
optional FieldDescription t
fd = FieldDescription t
fd {fdSkipIfMissing :: Bool
fdSkipIfMissing = Bool
True}
infixr 0 .=
infixr 0 .=?
field :: Text -> FieldValue a -> FieldDescription a
field :: forall a. Text -> FieldValue a -> FieldDescription a
field Text
name FieldValue a
value =
FieldDescription
{ fdName :: NormalizedText
fdName = Text -> NormalizedText
normalize (Text
name forall a. Semigroup a => a -> a -> a
<> Text
" "),
fdValue :: FieldValue a
fdValue = FieldValue a
value,
fdComment :: Seq Text
fdComment = forall a. Seq a
Seq.empty,
fdDummy :: Maybe Text
fdDummy = forall a. Maybe a
Nothing,
fdSkipIfMissing :: Bool
fdSkipIfMissing = Bool
False
}
flag :: Text -> FieldDescription Bool
flag :: Text -> FieldDescription Bool
flag Text
name = forall a. Text -> FieldValue a -> FieldDescription a
field Text
name FieldValue Bool
bool
readable :: forall a. (Show a, Read a, Typeable a) => FieldValue a
readable :: forall a. (Show a, Read a, Typeable a) => FieldValue a
readable = FieldValue {fvParse :: Text -> Either String a
fvParse = forall {b}. Read b => Text -> Either String b
parse, fvEmit :: a -> Text
fvEmit = a -> Text
emit}
where
emit :: a -> Text
emit = String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
parse :: Text -> Either String b
parse Text
t = case forall a. Read a => String -> Maybe a
readMaybe (Text -> String
T.unpack Text
t) of
Just b
v -> forall a b. b -> Either a b
Right b
v
Maybe b
Nothing ->
forall a b. a -> Either a b
Left
( String
"Unable to parse " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
t
forall a. [a] -> [a] -> [a]
++ String
" as a value of type "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show TypeRep
typ
)
typ :: TypeRep
typ = forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep Proxy a
prx
prx :: Proxy a
prx :: Proxy a
prx = forall {k} (t :: k). Proxy t
Proxy
number :: (Show a, Read a, Num a, Typeable a) => FieldValue a
number :: forall a. (Show a, Read a, Num a, Typeable a) => FieldValue a
number = forall a. (Show a, Read a, Typeable a) => FieldValue a
readable
text :: FieldValue Text
text :: FieldValue Text
text = FieldValue {fvParse :: Text -> Either String Text
fvParse = forall a b. b -> Either a b
Right, fvEmit :: Text -> Text
fvEmit = forall a. a -> a
id}
string :: FieldValue String
string :: FieldValue String
string = FieldValue {fvParse :: Text -> Either String String
fvParse = forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack, fvEmit :: String -> Text
fvEmit = String -> Text
T.pack}
bool :: FieldValue Bool
bool :: FieldValue Bool
bool = FieldValue {fvParse :: Text -> Either String Bool
fvParse = Text -> Either String Bool
parse, fvEmit :: Bool -> Text
fvEmit = forall {a}. IsString a => Bool -> a
emit}
where
parse :: Text -> Either String Bool
parse Text
s = case Text -> Text
T.toLower Text
s of
Text
"true" -> forall a b. b -> Either a b
Right Bool
True
Text
"yes" -> forall a b. b -> Either a b
Right Bool
True
Text
"t" -> forall a b. b -> Either a b
Right Bool
True
Text
"y" -> forall a b. b -> Either a b
Right Bool
True
Text
"false" -> forall a b. b -> Either a b
Right Bool
False
Text
"no" -> forall a b. b -> Either a b
Right Bool
False
Text
"f" -> forall a b. b -> Either a b
Right Bool
False
Text
"n" -> forall a b. b -> Either a b
Right Bool
False
Text
_ -> forall a b. a -> Either a b
Left (String
"Unable to parse " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
s forall a. [a] -> [a] -> [a]
++ String
" as a boolean")
emit :: Bool -> a
emit Bool
True = a
"true"
emit Bool
False = a
"false"
listWithSeparator :: IsList l => Text -> FieldValue (Item l) -> FieldValue l
listWithSeparator :: forall l. IsList l => Text -> FieldValue (Item l) -> FieldValue l
listWithSeparator Text
sep FieldValue (Item l)
fv =
FieldValue
{ fvParse :: Text -> Either String l
fvParse = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall l. IsList l => [Item l] -> l
fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a. FieldValue a -> Text -> Either String a
fvParse FieldValue (Item l)
fv forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> [Text]
T.splitOn Text
sep,
fvEmit :: l -> Text
fvEmit = Text -> [Text] -> Text
T.intercalate Text
sep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. FieldValue a -> a -> Text
fvEmit FieldValue (Item l)
fv) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall l. IsList l => l -> [Item l]
toList
}
pairWithSeparator :: FieldValue l -> Text -> FieldValue r -> FieldValue (l, r)
pairWithSeparator :: forall l r.
FieldValue l -> Text -> FieldValue r -> FieldValue (l, r)
pairWithSeparator FieldValue l
left Text
sep FieldValue r
right =
FieldValue
{ fvParse :: Text -> Either String (l, r)
fvParse = \Text
t ->
let (Text
leftChunk, Text
rightChunk) = Text -> Text -> (Text, Text)
T.breakOn Text
sep Text
t
in do
l
x <- forall a. FieldValue a -> Text -> Either String a
fvParse FieldValue l
left Text
leftChunk
r
y <- forall a. FieldValue a -> Text -> Either String a
fvParse FieldValue r
right Text
rightChunk
forall (m :: * -> *) a. Monad m => a -> m a
return (l
x, r
y),
fvEmit :: (l, r) -> Text
fvEmit = \(l
x, r
y) -> forall a. FieldValue a -> a -> Text
fvEmit FieldValue l
left l
x forall a. Semigroup a => a -> a -> a
<> Text
sep forall a. Semigroup a => a -> a -> a
<> forall a. FieldValue a -> a -> Text
fvEmit FieldValue r
right r
y
}
parseSections ::
s ->
Seq.ViewL (Section s) ->
Seq (NormalizedText, IniSection) ->
Either String s
parseSections :: forall s.
s
-> ViewL (Section s)
-> Seq (NormalizedText, IniSection)
-> Either String s
parseSections s
s ViewL (Section s)
Seq.EmptyL Seq (NormalizedText, IniSection)
_ = forall a b. b -> Either a b
Right s
s
parseSections s
s (Section NormalizedText
name Seq (Field s)
fs Bool
opt Seq.:< Seq (Section s)
rest) Seq (NormalizedText, IniSection)
i
| Just IniSection
v <- forall a. NormalizedText -> Seq (NormalizedText, a) -> Maybe a
lkp NormalizedText
name Seq (NormalizedText, IniSection)
i = do
s
s' <- forall s. s -> ViewL (Field s) -> IniSection -> Either String s
parseFields s
s (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs) IniSection
v
forall s.
s
-> ViewL (Section s)
-> Seq (NormalizedText, IniSection)
-> Either String s
parseSections s
s' (forall a. Seq a -> ViewL a
Seq.viewl Seq (Section s)
rest) Seq (NormalizedText, IniSection)
i
| Bool
opt = forall s.
s
-> ViewL (Section s)
-> Seq (NormalizedText, IniSection)
-> Either String s
parseSections s
s (forall a. Seq a -> ViewL a
Seq.viewl Seq (Section s)
rest) Seq (NormalizedText, IniSection)
i
| Bool
otherwise =
forall a b. a -> Either a b
Left
( String
"Unable to find section "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (NormalizedText -> Text
normalizedText NormalizedText
name)
)
parseFields :: s -> Seq.ViewL (Field s) -> IniSection -> Either String s
parseFields :: forall s. s -> ViewL (Field s) -> IniSection -> Either String s
parseFields s
s ViewL (Field s)
Seq.EmptyL IniSection
_ = forall a b. b -> Either a b
Right s
s
parseFields s
s (Field Lens s s a a
l FieldDescription a
descr Seq.:< Seq (Field s)
fs) IniSection
sect
| Just IniValue
v <- forall a. NormalizedText -> Seq (NormalizedText, a) -> Maybe a
lkp (forall t. FieldDescription t -> NormalizedText
fdName FieldDescription a
descr) (IniSection -> Seq (NormalizedText, IniValue)
isVals IniSection
sect) = do
a
value <- forall a. FieldValue a -> Text -> Either String a
fvParse (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
descr) (Text -> Text
T.strip (IniValue -> Text
vValue IniValue
v))
forall s. s -> ViewL (Field s) -> IniSection -> Either String s
parseFields (forall s t a b. Lens s t a b -> b -> s -> t
set Lens s s a a
l a
value s
s) (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs) IniSection
sect
| forall t. FieldDescription t -> Bool
fdSkipIfMissing FieldDescription a
descr =
forall s. s -> ViewL (Field s) -> IniSection -> Either String s
parseFields s
s (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs) IniSection
sect
| Bool
otherwise =
forall a b. a -> Either a b
Left
( String
"Unable to find field "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (NormalizedText -> Text
normalizedText (forall t. FieldDescription t -> NormalizedText
fdName FieldDescription a
descr))
)
parseFields s
s (FieldMb Lens s s (Maybe a) (Maybe a)
l FieldDescription a
descr Seq.:< Seq (Field s)
fs) IniSection
sect
| Just IniValue
v <- forall a. NormalizedText -> Seq (NormalizedText, a) -> Maybe a
lkp (forall t. FieldDescription t -> NormalizedText
fdName FieldDescription a
descr) (IniSection -> Seq (NormalizedText, IniValue)
isVals IniSection
sect) = do
a
value <- forall a. FieldValue a -> Text -> Either String a
fvParse (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
descr) (Text -> Text
T.strip (IniValue -> Text
vValue IniValue
v))
forall s. s -> ViewL (Field s) -> IniSection -> Either String s
parseFields (forall s t a b. Lens s t a b -> b -> s -> t
set Lens s s (Maybe a) (Maybe a)
l (forall a. a -> Maybe a
Just a
value) s
s) (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs) IniSection
sect
| Bool
otherwise =
forall s. s -> ViewL (Field s) -> IniSection -> Either String s
parseFields (forall s t a b. Lens s t a b -> b -> s -> t
set Lens s s (Maybe a) (Maybe a)
l forall a. Maybe a
Nothing s
s) (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs) IniSection
sect
emitIniFile :: s -> Spec s -> RawIni
emitIniFile :: forall s. s -> Spec s -> RawIni
emitIniFile s
s Spec s
spec =
Seq (NormalizedText, IniSection) -> RawIni
RawIni forall a b. (a -> b) -> a -> b
$
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( \(Section NormalizedText
name Seq (Field s)
fs Bool
_) ->
(NormalizedText
name, forall s. s -> Text -> Seq (Field s) -> IniSection
toSection s
s (NormalizedText -> Text
actualText NormalizedText
name) Seq (Field s)
fs)
)
Spec s
spec
mkComments :: Seq Text -> Seq BlankLine
= forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Text
ln -> Char -> Text -> BlankLine
CommentLine Char
'#' (Text
" " forall a. Semigroup a => a -> a -> a
<> Text
ln))
toSection :: s -> Text -> Seq (Field s) -> IniSection
toSection :: forall s. s -> Text -> Seq (Field s) -> IniSection
toSection s
s Text
name Seq (Field s)
fs =
IniSection
{ isName :: Text
isName = Text
name,
isVals :: Seq (NormalizedText, IniValue)
isVals = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Field s -> (NormalizedText, IniValue)
toVal Seq (Field s)
fs,
isStartLine :: Int
isStartLine = Int
0,
isEndLine :: Int
isEndLine = Int
0,
isComments :: Seq BlankLine
isComments = forall a. Seq a
Seq.empty
}
where
mkIniValue :: Text -> FieldDescription t -> Bool -> (NormalizedText, IniValue)
mkIniValue Text
val FieldDescription t
descr Bool
opt =
( forall t. FieldDescription t -> NormalizedText
fdName FieldDescription t
descr,
IniValue
{ vLineNo :: Int
vLineNo = Int
0,
vName :: Text
vName = NormalizedText -> Text
actualText (forall t. FieldDescription t -> NormalizedText
fdName FieldDescription t
descr),
vValue :: Text
vValue = Text
" " forall a. Semigroup a => a -> a -> a
<> Text
val,
vComments :: Seq BlankLine
vComments = Seq Text -> Seq BlankLine
mkComments (forall t. FieldDescription t -> Seq Text
fdComment FieldDescription t
descr),
vCommentedOut :: Bool
vCommentedOut = Bool
opt,
vDelimiter :: Char
vDelimiter = Char
'='
}
)
toVal :: Field s -> (NormalizedText, IniValue)
toVal (Field Lens s s a a
l FieldDescription a
descr)
| Just Text
dummy <- forall t. FieldDescription t -> Maybe Text
fdDummy FieldDescription a
descr =
forall {t}.
Text -> FieldDescription t -> Bool -> (NormalizedText, IniValue)
mkIniValue Text
dummy FieldDescription a
descr Bool
False
| Bool
otherwise =
forall {t}.
Text -> FieldDescription t -> Bool -> (NormalizedText, IniValue)
mkIniValue (forall a. FieldValue a -> a -> Text
fvEmit (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
descr) (forall s t a b. Lens s t a b -> s -> a
get Lens s s a a
l s
s)) FieldDescription a
descr Bool
False
toVal (FieldMb Lens s s (Maybe a) (Maybe a)
l FieldDescription a
descr)
| Just Text
dummy <- forall t. FieldDescription t -> Maybe Text
fdDummy FieldDescription a
descr =
forall {t}.
Text -> FieldDescription t -> Bool -> (NormalizedText, IniValue)
mkIniValue Text
dummy FieldDescription a
descr Bool
True
| Just a
v <- forall s t a b. Lens s t a b -> s -> a
get Lens s s (Maybe a) (Maybe a)
l s
s =
forall {t}.
Text -> FieldDescription t -> Bool -> (NormalizedText, IniValue)
mkIniValue (forall a. FieldValue a -> a -> Text
fvEmit (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
descr) a
v) FieldDescription a
descr Bool
True
| Bool
otherwise =
forall {t}.
Text -> FieldDescription t -> Bool -> (NormalizedText, IniValue)
mkIniValue Text
"" FieldDescription a
descr Bool
True
data UpdatePolicy = UpdatePolicy
{
UpdatePolicy -> Bool
updateAddOptionalFields :: Bool,
:: Bool,
:: UpdateCommentPolicy
}
deriving (UpdatePolicy -> UpdatePolicy -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UpdatePolicy -> UpdatePolicy -> Bool
$c/= :: UpdatePolicy -> UpdatePolicy -> Bool
== :: UpdatePolicy -> UpdatePolicy -> Bool
$c== :: UpdatePolicy -> UpdatePolicy -> Bool
Eq, Int -> UpdatePolicy -> ShowS
[UpdatePolicy] -> ShowS
UpdatePolicy -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UpdatePolicy] -> ShowS
$cshowList :: [UpdatePolicy] -> ShowS
show :: UpdatePolicy -> String
$cshow :: UpdatePolicy -> String
showsPrec :: Int -> UpdatePolicy -> ShowS
$cshowsPrec :: Int -> UpdatePolicy -> ShowS
Show)
defaultUpdatePolicy :: UpdatePolicy
defaultUpdatePolicy :: UpdatePolicy
defaultUpdatePolicy =
UpdatePolicy
{ updateAddOptionalFields :: Bool
updateAddOptionalFields = Bool
False,
updateIgnoreExtraneousFields :: Bool
updateIgnoreExtraneousFields = Bool
True,
updateGeneratedCommentPolicy :: UpdateCommentPolicy
updateGeneratedCommentPolicy = UpdateCommentPolicy
CommentPolicyNone
}
data
=
|
|
(Seq Text)
deriving (UpdateCommentPolicy -> UpdateCommentPolicy -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UpdateCommentPolicy -> UpdateCommentPolicy -> Bool
$c/= :: UpdateCommentPolicy -> UpdateCommentPolicy -> Bool
== :: UpdateCommentPolicy -> UpdateCommentPolicy -> Bool
$c== :: UpdateCommentPolicy -> UpdateCommentPolicy -> Bool
Eq, Int -> UpdateCommentPolicy -> ShowS
[UpdateCommentPolicy] -> ShowS
UpdateCommentPolicy -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UpdateCommentPolicy] -> ShowS
$cshowList :: [UpdateCommentPolicy] -> ShowS
show :: UpdateCommentPolicy -> String
$cshow :: UpdateCommentPolicy -> String
showsPrec :: Int -> UpdateCommentPolicy -> ShowS
$cshowsPrec :: Int -> UpdateCommentPolicy -> ShowS
Show)
getComments :: FieldDescription s -> UpdateCommentPolicy -> Seq BlankLine
FieldDescription s
_ UpdateCommentPolicy
CommentPolicyNone = forall a. Seq a
Seq.empty
getComments FieldDescription s
f UpdateCommentPolicy
CommentPolicyAddFieldComment =
Seq Text -> Seq BlankLine
mkComments (forall t. FieldDescription t -> Seq Text
fdComment FieldDescription s
f)
getComments FieldDescription s
_ (CommentPolicyAddDefaultComment Seq Text
cs) =
Seq Text -> Seq BlankLine
mkComments Seq Text
cs
doUpdateIni :: s -> Ini s -> Either String (Ini s)
doUpdateIni :: forall s. s -> Ini s -> Either String (Ini s)
doUpdateIni
s
s
i :: Ini s
i@Ini
{ iniSpec :: forall s. Ini s -> Spec s
iniSpec = Spec s
spec,
iniDef :: forall s. Ini s -> s
iniDef = s
def,
iniPol :: forall s. Ini s -> UpdatePolicy
iniPol = UpdatePolicy
pol
} = do
let RawIni Seq (NormalizedText, IniSection)
ini' = forall s. Ini s -> RawIni
getRawIni Ini s
i
Seq (NormalizedText, IniSection)
res <- forall s.
s
-> s
-> Seq (NormalizedText, IniSection)
-> Seq (Section s)
-> UpdatePolicy
-> Either String (Seq (NormalizedText, IniSection))
updateSections s
s s
def Seq (NormalizedText, IniSection)
ini' Spec s
spec UpdatePolicy
pol
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
Ini s
i
{ iniCurr :: s
iniCurr = s
s,
iniLast :: Maybe RawIni
iniLast = forall a. a -> Maybe a
Just (Seq (NormalizedText, IniSection) -> RawIni
RawIni Seq (NormalizedText, IniSection)
res)
}
updateSections ::
s ->
s ->
Seq (NormalizedText, IniSection) ->
Seq (Section s) ->
UpdatePolicy ->
Either String (Seq (NormalizedText, IniSection))
updateSections :: forall s.
s
-> s
-> Seq (NormalizedText, IniSection)
-> Seq (Section s)
-> UpdatePolicy
-> Either String (Seq (NormalizedText, IniSection))
updateSections s
s s
def Seq (NormalizedText, IniSection)
sections Seq (Section s)
fields UpdatePolicy
pol = do
Seq (NormalizedText, IniSection)
existingSections <- forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
F.for Seq (NormalizedText, IniSection)
sections forall a b. (a -> b) -> a -> b
$ \(NormalizedText
name, IniSection
sec) -> do
let err :: Either String b
err = forall a b. a -> Either a b
Left (String
"Unexpected top-level section: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show NormalizedText
name)
Section NormalizedText
_ Seq (Field s)
spec Bool
_ <-
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
forall {b}. Either String b
err
forall a b. b -> Either a b
Right
(forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
F.find (\(Section NormalizedText
n Seq (Field s)
_ Bool
_) -> NormalizedText
n forall a. Eq a => a -> a -> Bool
== NormalizedText
name) Seq (Section s)
fields)
Seq (NormalizedText, IniValue)
newVals <- forall s.
s
-> Seq (NormalizedText, IniValue)
-> Seq (Field s)
-> UpdatePolicy
-> Either String (Seq (NormalizedText, IniValue))
updateFields s
s (IniSection -> Seq (NormalizedText, IniValue)
isVals IniSection
sec) Seq (Field s)
spec UpdatePolicy
pol
forall (m :: * -> *) a. Monad m => a -> m a
return (NormalizedText
name, IniSection
sec {isVals :: Seq (NormalizedText, IniValue)
isVals = Seq (NormalizedText, IniValue)
newVals})
let existingSectionNames :: Seq NormalizedText
existingSectionNames = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst Seq (NormalizedText, IniSection)
existingSections
Seq (Seq (NormalizedText, IniSection))
newSections <- forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
F.for Seq (Section s)
fields forall a b. (a -> b) -> a -> b
$
\(Section NormalizedText
nm Seq (Field s)
spec Bool
_) ->
if NormalizedText
nm forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Seq NormalizedText
existingSectionNames
then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
else
let rs :: Seq (NormalizedText, IniValue)
rs = forall s.
s
-> s
-> Seq (Field s)
-> UpdatePolicy
-> Seq (NormalizedText, IniValue)
emitNewFields s
s s
def Seq (Field s)
spec UpdatePolicy
pol
in if forall a. Seq a -> Bool
Seq.null Seq (NormalizedText, IniValue)
rs
then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
else
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
forall a. a -> Seq a
Seq.singleton
( NormalizedText
nm,
Text
-> Seq (NormalizedText, IniValue)
-> Int
-> Int
-> Seq BlankLine
-> IniSection
IniSection (NormalizedText -> Text
actualText NormalizedText
nm) Seq (NormalizedText, IniValue)
rs Int
0 Int
0 forall a. Monoid a => a
mempty
)
forall (m :: * -> *) a. Monad m => a -> m a
return (Seq (NormalizedText, IniSection)
existingSections forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
F.asum Seq (Seq (NormalizedText, IniSection))
newSections)
emitNewFields ::
s ->
s ->
Seq (Field s) ->
UpdatePolicy ->
Seq (NormalizedText, IniValue)
emitNewFields :: forall s.
s
-> s
-> Seq (Field s)
-> UpdatePolicy
-> Seq (NormalizedText, IniValue)
emitNewFields s
s s
def Seq (Field s)
fields UpdatePolicy
pol = ViewL (Field s) -> Seq (NormalizedText, IniValue)
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fields)
where
go :: ViewL (Field s) -> Seq (NormalizedText, IniValue)
go ViewL (Field s)
EmptyL = forall a. Seq a
Seq.empty
go (Field Lens s s a a
l FieldDescription a
d :< Seq (Field s)
fs)
| forall s t a b. Lens s t a b -> s -> a
get Lens s s a a
l s
s forall a. Eq a => a -> a -> Bool
== forall s t a b. Lens s t a b -> s -> a
get Lens s s a a
l s
def Bool -> Bool -> Bool
&& Bool -> Bool
not (UpdatePolicy -> Bool
updateAddOptionalFields UpdatePolicy
pol) =
ViewL (Field s) -> Seq (NormalizedText, IniValue)
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs)
| Bool
otherwise =
let cs :: Seq BlankLine
cs = forall s.
FieldDescription s -> UpdateCommentPolicy -> Seq BlankLine
getComments FieldDescription a
d (UpdatePolicy -> UpdateCommentPolicy
updateGeneratedCommentPolicy UpdatePolicy
pol)
new :: (NormalizedText, IniValue)
new =
( forall t. FieldDescription t -> NormalizedText
fdName FieldDescription a
d,
IniValue
{ vLineNo :: Int
vLineNo = Int
0,
vName :: Text
vName = NormalizedText -> Text
actualText (forall t. FieldDescription t -> NormalizedText
fdName FieldDescription a
d),
vValue :: Text
vValue = Text
" " forall a. Semigroup a => a -> a -> a
<> forall a. FieldValue a -> a -> Text
fvEmit (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
d) (forall s t a b. Lens s t a b -> s -> a
get Lens s s a a
l s
s),
vComments :: Seq BlankLine
vComments = Seq BlankLine
cs,
vCommentedOut :: Bool
vCommentedOut = Bool
False,
vDelimiter :: Char
vDelimiter = Char
'='
}
)
in (NormalizedText, IniValue)
new forall a. a -> Seq a -> Seq a
<| ViewL (Field s) -> Seq (NormalizedText, IniValue)
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs)
go (FieldMb Lens s s (Maybe a) (Maybe a)
l FieldDescription a
d :< Seq (Field s)
fs) =
case forall s t a b. Lens s t a b -> s -> a
get Lens s s (Maybe a) (Maybe a)
l s
s of
Maybe a
Nothing -> ViewL (Field s) -> Seq (NormalizedText, IniValue)
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs)
Just a
v ->
let cs :: Seq BlankLine
cs = forall s.
FieldDescription s -> UpdateCommentPolicy -> Seq BlankLine
getComments FieldDescription a
d (UpdatePolicy -> UpdateCommentPolicy
updateGeneratedCommentPolicy UpdatePolicy
pol)
new :: (NormalizedText, IniValue)
new =
( forall t. FieldDescription t -> NormalizedText
fdName FieldDescription a
d,
IniValue
{ vLineNo :: Int
vLineNo = Int
0,
vName :: Text
vName = NormalizedText -> Text
actualText (forall t. FieldDescription t -> NormalizedText
fdName FieldDescription a
d),
vValue :: Text
vValue = forall a. FieldValue a -> a -> Text
fvEmit (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
d) a
v,
vComments :: Seq BlankLine
vComments = Seq BlankLine
cs,
vCommentedOut :: Bool
vCommentedOut = Bool
False,
vDelimiter :: Char
vDelimiter = Char
'='
}
)
in (NormalizedText, IniValue)
new forall a. a -> Seq a -> Seq a
<| ViewL (Field s) -> Seq (NormalizedText, IniValue)
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs)
updateFields ::
s ->
Seq (NormalizedText, IniValue) ->
Seq (Field s) ->
UpdatePolicy ->
Either String (Seq (NormalizedText, IniValue))
updateFields :: forall s.
s
-> Seq (NormalizedText, IniValue)
-> Seq (Field s)
-> UpdatePolicy
-> Either String (Seq (NormalizedText, IniValue))
updateFields s
s Seq (NormalizedText, IniValue)
values Seq (Field s)
fields UpdatePolicy
pol = ViewL (NormalizedText, IniValue)
-> Seq (Field s) -> Either String (Seq (NormalizedText, IniValue))
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (NormalizedText, IniValue)
values) Seq (Field s)
fields
where
go :: ViewL (NormalizedText, IniValue)
-> Seq (Field s) -> Either String (Seq (NormalizedText, IniValue))
go ((NormalizedText
t, IniValue
val) :< Seq (NormalizedText, IniValue)
vs) Seq (Field s)
fs =
case forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
F.find (\Field s
f -> forall s. Field s -> NormalizedText
fieldName Field s
f forall a. Eq a => a -> a -> Bool
== NormalizedText
t) Seq (Field s)
fs of
Just f :: Field s
f@(Field Lens s s a a
l FieldDescription a
descr) ->
if forall a b. b -> Either a b
Right (forall s t a b. Lens s t a b -> s -> a
get Lens s s a a
l s
s) forall a. Eq a => a -> a -> Bool
== forall a. FieldValue a -> Text -> Either String a
fvParse (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
descr) (Text -> Text
T.strip (IniValue -> Text
vValue IniValue
val))
then
((NormalizedText
t, IniValue
val) forall a. a -> Seq a -> Seq a
<|) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` ViewL (NormalizedText, IniValue)
-> Seq (Field s) -> Either String (Seq (NormalizedText, IniValue))
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (NormalizedText, IniValue)
vs) (forall s. NormalizedText -> Seq (Field s) -> Seq (Field s)
rmv NormalizedText
t Seq (Field s)
fs)
else
let Just IniValue
nv = NormalizedText -> Field s -> Char -> Maybe IniValue
mkValue NormalizedText
t Field s
f (IniValue -> Char
vDelimiter IniValue
val)
in ((NormalizedText
t, IniValue
nv) forall a. a -> Seq a -> Seq a
<|) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` ViewL (NormalizedText, IniValue)
-> Seq (Field s) -> Either String (Seq (NormalizedText, IniValue))
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (NormalizedText, IniValue)
vs) (forall s. NormalizedText -> Seq (Field s) -> Seq (Field s)
rmv NormalizedText
t Seq (Field s)
fs)
Just f :: Field s
f@(FieldMb Lens s s (Maybe a) (Maybe a)
l FieldDescription a
descr) ->
let parsed :: Either String a
parsed = forall a. FieldValue a -> Text -> Either String a
fvParse (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
descr) (Text -> Text
T.strip (IniValue -> Text
vValue IniValue
val))
in if forall a b. b -> Either a b
Right (forall s t a b. Lens s t a b -> s -> a
get Lens s s (Maybe a) (Maybe a)
l s
s) forall a. Eq a => a -> a -> Bool
== forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just Either String a
parsed
then ((NormalizedText
t, IniValue
val) forall a. a -> Seq a -> Seq a
<|) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` ViewL (NormalizedText, IniValue)
-> Seq (Field s) -> Either String (Seq (NormalizedText, IniValue))
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (NormalizedText, IniValue)
vs) (forall s. NormalizedText -> Seq (Field s) -> Seq (Field s)
rmv NormalizedText
t Seq (Field s)
fs)
else
case NormalizedText -> Field s -> Char -> Maybe IniValue
mkValue NormalizedText
t Field s
f (IniValue -> Char
vDelimiter IniValue
val) of
Just IniValue
nv -> ((NormalizedText
t, IniValue
nv) forall a. a -> Seq a -> Seq a
<|) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` ViewL (NormalizedText, IniValue)
-> Seq (Field s) -> Either String (Seq (NormalizedText, IniValue))
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (NormalizedText, IniValue)
vs) (forall s. NormalizedText -> Seq (Field s) -> Seq (Field s)
rmv NormalizedText
t Seq (Field s)
fs)
Maybe IniValue
Nothing -> ViewL (NormalizedText, IniValue)
-> Seq (Field s) -> Either String (Seq (NormalizedText, IniValue))
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (NormalizedText, IniValue)
vs) (forall s. NormalizedText -> Seq (Field s) -> Seq (Field s)
rmv NormalizedText
t Seq (Field s)
fs)
Maybe (Field s)
Nothing
| UpdatePolicy -> Bool
updateIgnoreExtraneousFields UpdatePolicy
pol ->
((NormalizedText
t, IniValue
val) forall a. a -> Seq a -> Seq a
<|) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` ViewL (NormalizedText, IniValue)
-> Seq (Field s) -> Either String (Seq (NormalizedText, IniValue))
go (forall a. Seq a -> ViewL a
Seq.viewl Seq (NormalizedText, IniValue)
vs) Seq (Field s)
fs
| Bool
otherwise -> forall a b. a -> Either a b
Left (String
"Unexpected field: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show NormalizedText
t)
go ViewL (NormalizedText, IniValue)
EmptyL Seq (Field s)
fs = forall (m :: * -> *) a. Monad m => a -> m a
return (ViewL (Field s) -> Seq (NormalizedText, IniValue)
finish (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs))
finish :: ViewL (Field s) -> Seq (NormalizedText, IniValue)
finish (f :: Field s
f@Field {} :< Seq (Field s)
fs)
| UpdatePolicy -> Bool
updateAddOptionalFields UpdatePolicy
pol,
Just IniValue
val <- NormalizedText -> Field s -> Char -> Maybe IniValue
mkValue (forall s. Field s -> NormalizedText
fieldName Field s
f) Field s
f Char
'=' =
(forall s. Field s -> NormalizedText
fieldName Field s
f, IniValue
val) forall a. a -> Seq a -> Seq a
<| ViewL (Field s) -> Seq (NormalizedText, IniValue)
finish (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs)
| Bool
otherwise = ViewL (Field s) -> Seq (NormalizedText, IniValue)
finish (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs)
finish (f :: Field s
f@(FieldMb Lens s s (Maybe a) (Maybe a)
_ FieldDescription a
descr) :< Seq (Field s)
fs)
| Bool -> Bool
not (forall t. FieldDescription t -> Bool
fdSkipIfMissing FieldDescription a
descr),
Just IniValue
val <- NormalizedText -> Field s -> Char -> Maybe IniValue
mkValue (forall s. Field s -> NormalizedText
fieldName Field s
f) Field s
f Char
'=' =
(forall s. Field s -> NormalizedText
fieldName Field s
f, IniValue
val) forall a. a -> Seq a -> Seq a
<| ViewL (Field s) -> Seq (NormalizedText, IniValue)
finish (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs)
| UpdatePolicy -> Bool
updateAddOptionalFields UpdatePolicy
pol,
Just IniValue
val <- NormalizedText -> Field s -> Char -> Maybe IniValue
mkValue (forall s. Field s -> NormalizedText
fieldName Field s
f) Field s
f Char
'=' =
(forall s. Field s -> NormalizedText
fieldName Field s
f, IniValue
val) forall a. a -> Seq a -> Seq a
<| ViewL (Field s) -> Seq (NormalizedText, IniValue)
finish (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs)
| Bool
otherwise = ViewL (Field s) -> Seq (NormalizedText, IniValue)
finish (forall a. Seq a -> ViewL a
Seq.viewl Seq (Field s)
fs)
finish ViewL (Field s)
EmptyL = forall a. Seq a
Seq.empty
mkValue :: NormalizedText -> Field s -> Char -> Maybe IniValue
mkValue NormalizedText
t Field s
fld Char
delim =
let comments :: Seq BlankLine
comments = case UpdatePolicy -> UpdateCommentPolicy
updateGeneratedCommentPolicy UpdatePolicy
pol of
UpdateCommentPolicy
CommentPolicyNone -> forall a. Seq a
Seq.empty
UpdateCommentPolicy
CommentPolicyAddFieldComment ->
Seq Text -> Seq BlankLine
mkComments (forall s. Field s -> Seq Text
fieldComment Field s
fld)
CommentPolicyAddDefaultComment Seq Text
cs ->
Seq Text -> Seq BlankLine
mkComments Seq Text
cs
val :: IniValue
val =
IniValue
{ vLineNo :: Int
vLineNo = Int
0,
vName :: Text
vName = NormalizedText -> Text
actualText NormalizedText
t,
vValue :: Text
vValue = Text
"",
vComments :: Seq BlankLine
vComments = Seq BlankLine
comments,
vCommentedOut :: Bool
vCommentedOut = Bool
False,
vDelimiter :: Char
vDelimiter = Char
delim
}
in case Field s
fld of
Field Lens s s a a
l FieldDescription a
descr ->
forall a. a -> Maybe a
Just (IniValue
val {vValue :: Text
vValue = Text
" " forall a. Semigroup a => a -> a -> a
<> forall a. FieldValue a -> a -> Text
fvEmit (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
descr) (forall s t a b. Lens s t a b -> s -> a
get Lens s s a a
l s
s)})
FieldMb Lens s s (Maybe a) (Maybe a)
l FieldDescription a
descr ->
case forall s t a b. Lens s t a b -> s -> a
get Lens s s (Maybe a) (Maybe a)
l s
s of
Just a
v -> forall a. a -> Maybe a
Just (IniValue
val {vValue :: Text
vValue = Text
" " forall a. Semigroup a => a -> a -> a
<> forall a. FieldValue a -> a -> Text
fvEmit (forall t. FieldDescription t -> FieldValue t
fdValue FieldDescription a
descr) a
v})
Maybe a
Nothing -> forall a. Maybe a
Nothing