Common.elm 2.34 KB
Newer Older
1
2
module Common exposing
    ( classes
3
4
    , decodeJsonMessage
    , decodeResponse
5
6
7
8
9
    , expectJsonMessage
    , expectStringResponse
    , maybe
    , resultEither
    )
10

11
import Dict
12
13
import Html.Styled exposing (Attribute)
import Html.Styled.Attributes exposing (class)
14
import Http exposing (Response)
15
import Json.Decode as D
16
17
18
19
20


classes : List String -> Attribute msg
classes xs =
    class (String.join " " xs)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37


maybe : b -> (a -> b) -> Maybe a -> b
maybe b f =
    Maybe.map f >> Maybe.withDefault b


resultEither : (a -> c) -> (b -> c) -> Result a b -> c
resultEither mapErr mapOk result =
    case result of
        Err a ->
            mapErr a

        Ok b ->
            mapOk b


38
39
40
41
42
43
44
45
46
47
type alias ToMsg a msg =
    Result String a -> msg


type alias ReadError =
    String -> String


decodeResponse : ReadError -> D.Decoder a -> Response String -> Result String a
decodeResponse readErr decoder resp =
48
49
50
51
52
53
54
    let
        badStatus code body =
            "BadStatus "
                ++ String.fromInt code
                ++ " : "
                ++ readErr body
    in
55
56
57
    case resp of
        Http.BadUrl_ x ->
            Err <| "BadUrl : " ++ x
58

59
60
        Http.Timeout_ ->
            Err "Timeout"
61

62
63
        Http.NetworkError_ ->
            Err "NetworkError"
64

65
66
        Http.BadStatus_ metadata body ->
            Err <| badStatus metadata.statusCode body
67

68
69
70
        Http.GoodStatus_ _ body ->
            D.decodeString decoder body
                |> Result.mapError D.errorToString
71
72


73
74
readErrorMessage : ReadError
readErrorMessage =
75
    let
76
77
78
79
80
        dictToStr =
            Dict.toList
                >> List.map (\( k, v ) -> "(" ++ k ++ ", " ++ v ++ ")")
                >> String.join " "

81
82
        getMessage x =
            Dict.get "message" x
83
                |> Maybe.withDefault (dictToStr x)
84
    in
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    D.decodeString (D.dict D.string)
        >> Result.map getMessage
        >> resultEither D.errorToString identity


decodeJsonMessage : D.Decoder a -> Response String -> Result String a
decodeJsonMessage =
    decodeResponse readErrorMessage


expectStringResponse : ToMsg a msg -> ReadError -> D.Decoder a -> Http.Expect msg
expectStringResponse toMsg readErr decoder =
    Http.expectStringResponse toMsg (decodeResponse readErr decoder)


expectJsonMessage : ToMsg a msg -> D.Decoder a -> Http.Expect msg
expectJsonMessage toMsg =
    expectStringResponse toMsg readErrorMessage