elm-format
parent
3983ab0de2
commit
db6573180b
5
elm.json
5
elm.json
|
@ -10,12 +10,14 @@
|
||||||
"Internal.Config.Log",
|
"Internal.Config.Log",
|
||||||
"Internal.Config.Phantom",
|
"Internal.Config.Phantom",
|
||||||
"Internal.Config.Text",
|
"Internal.Config.Text",
|
||||||
|
"Internal.Filter.Timeline",
|
||||||
"Internal.Tools.DecodeExtra",
|
"Internal.Tools.DecodeExtra",
|
||||||
"Internal.Tools.EncodeExtra",
|
"Internal.Tools.EncodeExtra",
|
||||||
"Internal.Tools.Hashdict",
|
"Internal.Tools.Hashdict",
|
||||||
"Internal.Tools.Iddict",
|
"Internal.Tools.Iddict",
|
||||||
"Internal.Tools.Json",
|
"Internal.Tools.Json",
|
||||||
"Internal.Tools.Mashdict",
|
"Internal.Tools.Mashdict",
|
||||||
|
"Internal.Tools.RationalOrder",
|
||||||
"Internal.Tools.Timestamp",
|
"Internal.Tools.Timestamp",
|
||||||
"Internal.Tools.VersionControl",
|
"Internal.Tools.VersionControl",
|
||||||
"Internal.Values.Context",
|
"Internal.Values.Context",
|
||||||
|
@ -27,7 +29,8 @@
|
||||||
"Internal.Values.Vault",
|
"Internal.Values.Vault",
|
||||||
"Matrix",
|
"Matrix",
|
||||||
"Matrix.Event",
|
"Matrix.Event",
|
||||||
"Matrix.Settings"
|
"Matrix.Settings",
|
||||||
|
"Types"
|
||||||
],
|
],
|
||||||
"elm-version": "0.19.0 <= v < 0.20.0",
|
"elm-version": "0.19.0 <= v < 0.20.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -485,18 +485,16 @@ leakingValueFound leaking_value =
|
||||||
"Found leaking value : " ++ leaking_value
|
"Found leaking value : " ++ leaking_value
|
||||||
|
|
||||||
|
|
||||||
{-|
|
{-| -}
|
||||||
-}
|
|
||||||
logs : { keyIsNotAnInt : String -> String }
|
logs : { keyIsNotAnInt : String -> String }
|
||||||
logs =
|
logs =
|
||||||
{ keyIsNotAnInt =
|
{ keyIsNotAnInt =
|
||||||
(\key ->
|
\key ->
|
||||||
String.concat
|
String.concat
|
||||||
[ "Encountered a key `"
|
[ "Encountered a key `"
|
||||||
, key
|
, key
|
||||||
, "` that cannot be converted to an Int"
|
, "` that cannot be converted to an Int"
|
||||||
]
|
]
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -161,52 +161,57 @@ and (Filter f1) (Filter f2) =
|
||||||
else
|
else
|
||||||
stdAnd
|
stdAnd
|
||||||
|
|
||||||
|
|
||||||
|
{-| Define how to encode and decode a Timeline Filter to and from a JSON value.
|
||||||
|
-}
|
||||||
coder : Json.Coder Filter
|
coder : Json.Coder Filter
|
||||||
coder =
|
coder =
|
||||||
Json.object4
|
Json.object4
|
||||||
{ name = Text.docs.timelineFilter.name
|
{ name = Text.docs.timelineFilter.name
|
||||||
, description = Text.docs.timelineFilter.description
|
, description = Text.docs.timelineFilter.description
|
||||||
, init =
|
, init =
|
||||||
(\a b c d ->
|
\a b c d ->
|
||||||
Filter
|
Filter
|
||||||
{ senders = a, sendersAllowOthers = b
|
{ senders = a
|
||||||
, types = c, typesAllowOthers = d
|
, sendersAllowOthers = b
|
||||||
|
, types = c
|
||||||
|
, typesAllowOthers = d
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
( Json.field.optional.withDefault
|
(Json.field.optional.withDefault
|
||||||
{ fieldName = "senders"
|
{ fieldName = "senders"
|
||||||
, toField = (\(Filter f) -> f.senders)
|
, toField = \(Filter f) -> f.senders
|
||||||
, description = Text.fields.timelineFilter.senders
|
, description = Text.fields.timelineFilter.senders
|
||||||
, coder = Json.set Json.string
|
, coder = Json.set Json.string
|
||||||
, default = ( Set.empty, [] )
|
, default = ( Set.empty, [] )
|
||||||
, defaultToString = always "[]"
|
, defaultToString = always "[]"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "sendersAllowOthers"
|
{ fieldName = "sendersAllowOthers"
|
||||||
, toField = (\(Filter f) -> f.sendersAllowOthers)
|
, toField = \(Filter f) -> f.sendersAllowOthers
|
||||||
, description = Text.fields.timelineFilter.sendersAllowOthers
|
, description = Text.fields.timelineFilter.sendersAllowOthers
|
||||||
, coder = Json.bool
|
, coder = Json.bool
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.optional.withDefault
|
(Json.field.optional.withDefault
|
||||||
{ fieldName = "types"
|
{ fieldName = "types"
|
||||||
, toField = (\(Filter f) -> f.types)
|
, toField = \(Filter f) -> f.types
|
||||||
, description = Text.fields.timelineFilter.types
|
, description = Text.fields.timelineFilter.types
|
||||||
, coder = Json.set Json.string
|
, coder = Json.set Json.string
|
||||||
, default = ( Set.empty, [] )
|
, default = ( Set.empty, [] )
|
||||||
, defaultToString = always "[]"
|
, defaultToString = always "[]"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "typesAllowOthers"
|
{ fieldName = "typesAllowOthers"
|
||||||
, toField = (\(Filter f) -> f.typesAllowOthers)
|
, toField = \(Filter f) -> f.typesAllowOthers
|
||||||
, description = Text.fields.timelineFilter.typesAllowOthers
|
, description = Text.fields.timelineFilter.typesAllowOthers
|
||||||
, coder = Json.bool
|
, coder = Json.bool
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
{-| Decode a Filter from a JSON value.
|
{-| Decode a Filter from a JSON value.
|
||||||
-}
|
-}
|
||||||
decoder : Json.Decoder Filter
|
decoder : Json.Decoder Filter
|
||||||
|
|
|
@ -53,6 +53,7 @@ type Iddict a
|
||||||
, dict : Dict Int a
|
, dict : Dict Int a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{-| Define how an Iddict can be encoded and decoded to and from a JSON value.
|
{-| Define how an Iddict can be encoded and decoded to and from a JSON value.
|
||||||
-}
|
-}
|
||||||
coder : Json.Coder a -> Json.Coder (Iddict a)
|
coder : Json.Coder a -> Json.Coder (Iddict a)
|
||||||
|
@ -61,7 +62,7 @@ coder x =
|
||||||
{ name = Text.docs.iddict.name
|
{ name = Text.docs.iddict.name
|
||||||
, description = Text.docs.iddict.description
|
, description = Text.docs.iddict.description
|
||||||
, init =
|
, init =
|
||||||
(\c d ->
|
\c d ->
|
||||||
Iddict
|
Iddict
|
||||||
{ cursor =
|
{ cursor =
|
||||||
Dict.keys d
|
Dict.keys d
|
||||||
|
@ -72,25 +73,25 @@ coder x =
|
||||||
|> max c
|
|> max c
|
||||||
, dict = d
|
, dict = d
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
( Json.field.optional.withDefault
|
(Json.field.optional.withDefault
|
||||||
{ fieldName = "cursor"
|
{ fieldName = "cursor"
|
||||||
, toField = (\(Iddict i) -> i.cursor)
|
, toField = \(Iddict i) -> i.cursor
|
||||||
, description = Text.fields.iddict.cursor
|
, description = Text.fields.iddict.cursor
|
||||||
, coder = Json.int
|
, coder = Json.int
|
||||||
, default = ( 0, [] )
|
, default = ( 0, [] )
|
||||||
, defaultToString = String.fromInt
|
, defaultToString = String.fromInt
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "dict"
|
{ fieldName = "dict"
|
||||||
, toField = (\(Iddict i) -> i.dict)
|
, toField = \(Iddict i) -> i.dict
|
||||||
, description = Text.fields.iddict.dict
|
, description = Text.fields.iddict.dict
|
||||||
, coder = Json.fastIntDict x
|
, coder = Json.fastIntDict x
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
{-| Decode an id-dict from a JSON value.
|
{-| Decode an id-dict from a JSON value.
|
||||||
-}
|
-}
|
||||||
decoder : Json.Coder a -> Json.Decoder (Iddict a)
|
decoder : Json.Coder a -> Json.Decoder (Iddict a)
|
||||||
|
|
|
@ -294,6 +294,7 @@ fastDict (Coder old) =
|
||||||
, docs = DocsDict old.docs
|
, docs = DocsDict old.docs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{-| Define a fast dict where the keys are integers, not strings.
|
{-| Define a fast dict where the keys are integers, not strings.
|
||||||
-}
|
-}
|
||||||
fastIntDict : Coder value -> Coder (FastDict.Dict Int value)
|
fastIntDict : Coder value -> Coder (FastDict.Dict Int value)
|
||||||
|
@ -308,8 +309,8 @@ fastIntDict (Coder old) =
|
||||||
( items
|
( items
|
||||||
|> List.map (Tuple.mapSecond Tuple.first)
|
|> List.map (Tuple.mapSecond Tuple.first)
|
||||||
|> List.filterMap
|
|> List.filterMap
|
||||||
(\(k, v) ->
|
(\( k, v ) ->
|
||||||
Maybe.map (\a -> (a, v)) (String.toInt k)
|
Maybe.map (\a -> ( a, v )) (String.toInt k)
|
||||||
)
|
)
|
||||||
|> FastDict.fromList
|
|> FastDict.fromList
|
||||||
, List.concat
|
, List.concat
|
||||||
|
@ -320,7 +321,7 @@ fastIntDict (Coder old) =
|
||||||
case String.toInt k of
|
case String.toInt k of
|
||||||
Just _ ->
|
Just _ ->
|
||||||
True
|
True
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
False
|
False
|
||||||
)
|
)
|
||||||
|
@ -335,6 +336,7 @@ fastIntDict (Coder old) =
|
||||||
, docs = DocsIntDict old.docs
|
, docs = DocsIntDict old.docs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{-| Create a new field using any of the three provided options.
|
{-| Create a new field using any of the three provided options.
|
||||||
|
|
||||||
For example, suppose we are creating a `Field String User` to represent the
|
For example, suppose we are creating a `Field String User` to represent the
|
||||||
|
@ -509,12 +511,13 @@ list (Coder old) =
|
||||||
, docs = DocsList old.docs
|
, docs = DocsList old.docs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{-| Define a list that has at least one value
|
{-| Define a list that has at least one value
|
||||||
-}
|
-}
|
||||||
listWithOne : Coder a -> Coder (a, List a)
|
listWithOne : Coder a -> Coder ( a, List a )
|
||||||
listWithOne (Coder old) =
|
listWithOne (Coder old) =
|
||||||
Coder
|
Coder
|
||||||
{ encoder = (\(h, t) -> E.list old.encoder (h :: t))
|
{ encoder = \( h, t ) -> E.list old.encoder (h :: t)
|
||||||
, decoder =
|
, decoder =
|
||||||
old.decoder
|
old.decoder
|
||||||
|> D.list
|
|> D.list
|
||||||
|
@ -523,10 +526,10 @@ listWithOne (Coder old) =
|
||||||
case items of
|
case items of
|
||||||
[] ->
|
[] ->
|
||||||
D.fail "Expected at least one value in list"
|
D.fail "Expected at least one value in list"
|
||||||
|
|
||||||
( h, l1) :: t ->
|
( h, l1 ) :: t ->
|
||||||
D.succeed
|
D.succeed
|
||||||
( (h, List.map Tuple.first items)
|
( ( h, List.map Tuple.first items )
|
||||||
, List.concatMap Tuple.second t
|
, List.concatMap Tuple.second t
|
||||||
|> List.append l1
|
|> List.append l1
|
||||||
)
|
)
|
||||||
|
@ -1170,6 +1173,7 @@ set (Coder data) =
|
||||||
, docs = DocsSet data.docs
|
, docs = DocsSet data.docs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{-| Define a slow dict from the `elm/core` library.
|
{-| Define a slow dict from the `elm/core` library.
|
||||||
-}
|
-}
|
||||||
slowDict : Coder value -> Coder (SlowDict.Dict String value)
|
slowDict : Coder value -> Coder (SlowDict.Dict String value)
|
||||||
|
|
|
@ -2,7 +2,7 @@ module Internal.Values.Timeline exposing
|
||||||
( Batch, Timeline
|
( Batch, Timeline
|
||||||
, empty, singleton
|
, empty, singleton
|
||||||
, mostRecentEvents, mostRecentEventsFrom
|
, mostRecentEvents, mostRecentEventsFrom
|
||||||
, insert, addSync
|
, addSync, insert
|
||||||
, coder, encode, decoder
|
, coder, encode, decoder
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -67,11 +67,11 @@ events!
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import FastDict as Dict exposing (Dict)
|
import FastDict as Dict exposing (Dict)
|
||||||
|
import Internal.Config.Text as Text
|
||||||
import Internal.Filter.Timeline as Filter exposing (Filter)
|
import Internal.Filter.Timeline as Filter exposing (Filter)
|
||||||
import Internal.Tools.Hashdict as Hashdict exposing (Hashdict)
|
import Internal.Tools.Hashdict as Hashdict exposing (Hashdict)
|
||||||
import Internal.Tools.Iddict as Iddict exposing (Iddict)
|
import Internal.Tools.Iddict as Iddict exposing (Iddict)
|
||||||
import Internal.Tools.Json as Json
|
import Internal.Tools.Json as Json
|
||||||
import Internal.Config.Text as Text
|
|
||||||
import Recursion
|
import Recursion
|
||||||
import Recursion.Traverse
|
import Recursion.Traverse
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
@ -82,6 +82,7 @@ that require an insertion, generally require this data type.
|
||||||
|
|
||||||
If the `start` value is `Nothing`, it is either the start of the timeline or the
|
If the `start` value is `Nothing`, it is either the start of the timeline or the
|
||||||
start of the timeline part that the user is allowed to view.
|
start of the timeline part that the user is allowed to view.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
type alias Batch =
|
type alias Batch =
|
||||||
{ events : List String
|
{ events : List String
|
||||||
|
@ -167,22 +168,26 @@ type Timeline
|
||||||
type alias TokenValue =
|
type alias TokenValue =
|
||||||
String
|
String
|
||||||
|
|
||||||
|
|
||||||
{-| Add a new batch as a sync
|
{-| Add a new batch as a sync
|
||||||
-}
|
-}
|
||||||
addSync : Batch -> Timeline -> Timeline
|
addSync : Batch -> Timeline -> Timeline
|
||||||
addSync batch timeline =
|
addSync batch timeline =
|
||||||
case insertBatch batch timeline of
|
case insertBatch batch timeline of
|
||||||
( Timeline t, { start, end }) ->
|
( Timeline t, { start, end } ) ->
|
||||||
let
|
let
|
||||||
old : ITokenPTR
|
old : ITokenPTR
|
||||||
old = t.mostRecentBatch
|
old =
|
||||||
|
t.mostRecentBatch
|
||||||
in
|
in
|
||||||
case Timeline { t | mostRecentBatch = end } of
|
case Timeline { t | mostRecentBatch = end } of
|
||||||
tl ->
|
tl ->
|
||||||
if old == start then
|
if old == start then
|
||||||
tl
|
tl
|
||||||
else
|
|
||||||
connectITokenToIToken old start tl
|
else
|
||||||
|
connectITokenToIToken old start tl
|
||||||
|
|
||||||
|
|
||||||
{-| Define how a Timeline can be encoded and decoded to and from a JSON value.
|
{-| Define how a Timeline can be encoded and decoded to and from a JSON value.
|
||||||
-}
|
-}
|
||||||
|
@ -192,51 +197,54 @@ coder =
|
||||||
{ name = Text.docs.timeline.name
|
{ name = Text.docs.timeline.name
|
||||||
, description = Text.docs.timeline.description
|
, description = Text.docs.timeline.description
|
||||||
, init =
|
, init =
|
||||||
(\a b c d e ->
|
\a b c d e ->
|
||||||
Timeline
|
Timeline
|
||||||
{ batches = a, events = b, filledBatches = c
|
{ batches = a
|
||||||
, mostRecentBatch = d, tokens = e
|
, events = b
|
||||||
|
, filledBatches = c
|
||||||
|
, mostRecentBatch = d
|
||||||
|
, tokens = e
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "batches"
|
{ fieldName = "batches"
|
||||||
, toField = (\(Timeline t) -> t.batches)
|
, toField = \(Timeline t) -> t.batches
|
||||||
, description = Text.fields.timeline.batches
|
, description = Text.fields.timeline.batches
|
||||||
, coder = Iddict.coder coderIBatch
|
, coder = Iddict.coder coderIBatch
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "events"
|
{ fieldName = "events"
|
||||||
, toField = (\(Timeline t) -> t.events)
|
, toField = \(Timeline t) -> t.events
|
||||||
, description = Text.fields.timeline.events
|
, description = Text.fields.timeline.events
|
||||||
, coder = Json.fastDict (Json.listWithOne coderIBatchPTR)
|
, coder = Json.fastDict (Json.listWithOne coderIBatchPTR)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.optional.withDefault
|
(Json.field.optional.withDefault
|
||||||
{ fieldName = "filledBatches"
|
{ fieldName = "filledBatches"
|
||||||
, toField = (\(Timeline t) -> t.filledBatches)
|
, toField = \(Timeline t) -> t.filledBatches
|
||||||
, description = Text.fields.timeline.filledBatches
|
, description = Text.fields.timeline.filledBatches
|
||||||
, coder = Json.int
|
, coder = Json.int
|
||||||
, default = ( 0, [] )
|
, default = ( 0, [] )
|
||||||
, defaultToString = String.fromInt
|
, defaultToString = String.fromInt
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "mostRecentBatch"
|
{ fieldName = "mostRecentBatch"
|
||||||
, toField = (\(Timeline t) -> t.mostRecentBatch)
|
, toField = \(Timeline t) -> t.mostRecentBatch
|
||||||
, description = Text.fields.timeline.mostRecentBatch
|
, description = Text.fields.timeline.mostRecentBatch
|
||||||
, coder = coderITokenPTR
|
, coder = coderITokenPTR
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "tokens"
|
{ fieldName = "tokens"
|
||||||
, toField = (\(Timeline t) -> t.tokens)
|
, toField = \(Timeline t) -> t.tokens
|
||||||
, description = Text.fields.timeline.tokens
|
, description = Text.fields.timeline.tokens
|
||||||
, coder = Hashdict.coder .name coderIToken
|
, coder = Hashdict.coder .name coderIToken
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
{-| Define how to encode and decode a IBatch to and from a JSON value.
|
{-| Define how to encode and decode a IBatch to and from a JSON value.
|
||||||
-}
|
-}
|
||||||
coderIBatch : Json.Coder IBatch
|
coderIBatch : Json.Coder IBatch
|
||||||
|
@ -246,28 +254,28 @@ coderIBatch =
|
||||||
, description = Text.docs.ibatch.description
|
, description = Text.docs.ibatch.description
|
||||||
, init = IBatch
|
, init = IBatch
|
||||||
}
|
}
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "events"
|
{ fieldName = "events"
|
||||||
, toField = .events
|
, toField = .events
|
||||||
, description = Text.fields.ibatch.events
|
, description = Text.fields.ibatch.events
|
||||||
, coder = Json.list Json.string
|
, coder = Json.list Json.string
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "filter"
|
{ fieldName = "filter"
|
||||||
, toField = .filter
|
, toField = .filter
|
||||||
, description = Text.fields.ibatch.filter
|
, description = Text.fields.ibatch.filter
|
||||||
, coder = Filter.coder
|
, coder = Filter.coder
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "start"
|
{ fieldName = "start"
|
||||||
, toField = .start
|
, toField = .start
|
||||||
, description = Text.fields.ibatch.start
|
, description = Text.fields.ibatch.start
|
||||||
, coder = coderITokenPTR
|
, coder = coderITokenPTR
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "end"
|
{ fieldName = "end"
|
||||||
, toField = .end
|
, toField = .end
|
||||||
, description = Text.fields.ibatch.end
|
, description = Text.fields.ibatch.end
|
||||||
|
@ -275,6 +283,7 @@ coderIBatch =
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
{-| Define how to encode and decode a IBatchPTR to and from a JSON value.
|
{-| Define how to encode and decode a IBatchPTR to and from a JSON value.
|
||||||
-}
|
-}
|
||||||
coderIBatchPTR : Json.Coder IBatchPTR
|
coderIBatchPTR : Json.Coder IBatchPTR
|
||||||
|
@ -282,15 +291,18 @@ coderIBatchPTR =
|
||||||
Json.map
|
Json.map
|
||||||
{ name = Text.docs.itoken.name
|
{ name = Text.docs.itoken.name
|
||||||
, description = Text.docs.itoken.description
|
, description = Text.docs.itoken.description
|
||||||
, back = (\(IBatchPTR value) -> value)
|
, back = \(IBatchPTR value) -> value
|
||||||
, forth = IBatchPTR
|
, forth = IBatchPTR
|
||||||
}
|
}
|
||||||
coderIBatchPTRValue
|
coderIBatchPTRValue
|
||||||
|
|
||||||
|
|
||||||
{-| Define how to encode and decode a IBatchPTRValue to and from a JSON value.
|
{-| Define how to encode and decode a IBatchPTRValue to and from a JSON value.
|
||||||
-}
|
-}
|
||||||
coderIBatchPTRValue : Json.Coder IBatchPTRValue
|
coderIBatchPTRValue : Json.Coder IBatchPTRValue
|
||||||
coderIBatchPTRValue = Json.int
|
coderIBatchPTRValue =
|
||||||
|
Json.int
|
||||||
|
|
||||||
|
|
||||||
{-| Define how to encode and decode a IToken to and from a JSON value.
|
{-| Define how to encode and decode a IToken to and from a JSON value.
|
||||||
-}
|
-}
|
||||||
|
@ -301,14 +313,14 @@ coderIToken =
|
||||||
, description = Text.docs.itoken.description
|
, description = Text.docs.itoken.description
|
||||||
, init = IToken
|
, init = IToken
|
||||||
}
|
}
|
||||||
( Json.field.required
|
(Json.field.required
|
||||||
{ fieldName = "name"
|
{ fieldName = "name"
|
||||||
, toField = .name
|
, toField = .name
|
||||||
, description = Text.fields.itoken.name
|
, description = Text.fields.itoken.name
|
||||||
, coder = coderTokenValue
|
, coder = coderTokenValue
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.optional.withDefault
|
(Json.field.optional.withDefault
|
||||||
{ fieldName = "starts"
|
{ fieldName = "starts"
|
||||||
, toField = .starts
|
, toField = .starts
|
||||||
, description = Text.fields.itoken.starts
|
, description = Text.fields.itoken.starts
|
||||||
|
@ -317,7 +329,7 @@ coderIToken =
|
||||||
, defaultToString = always "[]"
|
, defaultToString = always "[]"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.optional.withDefault
|
(Json.field.optional.withDefault
|
||||||
{ fieldName = "ends"
|
{ fieldName = "ends"
|
||||||
, toField = .ends
|
, toField = .ends
|
||||||
, description = Text.fields.itoken.ends
|
, description = Text.fields.itoken.ends
|
||||||
|
@ -326,7 +338,7 @@ coderIToken =
|
||||||
, defaultToString = always "[]"
|
, defaultToString = always "[]"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.optional.withDefault
|
(Json.field.optional.withDefault
|
||||||
{ fieldName = "inFrontOf"
|
{ fieldName = "inFrontOf"
|
||||||
, toField = .inFrontOf
|
, toField = .inFrontOf
|
||||||
, description = Text.fields.itoken.inFrontOf
|
, description = Text.fields.itoken.inFrontOf
|
||||||
|
@ -335,7 +347,7 @@ coderIToken =
|
||||||
, defaultToString = always "[]"
|
, defaultToString = always "[]"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
( Json.field.optional.withDefault
|
(Json.field.optional.withDefault
|
||||||
{ fieldName = "behind"
|
{ fieldName = "behind"
|
||||||
, toField = .behind
|
, toField = .behind
|
||||||
, description = Text.fields.itoken.behind
|
, description = Text.fields.itoken.behind
|
||||||
|
@ -345,6 +357,7 @@ coderIToken =
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
{-| Define how to encode and decode a ITokenPTR to and from a JSON value.
|
{-| Define how to encode and decode a ITokenPTR to and from a JSON value.
|
||||||
-}
|
-}
|
||||||
coderITokenPTR : Json.Coder ITokenPTR
|
coderITokenPTR : Json.Coder ITokenPTR
|
||||||
|
@ -354,34 +367,37 @@ coderITokenPTR =
|
||||||
{ name = Text.mappings.itokenPTR.name
|
{ name = Text.mappings.itokenPTR.name
|
||||||
, description = Text.mappings.itokenPTR.description
|
, description = Text.mappings.itokenPTR.description
|
||||||
, back =
|
, back =
|
||||||
(\itokenptr ->
|
\itokenptr ->
|
||||||
case itokenptr of
|
case itokenptr of
|
||||||
ITokenPTR name ->
|
ITokenPTR name ->
|
||||||
Just name
|
Just name
|
||||||
|
|
||||||
StartOfTimeline ->
|
StartOfTimeline ->
|
||||||
Nothing
|
Nothing
|
||||||
)
|
|
||||||
, forth =
|
, forth =
|
||||||
(\value ->
|
\value ->
|
||||||
case value of
|
case value of
|
||||||
Just name ->
|
Just name ->
|
||||||
ITokenPTR name
|
ITokenPTR name
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
StartOfTimeline
|
StartOfTimeline
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{-| Define how to encode and decode a ITokenPTRValue to and from a JSON value.
|
{-| Define how to encode and decode a ITokenPTRValue to and from a JSON value.
|
||||||
-}
|
-}
|
||||||
coderITokenPTRValue : Json.Coder ITokenPTRValue
|
coderITokenPTRValue : Json.Coder ITokenPTRValue
|
||||||
coderITokenPTRValue = Json.string
|
coderITokenPTRValue =
|
||||||
|
Json.string
|
||||||
|
|
||||||
|
|
||||||
{-| Define how to encode and decode a TokenValue to and from a JSON value.
|
{-| Define how to encode and decode a TokenValue to and from a JSON value.
|
||||||
-}
|
-}
|
||||||
coderTokenValue : Json.Coder TokenValue
|
coderTokenValue : Json.Coder TokenValue
|
||||||
coderTokenValue = Json.string
|
coderTokenValue =
|
||||||
|
Json.string
|
||||||
|
|
||||||
|
|
||||||
{-| Append a token at the end of a batch.
|
{-| Append a token at the end of a batch.
|
||||||
-}
|
-}
|
||||||
|
@ -454,10 +470,13 @@ connectITokenToIToken pointer1 pointer2 (Timeline tl) =
|
||||||
( _, _ ) ->
|
( _, _ ) ->
|
||||||
Timeline tl
|
Timeline tl
|
||||||
|
|
||||||
|
|
||||||
{-| Timeline JSON decoder that helps decode a Timeline from JSON.
|
{-| Timeline JSON decoder that helps decode a Timeline from JSON.
|
||||||
-}
|
-}
|
||||||
decoder : Json.Decoder Timeline
|
decoder : Json.Decoder Timeline
|
||||||
decoder = Json.decode coder
|
decoder =
|
||||||
|
Json.decode coder
|
||||||
|
|
||||||
|
|
||||||
{-| Create a new empty timeline.
|
{-| Create a new empty timeline.
|
||||||
-}
|
-}
|
||||||
|
@ -471,10 +490,13 @@ empty =
|
||||||
, tokens = Hashdict.empty .name
|
, tokens = Hashdict.empty .name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{-| Directly encode a Timeline into a JSON value.
|
{-| Directly encode a Timeline into a JSON value.
|
||||||
-}
|
-}
|
||||||
encode : Json.Encoder Timeline
|
encode : Json.Encoder Timeline
|
||||||
encode = Json.encode coder
|
encode =
|
||||||
|
Json.encode coder
|
||||||
|
|
||||||
|
|
||||||
{-| Get an IBatch from the Timeline.
|
{-| Get an IBatch from the Timeline.
|
||||||
-}
|
-}
|
||||||
|
@ -608,6 +630,7 @@ mostRecentEvents : Filter -> Timeline -> List (List String)
|
||||||
mostRecentEvents filter (Timeline timeline) =
|
mostRecentEvents filter (Timeline timeline) =
|
||||||
mostRecentFrom filter (Timeline timeline) timeline.mostRecentBatch
|
mostRecentFrom filter (Timeline timeline) timeline.mostRecentBatch
|
||||||
|
|
||||||
|
|
||||||
{-| Instead of finding the most recent events from the latest sync, users can
|
{-| Instead of finding the most recent events from the latest sync, users can
|
||||||
also find the most recent events given a token value.
|
also find the most recent events given a token value.
|
||||||
-}
|
-}
|
||||||
|
|
|
@ -428,7 +428,7 @@ suite =
|
||||||
|> Filter.encode
|
|> Filter.encode
|
||||||
|> E.encode 0
|
|> E.encode 0
|
||||||
|> D.decodeString Filter.decoder
|
|> D.decodeString Filter.decoder
|
||||||
|> Expect.equal (Ok (filter, []))
|
|> Expect.equal (Ok ( filter, [] ))
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,11 +3,11 @@ module Test.Values.Timeline exposing (..)
|
||||||
import Expect
|
import Expect
|
||||||
import Fuzz exposing (Fuzzer)
|
import Fuzz exposing (Fuzzer)
|
||||||
import Internal.Filter.Timeline as Filter exposing (Filter)
|
import Internal.Filter.Timeline as Filter exposing (Filter)
|
||||||
|
import Internal.Tools.Json as Json
|
||||||
import Internal.Values.Timeline as Timeline exposing (Batch, Timeline)
|
import Internal.Values.Timeline as Timeline exposing (Batch, Timeline)
|
||||||
import Json.Decode as D
|
import Json.Decode as D
|
||||||
import Test exposing (..)
|
import Test exposing (..)
|
||||||
import Test.Filter.Timeline as TestFilter
|
import Test.Filter.Timeline as TestFilter
|
||||||
import Internal.Tools.Json as Json
|
|
||||||
|
|
||||||
|
|
||||||
fuzzer : Fuzzer Timeline
|
fuzzer : Fuzzer Timeline
|
||||||
|
@ -216,9 +216,11 @@ suite =
|
||||||
|> Timeline.mostRecentEventsFrom filter "token_4"
|
|> Timeline.mostRecentEventsFrom filter "token_4"
|
||||||
|> Expect.equal [ [ "d", "e", "f" ] ]
|
|> Expect.equal [ [ "d", "e", "f" ] ]
|
||||||
)
|
)
|
||||||
, fuzz3 TestFilter.fuzzer (Fuzz.list Fuzz.string) (Fuzz.pair (Fuzz.list Fuzz.string) (Fuzz.list Fuzz.string))
|
, fuzz3 TestFilter.fuzzer
|
||||||
|
(Fuzz.list Fuzz.string)
|
||||||
|
(Fuzz.pair (Fuzz.list Fuzz.string) (Fuzz.list Fuzz.string))
|
||||||
"Gaps can be bridged"
|
"Gaps can be bridged"
|
||||||
(\filter l1 (l2, l3) ->
|
(\filter l1 ( l2, l3 ) ->
|
||||||
Timeline.empty
|
Timeline.empty
|
||||||
|> Timeline.insert
|
|> Timeline.insert
|
||||||
{ events = l1
|
{ events = l1
|
||||||
|
@ -243,7 +245,8 @@ suite =
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
, describe "JSON"
|
, describe "JSON"
|
||||||
[ fuzz fuzzer "Encode + Decode gives same output"
|
[ fuzz fuzzer
|
||||||
|
"Encode + Decode gives same output"
|
||||||
(\timeline ->
|
(\timeline ->
|
||||||
timeline
|
timeline
|
||||||
|> Json.encode Timeline.coder
|
|> Json.encode Timeline.coder
|
||||||
|
@ -254,7 +257,8 @@ suite =
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
, describe "Weird loops"
|
, describe "Weird loops"
|
||||||
[ fuzz TestFilter.fuzzer "Weird loops stop looping"
|
[ fuzz TestFilter.fuzzer
|
||||||
|
"Weird loops stop looping"
|
||||||
(\filter ->
|
(\filter ->
|
||||||
Timeline.empty
|
Timeline.empty
|
||||||
|> Timeline.insert
|
|> Timeline.insert
|
||||||
|
@ -283,7 +287,8 @@ suite =
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
, describe "Sync"
|
, describe "Sync"
|
||||||
[ fuzz TestFilter.fuzzer "Sync fills gaps"
|
[ fuzz TestFilter.fuzzer
|
||||||
|
"Sync fills gaps"
|
||||||
(\filter ->
|
(\filter ->
|
||||||
Timeline.empty
|
Timeline.empty
|
||||||
|> Timeline.addSync
|
|> Timeline.addSync
|
||||||
|
@ -293,7 +298,7 @@ suite =
|
||||||
, end = "token_2"
|
, end = "token_2"
|
||||||
}
|
}
|
||||||
|> Timeline.addSync
|
|> Timeline.addSync
|
||||||
{ events = [ "f", "g", "h"]
|
{ events = [ "f", "g", "h" ]
|
||||||
, filter = filter
|
, filter = filter
|
||||||
, start = Just "token_3"
|
, start = Just "token_3"
|
||||||
, end = "token_4"
|
, end = "token_4"
|
||||||
|
@ -305,9 +310,10 @@ suite =
|
||||||
, end = "token_3"
|
, end = "token_3"
|
||||||
}
|
}
|
||||||
|> Timeline.mostRecentEvents filter
|
|> Timeline.mostRecentEvents filter
|
||||||
|> Expect.equal [ [ "a", "b", "c", "d", "e", "f", "g", "h" ]]
|
|> Expect.equal [ [ "a", "b", "c", "d", "e", "f", "g", "h" ] ]
|
||||||
)
|
)
|
||||||
, fuzz TestFilter.fuzzer "Sync doesn't fill open gaps"
|
, fuzz TestFilter.fuzzer
|
||||||
|
"Sync doesn't fill open gaps"
|
||||||
(\filter ->
|
(\filter ->
|
||||||
Timeline.empty
|
Timeline.empty
|
||||||
|> Timeline.addSync
|
|> Timeline.addSync
|
||||||
|
@ -317,31 +323,36 @@ suite =
|
||||||
, end = "token_2"
|
, end = "token_2"
|
||||||
}
|
}
|
||||||
|> Timeline.addSync
|
|> Timeline.addSync
|
||||||
{ events = [ "f", "g", "h"]
|
{ events = [ "f", "g", "h" ]
|
||||||
, filter = filter
|
, filter = filter
|
||||||
, start = Just "token_3"
|
, start = Just "token_3"
|
||||||
, end = "token_4"
|
, end = "token_4"
|
||||||
}
|
}
|
||||||
|> Timeline.mostRecentEvents filter
|
|> Timeline.mostRecentEvents filter
|
||||||
|> Expect.equal [ [ "f", "g", "h" ]]
|
|> Expect.equal [ [ "f", "g", "h" ] ]
|
||||||
)
|
)
|
||||||
, fuzz3 (Fuzz.pair Fuzz.string Fuzz.string) fuzzer TestFilter.fuzzer "Getting /sync is the same as getting from the token"
|
, fuzz3 (Fuzz.pair Fuzz.string Fuzz.string)
|
||||||
(\(start, end) timeline filter ->
|
fuzzer
|
||||||
|
TestFilter.fuzzer
|
||||||
|
"Getting /sync is the same as getting from the token"
|
||||||
|
(\( start, end ) timeline filter ->
|
||||||
let
|
let
|
||||||
t : Timeline
|
t : Timeline
|
||||||
t = Timeline.addSync
|
t =
|
||||||
{ events = [ "a", "b", "c" ]
|
Timeline.addSync
|
||||||
, filter = filter
|
{ events = [ "a", "b", "c" ]
|
||||||
, start = Just start
|
, filter = filter
|
||||||
, end = end
|
, start = Just start
|
||||||
}
|
, end = end
|
||||||
timeline
|
}
|
||||||
|
timeline
|
||||||
in
|
in
|
||||||
Expect.equal
|
Expect.equal
|
||||||
(Timeline.mostRecentEvents filter t)
|
(Timeline.mostRecentEvents filter t)
|
||||||
(Timeline.mostRecentEventsFrom filter end t)
|
(Timeline.mostRecentEventsFrom filter end t)
|
||||||
)
|
)
|
||||||
, fuzz TestFilter.fuzzer "Weird loops stop looping"
|
, fuzz TestFilter.fuzzer
|
||||||
|
"Weird loops stop looping"
|
||||||
(\filter ->
|
(\filter ->
|
||||||
Timeline.empty
|
Timeline.empty
|
||||||
|> Timeline.insert
|
|> Timeline.insert
|
||||||
|
|
Loading…
Reference in New Issue