-- | Additional and utilities for 'Position' and 'Range'.
module Language.LSP.Protocol.Types.Location where

import Language.LSP.Protocol.Internal.Types.Position
import Language.LSP.Protocol.Internal.Types.Range
import Language.LSP.Protocol.Types.Common

{- | A helper function for creating ranges.
 prop> mkRange l c l' c' = Range (Position l c) (Position l' c')
-}
mkRange :: UInt -> UInt -> UInt -> UInt -> Range
mkRange :: UInt -> UInt -> UInt -> UInt -> Range
mkRange UInt
l UInt
c UInt
l' UInt
c' = Position -> Position -> Range
Range (UInt -> UInt -> Position
Position UInt
l UInt
c) (UInt -> UInt -> Position
Position UInt
l' UInt
c')

-- | 'isSubrangeOf' returns true if for every 'Position' in the first 'Range', it's also in the second 'Range'.
isSubrangeOf :: Range -> Range -> Bool
isSubrangeOf :: Range -> Range -> Bool
isSubrangeOf Range
smallRange Range
range = Range -> Position
_start Range
smallRange Position -> Position -> Bool
forall a. Ord a => a -> a -> Bool
>= Range -> Position
_start Range
range Bool -> Bool -> Bool
&& Range -> Position
_end Range
smallRange Position -> Position -> Bool
forall a. Ord a => a -> a -> Bool
<= Range -> Position
_end Range
range

-- | 'positionInRange' returns true if the given 'Position' is in the 'Range'.
positionInRange :: Position -> Range -> Bool
positionInRange :: Position -> Range -> Bool
positionInRange Position
p (Range Position
sp Position
ep) = Position
sp Position -> Position -> Bool
forall a. Ord a => a -> a -> Bool
<= Position
p Bool -> Bool -> Bool
&& Position
p Position -> Position -> Bool
forall a. Ord a => a -> a -> Bool
< Position
ep -- Range's end position is exclusive.