3 | module Data.String.Position
13 | record ValidPosition (str : String) where
14 | constructor MkValidPosition
18 | parameterLength : Int
25 | Position : String -> Type
26 | Position str = Maybe (ValidPosition str)
30 | mkPosition : (str : String) -> Int -> Position str
32 | = do let len : Int = cast (length str)
33 | guard (0 <= idx && idx < len)
34 | pure (MkValidPosition idx len)
38 | mvPosition : ValidPosition str -> Int -> Position str
39 | mvPosition (MkValidPosition pos len) idx
40 | = do guard (0 <= idx && idx < len)
41 | pure (MkValidPosition idx len)
45 | init : (str : String) -> Position str
46 | init str = mkPosition str 0
50 | next : ValidPosition str -> Position str
51 | next (MkValidPosition pos len)
52 | = do let idx = pos + 1
54 | pure (MkValidPosition idx len)
58 | index : {str : _} -> ValidPosition str -> Char
59 | index pos = assert_total (strIndex str pos.currentIndex)
65 | uncons : {str : _} -> ValidPosition str -> (Char, Position str)
66 | uncons pos = (index pos, next pos)
77 | span : {str : _} -> (Char -> Bool) -> Position str -> Position str
78 | span p pos = do (c, str) <- map uncons pos
79 | if p c then assert_total (span p str) else pos
85 | count : {str : _} -> (Char -> Bool) -> Position str -> Nat
87 | count p (Just pos) =
89 | then S (assert_total (count p (next pos)))
90 | else assert_total (count p (next pos))
96 | distance : (start : Position str) ->
97 | (end : Position str) -> Int
98 | distance Nothing _ = 0
99 | distance (Just pos) pos' =
100 | let start = pos.currentIndex
101 | end = maybe pos.parameterLength currentIndex pos'
107 | subString : {str : _} ->
108 | (start : Position str) ->
109 | (end : Position str) -> String
110 | subString Nothing pos' = ""
111 | subString (Just pos) pos' =
112 | let start = pos.currentIndex
113 | end = maybe pos.parameterLength currentIndex pos'
114 | in assert_total (strSubstr start (end - start) str)