pro-source-0.1.0.0: src/ProSource/HasLocation.hs
{- |
Copyright: © 2020 James Alexander Feldman-Crough
License: MPL-2.0
-}
module ProSource.HasLocation
( -- * Classy optics; implementable on all types with a location
HasLocation(..), offset
-- ** Read-only optics
, column, line, source
) where
import ProSource.Location
import ProSource.Units
import ProSource.SparseLocation
import ProSource.Source
import ProSource.LocationOps
-- | A classy optic for selecting the 'Location' from a value. Note that 'location' is affine: a 'Location' can't be attached to a value which does not -- already have one, and not all values with an instance of 'HasLocation' have a location.
class HasLocation t where
location :: AffineTraversal' t Location
instance HasLocation Location where
location = castOptic simple
-- | Focus on the 'Offset' from a value parsed from a source file. If the 'Offset' is modified, note that the resulting 'column' and 'line' will /also/ be modified as they are denormalizations of this value.
offset :: HasLocation l => AffineTraversal' l Offset
offset = location % sparse % lens
sparseLocationOffset
(\sl x -> sl { sparseLocationOffset = x })
-- | Fetch the 'Column' from a value parsed from a source file. Modifications are not allowed as the 'offset' and 'line' may become inconsistent.
column :: HasLocation l => AffineFold l Column
column = location % to locationColumn
-- | Fetch the 'Line' from a value parsed from a source file. Modifications are not allowed as the 'offset' and 'column' may become inconsistent.
line :: HasLocation l => AffineFold l Line
line = location % to locationLine
-- | Fetch the 'Source' a value was parsed from. Modifications are not allowed as the 'line', 'offset', and 'column' may become inconsistent.
source :: HasLocation l => AffineFold l Source
source = location % to locationSource