Skip to content
This repository has been archived by the owner on Oct 28, 2019. It is now read-only.

Commit

Permalink
Add more defaults, add Data.Status
Browse files Browse the repository at this point in the history
  • Loading branch information
rl-king committed Jun 4, 2019
1 parent 661fc4b commit 7d91b35
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 22 deletions.
167 changes: 167 additions & 0 deletions src/Data/Status.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
module Data.Status exposing
( Status(..)
, cons
, fromResult
, map
, map2
, map3
, mapError
, sequence
, traverse
, withDefault
)

-- STATUS


type Status err result
= NotAsked
| Failure err (List err)
| Loading
| Success result



-- MAP ERROR


mapError : (x -> y) -> Status x a -> Status y a
mapError func status =
case status of
NotAsked ->
NotAsked

Failure err errors ->
Failure (func err) (List.map func errors)

Loading ->
Loading

Success a ->
Success a



-- MAPPING


map : (a -> b) -> Status x a -> Status x b
map func status =
case status of
NotAsked ->
NotAsked

Failure err errors ->
Failure err errors

Loading ->
Loading

Success a ->
Success (func a)


map2 : (a -> b -> result) -> Status x a -> Status x b -> Status x result
map2 func aStatus bStatus =
case ( aStatus, bStatus ) of
( Success a, Success b ) ->
Success (func a b)

_ ->
case toErrors aStatus ++ toErrors bStatus of
[] ->
Loading

err :: errors ->
Failure err errors


map3 : (a -> b -> c -> result) -> Status x a -> Status x b -> Status x c -> Status x result
map3 func aStatus bStatus cStatus =
case ( aStatus, bStatus, cStatus ) of
( Success a, Success b, Success c ) ->
Success (func a b c)

_ ->
case toErrors aStatus ++ toErrors bStatus ++ toErrors cStatus of
[] ->
Loading

err :: errors ->
Failure err errors



-- CONS


cons : Status a b -> Status a (List b) -> Status a (List b)
cons aStatus bStatus =
case ( aStatus, bStatus ) of
( Success a, Success b ) ->
Success (a :: b)

( Failure _ _, Success b ) ->
Success b

_ ->
case toErrors aStatus ++ toErrors bStatus of
[] ->
Loading

err :: errors ->
Failure err errors


toErrors : Status x a -> List x
toErrors status =
case status of
NotAsked ->
[]

Failure e es ->
e :: es

Loading ->
[]

Success _ ->
[]


traverse : (a -> Status err b) -> List a -> Status err (List b)
traverse func list =
sequence (List.map func list)


sequence : List (Status err a) -> Status err (List a)
sequence status =
List.foldr (map2 (::)) (Success []) status



-- FROM RESULT


fromResult : Result err a -> Status err a
fromResult result =
case result of
Ok x ->
Success x

Err err ->
Failure err []



-- UNWRAP


withDefault : a -> Status err a -> a
withDefault default status =
case status of
Success s ->
s

_ ->
default
23 changes: 16 additions & 7 deletions src/Main.elm
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ type Page

init : flags -> Url -> Navigation.Key -> ( Model, Cmd Msg )
init _ url key =
onNavigation
{ route = Route.fromUrl url
, page = Loading
, key = key
}
Debug.log "init" <|
onNavigation
{ route = Route.fromUrl url
, page = Loading
, key = key
}



Expand Down Expand Up @@ -104,16 +105,24 @@ mapPage model toPage toMsg ( page, cmds ) =
)


{-| Map a Route (a parsed url) to a Page and initialize the modules Model.
This is the place you fetch data to render the page.
-}
onNavigation : Model -> ( Model, Cmd Msg )
onNavigation model =
case model.route of
Route.Root ->
mapPage model Home HomeMsg <|
Page.Home.init

Route.Article _ ->
Route.Article (Just id) ->
mapPage model Article ArticleMsg <|
Page.Article.init
Page.Article.init id

Route.Article Nothing ->
( model, Cmd.none )

Route.NotFound ->
( model, Cmd.none )
Expand Down
41 changes: 32 additions & 9 deletions src/Page/Article.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,44 @@ module Page.Article exposing
, view
)

import Data.Id as Id exposing (Id)
import Data.Status as Status exposing (Status)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http



-- MODEL


type alias Model =
()
{ data : Status Http.Error String }


init : ( Model, Cmd Msg )
init =
( (), Cmd.none )
init : Id Id.Article -> ( Model, Cmd Msg )
init articleId =
( { data = Status.NotAsked }
, Cmd.none
)



-- UPDATE


type Msg
= NoOp
= GotData (Result Http.Error String)


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
GotData data ->
( { model | data = Status.fromResult data }
, Cmd.none
)



Expand All @@ -47,7 +54,23 @@ view : Model -> { title : String, page : List (Html Msg) }
view model =
{ title = "Article"
, page =
[ header [] [ h1 [] [ text "Article page" ] ]
, main_ [] []
[ header [] [ h1 [] [ text "Article" ] ]
, main_ [] (viewPage model)
]
}


viewPage : Model -> List (Html Msg)
viewPage model =
case model.data of
Status.NotAsked ->
[ text "not asked" ]

Status.Loading ->
[ text "loading" ]

Status.Failure err _ ->
[ text "error" ]

Status.Success data ->
[ text data ]
34 changes: 28 additions & 6 deletions src/Page/Home.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,43 @@ module Page.Home exposing
, view
)

import Data.Status as Status exposing (Status)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http



-- MODEL


type alias Model =
()
{ data : Status Http.Error String }


init : ( Model, Cmd Msg )
init =
( (), Cmd.none )
( { data = Status.NotAsked }
, Cmd.none
)



-- UPDATE


type Msg
= NoOp
= GotData (Result Http.Error String)


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
GotData data ->
( { model | data = Status.fromResult data }
, Cmd.none
)



Expand All @@ -48,6 +54,22 @@ view model =
{ title = "Home"
, page =
[ header [] [ h1 [] [ text "Homepage" ] ]
, main_ [] []
, main_ [] (viewPage model)
]
}


viewPage : Model -> List (Html Msg)
viewPage model =
case model.data of
Status.NotAsked ->
[ text "not asked" ]

Status.Loading ->
[ text "loading" ]

Status.Failure err _ ->
[ text "error" ]

Status.Success data ->
[ text data ]

0 comments on commit 7d91b35

Please sign in to comment.