Rename more stuff
This commit is contained in:
154
intro/part1/src/Data/Article.elm
Normal file
154
intro/part1/src/Data/Article.elm
Normal file
@@ -0,0 +1,154 @@
|
||||
module Data.Article
|
||||
exposing
|
||||
( Article
|
||||
, Body
|
||||
, Slug
|
||||
, Tag
|
||||
, bodyToHtml
|
||||
, bodyToMarkdownString
|
||||
, decoder
|
||||
, decoderWithBody
|
||||
, slugParser
|
||||
, slugToString
|
||||
, tagDecoder
|
||||
, tagToString
|
||||
)
|
||||
|
||||
import Data.Article.Author as Author exposing (Author)
|
||||
import Date exposing (Date)
|
||||
import Html exposing (Attribute, Html)
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
import Json.Decode.Extra
|
||||
import Json.Decode.Pipeline exposing (custom, decode, hardcoded, required)
|
||||
import Markdown
|
||||
import UrlParser
|
||||
|
||||
|
||||
{-| An article, optionally with an article body.
|
||||
|
||||
To see the difference between { body : body } and { body : Maybe Body },
|
||||
consider the difference between the "view individual article" page (which
|
||||
renders one article, including its body) and the "article feed" -
|
||||
which displays multiple articles, but without bodies.
|
||||
|
||||
This definition for `Article` means we can write:
|
||||
|
||||
viewArticle : Article Body -> Html msg
|
||||
viewFeed : List (Article ()) -> Html msg
|
||||
|
||||
This indicates that `viewArticle` requires an article _with a `body` present_,
|
||||
wereas `viewFeed` accepts articles with no bodies. (We could also have written
|
||||
it as `List (Article a)` to specify that feeds can accept either articles that
|
||||
have `body` present or not. Either work, given that feeds do not attempt to
|
||||
read the `body` field from articles.)
|
||||
|
||||
This is an important distinction, because in Request.Article, the `feed`
|
||||
function produces `List (Article ())` because the API does not return bodies.
|
||||
Those articles are useful to the feed, but not to the individual article view.
|
||||
|
||||
-}
|
||||
type alias Article a =
|
||||
{ description : String
|
||||
, slug : Slug
|
||||
, title : String
|
||||
, tags : List String
|
||||
, createdAt : Date
|
||||
, updatedAt : Date
|
||||
, favorited : Bool
|
||||
, favoritesCount : Int
|
||||
, author : Author
|
||||
, body : a
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- SERIALIZATION --
|
||||
|
||||
|
||||
decoder : Decoder (Article ())
|
||||
decoder =
|
||||
baseArticleDecoder
|
||||
|> hardcoded ()
|
||||
|
||||
|
||||
decoderWithBody : Decoder (Article Body)
|
||||
decoderWithBody =
|
||||
baseArticleDecoder
|
||||
|> required "body" bodyDecoder
|
||||
|
||||
|
||||
baseArticleDecoder : Decoder (a -> Article a)
|
||||
baseArticleDecoder =
|
||||
decode Article
|
||||
|> required "description" (Decode.map (Maybe.withDefault "") (Decode.nullable Decode.string))
|
||||
|> required "slug" (Decode.map Slug Decode.string)
|
||||
|> required "title" Decode.string
|
||||
|> required "tagList" (Decode.list Decode.string)
|
||||
|> required "createdAt" Json.Decode.Extra.date
|
||||
|> required "updatedAt" Json.Decode.Extra.date
|
||||
|> required "favorited" Decode.bool
|
||||
|> required "favoritesCount" Decode.int
|
||||
|> required "author" Author.decoder
|
||||
|
||||
|
||||
|
||||
-- IDENTIFIERS --
|
||||
|
||||
|
||||
type Slug
|
||||
= Slug String
|
||||
|
||||
|
||||
slugParser : UrlParser.Parser (Slug -> a) a
|
||||
slugParser =
|
||||
UrlParser.custom "SLUG" (Ok << Slug)
|
||||
|
||||
|
||||
slugToString : Slug -> String
|
||||
slugToString (Slug slug) =
|
||||
slug
|
||||
|
||||
|
||||
|
||||
-- TAGS --
|
||||
|
||||
|
||||
type Tag
|
||||
= Tag String
|
||||
|
||||
|
||||
tagToString : Tag -> String
|
||||
tagToString (Tag slug) =
|
||||
slug
|
||||
|
||||
|
||||
tagDecoder : Decoder Tag
|
||||
tagDecoder =
|
||||
Decode.map Tag Decode.string
|
||||
|
||||
|
||||
|
||||
-- BODY --
|
||||
|
||||
|
||||
type Body
|
||||
= Body Markdown
|
||||
|
||||
|
||||
type alias Markdown =
|
||||
String
|
||||
|
||||
|
||||
bodyToHtml : Body -> List (Attribute msg) -> Html msg
|
||||
bodyToHtml (Body markdown) attributes =
|
||||
Markdown.toHtml attributes markdown
|
||||
|
||||
|
||||
bodyToMarkdownString : Body -> String
|
||||
bodyToMarkdownString (Body markdown) =
|
||||
markdown
|
||||
|
||||
|
||||
bodyDecoder : Decoder Body
|
||||
bodyDecoder =
|
||||
Decode.map Body Decode.string
|
||||
Reference in New Issue
Block a user