Skip to content

Commit

Permalink
[#15] Add lenses for config-related types
Browse files Browse the repository at this point in the history
Problem: It's quite inconvenient to access config-related records'
fields by hand, especially when it comes to nested ones.

Solution: Add lenses for config-related types and add common lenses
operators & types.
  • Loading branch information
nalkuatov committed Jun 28, 2022
1 parent 5e15805 commit c64bc83
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 1 deletion.
6 changes: 5 additions & 1 deletion core/nyan-interpolation-core.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ cabal-version: 2.0
--
-- see: https://github.com/sol/hpack
--
-- hash: 454835beb066a76fcd19ff1540bc89d3e2f2732ac9d7164ec5903d0eb782bebd
-- hash: 53cd08bc1c6de787c00e5dddb89582000ea02db4675760cf87d8f583338306da

name: nyan-interpolation-core
version: 0.9
Expand All @@ -30,10 +30,13 @@ library
exposed-modules:
Text.Interpolation.Nyan.Core
Text.Interpolation.Nyan.Core.Internal.Base
Text.Interpolation.Nyan.Core.Internal.Base.Lens
Text.Interpolation.Nyan.Core.Internal.Parser
Text.Interpolation.Nyan.Core.Internal.Processor
Text.Interpolation.Nyan.Core.Internal.RMode
Text.Interpolation.Nyan.Core.Internal.Splice
Text.Interpolation.Nyan.Lens
Text.Interpolation.Nyan.Lens.Type
Text.Interpolation.Nyan.RModes.Buildable
Text.Interpolation.Nyan.RModes.CommonExtra
Text.Interpolation.Nyan.RModes.Show
Expand Down Expand Up @@ -91,6 +94,7 @@ test-suite nyan-interpolation-core-tests
other-modules:
Test.Customization
Test.Interpolator
Test.Lens
Test.Parser
Test.Processor
Test.Util
Expand Down
62 changes: 62 additions & 0 deletions core/src/Text/Interpolation/Nyan/Core/Internal/Base/Lens.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
-- SPDX-FileCopyrightText: 2022 Serokell <https://serokell.io/>
--
-- SPDX-License-Identifier: MPL-2.0

-- | Exports basic lens for config-related types.
module Text.Interpolation.Nyan.Core.Internal.Base.Lens where

import Text.Interpolation.Nyan.Core.Internal.Base
import Text.Interpolation.Nyan.Lens

---------------------------------------------------------------------
-- Basic lens for 'SwitchesOptions'
---------------------------------------------------------------------

spacesTrimmingL, indentationStrippingL, leadingNewlineStrippingL,
trailingSpacesStrippingL, reducedNewlinesL, monadicL :: Lens' SwitchesOptions Bool

spacesTrimmingL = lens spacesTrimming (\s a -> s { spacesTrimming = a })
indentationStrippingL = lens indentationStripping (\s a -> s { indentationStripping = a })
leadingNewlineStrippingL = lens leadingNewlineStripping (\s a -> s { leadingNewlineStripping = a })
trailingSpacesStrippingL = lens trailingSpacesStripping (\s a -> s { trailingSpacesStripping = a })
reducedNewlinesL = lens reducedNewlines (\s a -> s { reducedNewlines = a })
monadicL = lens monadic (\s a -> s { monadic = a })

returnTypeL :: Lens' SwitchesOptions ReturnType
returnTypeL = lens returnType (\s a -> s { returnType = a })

previewLevelL :: Lens' SwitchesOptions PreviewLevel
previewLevelL = lens previewLevel (\s a -> s { previewLevel = a })

---------------------------------------------------------------------
-- Basic lens for 'DefaultSwitchesOptions'
---------------------------------------------------------------------

defSpacesTrimmingL, defIndentationStrippingL, defLeadingNewlineStrippingL,
defTrailingSpacesStrippingL, defReducedNewlinesL, defMonadicL
:: Lens' DefaultSwitchesOptions (Maybe Bool)

defSpacesTrimmingL = lens defSpacesTrimming (\s a -> s { defSpacesTrimming = a })
defIndentationStrippingL = lens defIndentationStripping (\s a -> s { defIndentationStripping = a })
defLeadingNewlineStrippingL =
lens defLeadingNewlineStripping (\s a -> s { defLeadingNewlineStripping = a })
defTrailingSpacesStrippingL =
lens defTrailingSpacesStripping (\s a -> s { defTrailingSpacesStripping = a })
defReducedNewlinesL = lens defReducedNewlines (\s a -> s { defReducedNewlines = a })
defMonadicL = lens defMonadic (\s a -> s { defMonadic = a })

defReturnTypeL :: Lens' DefaultSwitchesOptions (Maybe ReturnType)
defReturnTypeL = lens defReturnType (\s a -> s { defReturnType = a })

---------------------------------------------------------------------
-- Basic lens for 'InterpolatorOptions'
---------------------------------------------------------------------

defaultSwitchesOptionsL :: Lens' InterpolatorOptions DefaultSwitchesOptions
defaultSwitchesOptionsL = lens defaultSwitchesOptions (\s a -> s { defaultSwitchesOptions = a })

valueInterpolatorL :: Lens' InterpolatorOptions ValueInterpolator
valueInterpolatorL = lens valueInterpolator (\s a -> s { valueInterpolator = a })

invisibleCharsPreviewL :: Lens' InterpolatorOptions InvisibleCharsPreview
invisibleCharsPreviewL = lens invisibleCharsPreview (\s a -> s { invisibleCharsPreview = a })
33 changes: 33 additions & 0 deletions core/src/Text/Interpolation/Nyan/Lens.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- SPDX-FileCopyrightText: 2022 Serokell <https://serokell.io/>
--
-- SPDX-License-Identifier: MPL-2.0

module Text.Interpolation.Nyan.Lens
( module Text.Interpolation.Nyan.Lens.Type
, view
, over
, set
, lens
, (^.)
)
where

import Control.Applicative (Const(..))
import Data.Functor.Identity (Identity(..))

import Text.Interpolation.Nyan.Lens.Type

(^.) :: s -> SimpleGetter s a -> a
s ^. l = view l s

set :: ASetter' s a -> a -> s -> s
set l a = runIdentity . l (const $ Identity a)

view :: SimpleGetter s a -> s -> a
view l = getConst . l Const

over :: ASetter' s a -> (a -> a) -> s -> s
over l f = runIdentity . l (Identity . f)

lens :: Functor f => (s -> a) -> (s -> a -> s) -> (a -> f a) -> s -> f s
lens getter setter f s = setter s <$> f (getter s)
17 changes: 17 additions & 0 deletions core/src/Text/Interpolation/Nyan/Lens/Type.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- SPDX-FileCopyrightText: 2022 Serokell <https://serokell.io/>
--
-- SPDX-License-Identifier: MPL-2.0

module Text.Interpolation.Nyan.Lens.Type where

import Control.Applicative (Const)
import Data.Functor.Identity (Identity)

type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
type Lens' s a = Lens s s a a

type ASetter s t a b = (a -> Identity b) -> s -> Identity t
type ASetter' s a = ASetter s s a a

type Getting r s a = (a -> Const r a) -> s -> Const r s
type SimpleGetter s a = forall r. Getting r s a

0 comments on commit c64bc83

Please sign in to comment.