loc-0.2.0.0: src/Data/Loc/SpanOrLoc.hs
module Data.Loc.SpanOrLoc
( SpanOrLoc,
-- * Constructing
span,
loc,
fromTo,
-- * Deconstructing
spanOrLoc,
-- * Querying
start,
end,
)
where
import Data.Loc.Internal.Prelude
import Data.Loc.Loc (Loc)
import Data.Loc.Loc qualified as Loc
import Data.Loc.Span (Span)
import Data.Loc.Span qualified as Span
-- | A 'SpanOrLoc' consists of a start location and an end location
--
-- The end location must be greater than or equal to the start location;
-- in other words, backwards spans are not permitted.
--
-- If the start and end location are the same, then the value is a 'Loc'.
-- If they differ, then the value is a 'Span'.
data SpanOrLoc = Span Span | Loc Loc
deriving (Eq, Ord)
instance Show SpanOrLoc where
showsPrec i = \case
Span x -> Span.spanShowsPrec i x
Loc x -> Loc.locShowsPrec i x
span :: Span -> SpanOrLoc
span = Span
loc :: Loc -> SpanOrLoc
loc = Loc
spanOrLoc :: (Span -> a) -> (Loc -> a) -> SpanOrLoc -> a
spanOrLoc f _ (Span x) = f x
spanOrLoc _ f (Loc x) = f x
-- | Construct a 'SpanOrLoc' from two 'Loc's
--
-- If the two locs are not equal, the lesser loc will be the start,
-- and the greater loc will be the end.
fromTo :: Loc -> Loc -> SpanOrLoc
fromTo a b =
maybe (Loc a) Span (Span.fromToMay a b)
start :: SpanOrLoc -> Loc
start = spanOrLoc Span.start id
end :: SpanOrLoc -> Loc
end = spanOrLoc Span.end id