0 | module HTTP.API.Decode
2 | import Data.List.Quantifiers as L
3 | import Derive.Prelude
4 | import HTTP.API.Encode
6 | import HTTP.Header.Types
7 | import HTTP.RequestErr
11 | import JSON.Simple.Derive
14 | %language ElabReflection
19 | data DecodeErr : Type where
26 | ReadErr : (type, value : String) -> (details : String) -> DecodeErr
32 | ContentErr : (type : String) -> (details : String) -> DecodeErr
35 | Msg : (message : String) -> DecodeErr
37 | %runElab derive "DecodeErr" [Show,Eq,FromJSON,ToJSON]
41 | readErr : (type : String) -> (value : ByteString) -> DecodeErr
42 | readErr type value = ReadErr type (toString value) ""
46 | contentErr : (type : String) -> Interpolation a => a -> DecodeErr
47 | contentErr type = ContentErr type . interpolate
51 | setType : String -> DecodeErr -> DecodeErr
52 | setType t (ReadErr _ v d) = ReadErr t v d
53 | setType t (ContentErr _ d) = ContentErr t d
54 | setType t (Msg m) = Msg m
58 | setValue : String -> DecodeErr -> DecodeErr
59 | setValue v (ReadErr t _ d) = ReadErr t v d
60 | setValue _ err = err
64 | modMsg : (String -> String) -> DecodeErr -> DecodeErr
65 | modMsg f (ReadErr t v d) = ReadErr t v (f d)
66 | modMsg f (ContentErr t d) = ContentErr t (f d)
67 | modMsg f (Msg m) = Msg (f m)
75 | interface Decode (0 a : Type) where
76 | decode : ByteString -> Either DecodeErr a
80 | public export %inline
81 | decodeAs : (0 a : Type) -> Decode a => ByteString -> Either DecodeErr a
87 | interface DecodeMany (0 a : Type) where
88 | simulateDecode : List ByteString -> Maybe (List ByteString)
90 | decodeMany : List ByteString -> Either DecodeErr (List ByteString, a)
93 | Decode a => DecodeMany a where
94 | simulateDecode [] = Nothing
95 | simulateDecode (b::bs) = Just bs
97 | decodeMany [] = Left (Msg "Unexpected end of URL path")
98 | decodeMany (b::bs) = (bs,) <$> decode b
105 | -> Either DecodeErr (List ByteString,SnocList a)
106 | decodeAll sx d [] = Right ([],sx)
107 | decodeAll sx d (x :: xs) =
108 | case decode @{d} x of
109 | Right v => decodeAll (sx:<v) d xs
110 | Left err => Left err
113 | Decode a => DecodeMany (SnocList a) where
114 | simulateDecode bs = Just []
115 | decodeMany = decodeAll [<] %search
118 | Decode a => DecodeMany (List a) where
119 | simulateDecode bs = Just []
120 | decodeMany bs = map (<>> []) <$> decodeAll [<] %search bs
123 | L.All.All (DecodeMany . f) ts
125 | -> Maybe (List ByteString)
126 | simulateHL [] xs = Just xs
127 | simulateHL (x :: y) xs =
128 | case simulateDecode @{x} xs of
130 | Just xs2 => simulateHL y xs2
133 | L.All.All (DecodeMany . f) ts
135 | -> Either DecodeErr (List ByteString, L.All.All f ts)
136 | decodeHL [] xs = Right (xs, [])
137 | decodeHL (x :: y) xs =
138 | case decodeMany @{x} xs of
139 | Left err => Left err
140 | Right (xs2, v) => map (v::) <$> decodeHL y xs2
143 | (all : L.All.All (DecodeMany . f) ts) => DecodeMany (L.All.All f ts) where
144 | simulateDecode = simulateHL all
145 | decodeMany = decodeHL all
151 | -> Maybe (List ByteString)
152 | simulateN x 0 xs = Just xs
153 | simulateN x (S n) xs =
154 | case simulateDecode @{x} xs of
156 | Just xs2 => simulateN x n xs2
162 | -> Either DecodeErr (List ByteString, Vect n t)
163 | decodeN x 0 xs = Right (xs, [])
164 | decodeN x (S n) xs =
165 | case decodeMany @{x} xs of
166 | Left err => Left err
167 | Right (xs2, v) => map (v::) <$> decodeN x n xs2
170 | {n : Nat} -> (x : DecodeMany a) => DecodeMany (Vect n a) where
171 | simulateDecode = simulateN x n
172 | decodeMany = decodeN x n
178 | namespace DecodeVia
180 | interface DecodeVia (0 from, to : Type) where
181 | fromBytes : Parameters -> ByteString -> Either DecodeErr from
182 | decodeFrom : from -> Either DecodeErr to
183 | mediaType : MediaType
186 | DecodeVia Octett ByteString where
187 | fromBytes _ = Right
189 | mediaType = applicationOctettStream
192 | DecodeVia ByteString String where
193 | fromBytes _ = Right
194 | decodeFrom = Right . toString
195 | mediaType = textPlain
199 | {0 from, to : Type}
200 | -> {auto d : DecodeVia from to}
203 | -> Either DecodeErr to
204 | decodeVia ps bs = fromBytes @{d} ps bs >>= decodeFrom
207 | interface FromFormData a where
208 | fromFormData : FormData -> Either DecodeErr a
215 | Decode ByteString where decode = Right
218 | Decode String where decode = Right . toString
222 | {auto r : Decode a}
224 | -> (a -> Either String b)
226 | -> Either DecodeErr b
227 | refinedEither t f bs = Prelude.do
228 | v <- mapFst (setType t) $
decodeAs a bs
229 | mapFst (ReadErr t (toString bs)) (f v)
233 | {auto r : Decode a}
235 | -> (details : Lazy String)
238 | -> Either DecodeErr b
239 | refined t details f bs = Prelude.do
240 | v <- mapFst (setType t) $
decodeAs a bs
242 | Nothing => Left $
ReadErr t (toString bs) details