elm-format

pull/17/head
Bram 2024-03-29 11:52:12 +01:00
parent 3983ab0de2
commit db6573180b
8 changed files with 146 additions and 101 deletions

View File

@ -10,12 +10,14 @@
"Internal.Config.Log",
"Internal.Config.Phantom",
"Internal.Config.Text",
"Internal.Filter.Timeline",
"Internal.Tools.DecodeExtra",
"Internal.Tools.EncodeExtra",
"Internal.Tools.Hashdict",
"Internal.Tools.Iddict",
"Internal.Tools.Json",
"Internal.Tools.Mashdict",
"Internal.Tools.RationalOrder",
"Internal.Tools.Timestamp",
"Internal.Tools.VersionControl",
"Internal.Values.Context",
@ -27,7 +29,8 @@
"Internal.Values.Vault",
"Matrix",
"Matrix.Event",
"Matrix.Settings"
"Matrix.Settings",
"Types"
],
"elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": {

View File

@ -485,18 +485,16 @@ leakingValueFound leaking_value =
"Found leaking value : " ++ leaking_value
{-|
-}
{-| -}
logs : { keyIsNotAnInt : String -> String }
logs =
{ keyIsNotAnInt =
(\key ->
\key ->
String.concat
[ "Encountered a key `"
, key
, "` that cannot be converted to an Int"
]
)
}

View File

@ -161,52 +161,57 @@ and (Filter f1) (Filter f2) =
else
stdAnd
{-| Define how to encode and decode a Timeline Filter to and from a JSON value.
-}
coder : Json.Coder Filter
coder =
Json.object4
{ name = Text.docs.timelineFilter.name
, description = Text.docs.timelineFilter.description
, init =
(\a b c d ->
\a b c d ->
Filter
{ senders = a, sendersAllowOthers = b
, types = c, typesAllowOthers = d
{ senders = a
, sendersAllowOthers = b
, types = c
, typesAllowOthers = d
}
)
}
( Json.field.optional.withDefault
(Json.field.optional.withDefault
{ fieldName = "senders"
, toField = (\(Filter f) -> f.senders)
, toField = \(Filter f) -> f.senders
, description = Text.fields.timelineFilter.senders
, coder = Json.set Json.string
, default = ( Set.empty, [] )
, defaultToString = always "[]"
}
)
( Json.field.required
(Json.field.required
{ fieldName = "sendersAllowOthers"
, toField = (\(Filter f) -> f.sendersAllowOthers)
, toField = \(Filter f) -> f.sendersAllowOthers
, description = Text.fields.timelineFilter.sendersAllowOthers
, coder = Json.bool
}
)
( Json.field.optional.withDefault
(Json.field.optional.withDefault
{ fieldName = "types"
, toField = (\(Filter f) -> f.types)
, toField = \(Filter f) -> f.types
, description = Text.fields.timelineFilter.types
, coder = Json.set Json.string
, default = ( Set.empty, [] )
, defaultToString = always "[]"
}
)
( Json.field.required
(Json.field.required
{ fieldName = "typesAllowOthers"
, toField = (\(Filter f) -> f.typesAllowOthers)
, toField = \(Filter f) -> f.typesAllowOthers
, description = Text.fields.timelineFilter.typesAllowOthers
, coder = Json.bool
}
)
{-| Decode a Filter from a JSON value.
-}
decoder : Json.Decoder Filter

View File

@ -53,6 +53,7 @@ type Iddict a
, dict : Dict Int a
}
{-| Define how an Iddict can be encoded and decoded to and from a JSON value.
-}
coder : Json.Coder a -> Json.Coder (Iddict a)
@ -61,7 +62,7 @@ coder x =
{ name = Text.docs.iddict.name
, description = Text.docs.iddict.description
, init =
(\c d ->
\c d ->
Iddict
{ cursor =
Dict.keys d
@ -72,25 +73,25 @@ coder x =
|> max c
, dict = d
}
)
}
( Json.field.optional.withDefault
(Json.field.optional.withDefault
{ fieldName = "cursor"
, toField = (\(Iddict i) -> i.cursor)
, toField = \(Iddict i) -> i.cursor
, description = Text.fields.iddict.cursor
, coder = Json.int
, default = ( 0, [] )
, defaultToString = String.fromInt
}
)
( Json.field.required
(Json.field.required
{ fieldName = "dict"
, toField = (\(Iddict i) -> i.dict)
, toField = \(Iddict i) -> i.dict
, description = Text.fields.iddict.dict
, coder = Json.fastIntDict x
}
)
{-| Decode an id-dict from a JSON value.
-}
decoder : Json.Coder a -> Json.Decoder (Iddict a)

View File

@ -294,6 +294,7 @@ fastDict (Coder old) =
, docs = DocsDict old.docs
}
{-| Define a fast dict where the keys are integers, not strings.
-}
fastIntDict : Coder value -> Coder (FastDict.Dict Int value)
@ -308,8 +309,8 @@ fastIntDict (Coder old) =
( items
|> List.map (Tuple.mapSecond Tuple.first)
|> List.filterMap
(\(k, v) ->
Maybe.map (\a -> (a, v)) (String.toInt k)
(\( k, v ) ->
Maybe.map (\a -> ( a, v )) (String.toInt k)
)
|> FastDict.fromList
, List.concat
@ -335,6 +336,7 @@ fastIntDict (Coder old) =
, docs = DocsIntDict old.docs
}
{-| Create a new field using any of the three provided options.
For example, suppose we are creating a `Field String User` to represent the
@ -509,12 +511,13 @@ list (Coder old) =
, docs = DocsList old.docs
}
{-| 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) =
Coder
{ encoder = (\(h, t) -> E.list old.encoder (h :: t))
{ encoder = \( h, t ) -> E.list old.encoder (h :: t)
, decoder =
old.decoder
|> D.list
@ -524,9 +527,9 @@ listWithOne (Coder old) =
[] ->
D.fail "Expected at least one value in list"
( h, l1) :: t ->
( h, l1 ) :: t ->
D.succeed
( (h, List.map Tuple.first items)
( ( h, List.map Tuple.first items )
, List.concatMap Tuple.second t
|> List.append l1
)
@ -1170,6 +1173,7 @@ set (Coder data) =
, docs = DocsSet data.docs
}
{-| Define a slow dict from the `elm/core` library.
-}
slowDict : Coder value -> Coder (SlowDict.Dict String value)

View File

@ -2,7 +2,7 @@ module Internal.Values.Timeline exposing
( Batch, Timeline
, empty, singleton
, mostRecentEvents, mostRecentEventsFrom
, insert, addSync
, addSync, insert
, coder, encode, decoder
)
@ -67,11 +67,11 @@ events!
-}
import FastDict as Dict exposing (Dict)
import Internal.Config.Text as Text
import Internal.Filter.Timeline as Filter exposing (Filter)
import Internal.Tools.Hashdict as Hashdict exposing (Hashdict)
import Internal.Tools.Iddict as Iddict exposing (Iddict)
import Internal.Tools.Json as Json
import Internal.Config.Text as Text
import Recursion
import Recursion.Traverse
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
start of the timeline part that the user is allowed to view.
-}
type alias Batch =
{ events : List String
@ -167,22 +168,26 @@ type Timeline
type alias TokenValue =
String
{-| Add a new batch as a sync
-}
addSync : Batch -> Timeline -> Timeline
addSync batch timeline =
case insertBatch batch timeline of
( Timeline t, { start, end }) ->
( Timeline t, { start, end } ) ->
let
old : ITokenPTR
old = t.mostRecentBatch
old =
t.mostRecentBatch
in
case Timeline { t | mostRecentBatch = end } of
tl ->
if old == start then
tl
else
connectITokenToIToken old start tl
case Timeline { t | mostRecentBatch = end } of
tl ->
if old == start then
tl
else
connectITokenToIToken old start tl
{-| 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
, description = Text.docs.timeline.description
, init =
(\a b c d e ->
\a b c d e ->
Timeline
{ batches = a, events = b, filledBatches = c
, mostRecentBatch = d, tokens = e
{ batches = a
, events = b
, filledBatches = c
, mostRecentBatch = d
, tokens = e
}
)
}
( Json.field.required
(Json.field.required
{ fieldName = "batches"
, toField = (\(Timeline t) -> t.batches)
, toField = \(Timeline t) -> t.batches
, description = Text.fields.timeline.batches
, coder = Iddict.coder coderIBatch
}
)
( Json.field.required
(Json.field.required
{ fieldName = "events"
, toField = (\(Timeline t) -> t.events)
, toField = \(Timeline t) -> t.events
, description = Text.fields.timeline.events
, coder = Json.fastDict (Json.listWithOne coderIBatchPTR)
}
)
( Json.field.optional.withDefault
(Json.field.optional.withDefault
{ fieldName = "filledBatches"
, toField = (\(Timeline t) -> t.filledBatches)
, toField = \(Timeline t) -> t.filledBatches
, description = Text.fields.timeline.filledBatches
, coder = Json.int
, default = ( 0, [] )
, defaultToString = String.fromInt
}
)
( Json.field.required
(Json.field.required
{ fieldName = "mostRecentBatch"
, toField = (\(Timeline t) -> t.mostRecentBatch)
, toField = \(Timeline t) -> t.mostRecentBatch
, description = Text.fields.timeline.mostRecentBatch
, coder = coderITokenPTR
}
)
( Json.field.required
(Json.field.required
{ fieldName = "tokens"
, toField = (\(Timeline t) -> t.tokens)
, toField = \(Timeline t) -> t.tokens
, description = Text.fields.timeline.tokens
, coder = Hashdict.coder .name coderIToken
}
)
{-| Define how to encode and decode a IBatch to and from a JSON value.
-}
coderIBatch : Json.Coder IBatch
@ -246,28 +254,28 @@ coderIBatch =
, description = Text.docs.ibatch.description
, init = IBatch
}
( Json.field.required
(Json.field.required
{ fieldName = "events"
, toField = .events
, description = Text.fields.ibatch.events
, coder = Json.list Json.string
}
)
( Json.field.required
(Json.field.required
{ fieldName = "filter"
, toField = .filter
, description = Text.fields.ibatch.filter
, coder = Filter.coder
}
)
( Json.field.required
(Json.field.required
{ fieldName = "start"
, toField = .start
, description = Text.fields.ibatch.start
, coder = coderITokenPTR
}
)
( Json.field.required
(Json.field.required
{ fieldName = "end"
, toField = .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.
-}
coderIBatchPTR : Json.Coder IBatchPTR
@ -282,15 +291,18 @@ coderIBatchPTR =
Json.map
{ name = Text.docs.itoken.name
, description = Text.docs.itoken.description
, back = (\(IBatchPTR value) -> value)
, back = \(IBatchPTR value) -> value
, forth = IBatchPTR
}
coderIBatchPTRValue
{-| Define how to encode and decode a IBatchPTRValue to and from a JSON value.
-}
coderIBatchPTRValue : Json.Coder IBatchPTRValue
coderIBatchPTRValue = Json.int
coderIBatchPTRValue =
Json.int
{-| Define how to encode and decode a IToken to and from a JSON value.
-}
@ -301,14 +313,14 @@ coderIToken =
, description = Text.docs.itoken.description
, init = IToken
}
( Json.field.required
(Json.field.required
{ fieldName = "name"
, toField = .name
, description = Text.fields.itoken.name
, coder = coderTokenValue
}
)
( Json.field.optional.withDefault
(Json.field.optional.withDefault
{ fieldName = "starts"
, toField = .starts
, description = Text.fields.itoken.starts
@ -317,7 +329,7 @@ coderIToken =
, defaultToString = always "[]"
}
)
( Json.field.optional.withDefault
(Json.field.optional.withDefault
{ fieldName = "ends"
, toField = .ends
, description = Text.fields.itoken.ends
@ -326,7 +338,7 @@ coderIToken =
, defaultToString = always "[]"
}
)
( Json.field.optional.withDefault
(Json.field.optional.withDefault
{ fieldName = "inFrontOf"
, toField = .inFrontOf
, description = Text.fields.itoken.inFrontOf
@ -335,7 +347,7 @@ coderIToken =
, defaultToString = always "[]"
}
)
( Json.field.optional.withDefault
(Json.field.optional.withDefault
{ fieldName = "behind"
, toField = .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.
-}
coderITokenPTR : Json.Coder ITokenPTR
@ -354,34 +367,37 @@ coderITokenPTR =
{ name = Text.mappings.itokenPTR.name
, description = Text.mappings.itokenPTR.description
, back =
(\itokenptr ->
\itokenptr ->
case itokenptr of
ITokenPTR name ->
Just name
StartOfTimeline ->
Nothing
)
, forth =
(\value ->
\value ->
case value of
Just name ->
ITokenPTR name
Nothing ->
StartOfTimeline
)
}
{-| Define how to encode and decode a ITokenPTRValue to and from a JSON value.
-}
coderITokenPTRValue : Json.Coder ITokenPTRValue
coderITokenPTRValue = Json.string
coderITokenPTRValue =
Json.string
{-| Define how to encode and decode a TokenValue to and from a JSON value.
-}
coderTokenValue : Json.Coder TokenValue
coderTokenValue = Json.string
coderTokenValue =
Json.string
{-| Append a token at the end of a batch.
-}
@ -454,10 +470,13 @@ connectITokenToIToken pointer1 pointer2 (Timeline tl) =
( _, _ ) ->
Timeline tl
{-| Timeline JSON decoder that helps decode a Timeline from JSON.
-}
decoder : Json.Decoder Timeline
decoder = Json.decode coder
decoder =
Json.decode coder
{-| Create a new empty timeline.
-}
@ -471,10 +490,13 @@ empty =
, tokens = Hashdict.empty .name
}
{-| Directly encode a Timeline into a JSON value.
-}
encode : Json.Encoder Timeline
encode = Json.encode coder
encode =
Json.encode coder
{-| Get an IBatch from the Timeline.
-}
@ -608,6 +630,7 @@ mostRecentEvents : Filter -> Timeline -> List (List String)
mostRecentEvents filter (Timeline timeline) =
mostRecentFrom filter (Timeline timeline) timeline.mostRecentBatch
{-| Instead of finding the most recent events from the latest sync, users can
also find the most recent events given a token value.
-}

View File

@ -428,7 +428,7 @@ suite =
|> Filter.encode
|> E.encode 0
|> D.decodeString Filter.decoder
|> Expect.equal (Ok (filter, []))
|> Expect.equal (Ok ( filter, [] ))
)
]
]

View File

@ -3,11 +3,11 @@ module Test.Values.Timeline exposing (..)
import Expect
import Fuzz exposing (Fuzzer)
import Internal.Filter.Timeline as Filter exposing (Filter)
import Internal.Tools.Json as Json
import Internal.Values.Timeline as Timeline exposing (Batch, Timeline)
import Json.Decode as D
import Test exposing (..)
import Test.Filter.Timeline as TestFilter
import Internal.Tools.Json as Json
fuzzer : Fuzzer Timeline
@ -216,9 +216,11 @@ suite =
|> Timeline.mostRecentEventsFrom filter "token_4"
|> 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"
(\filter l1 (l2, l3) ->
(\filter l1 ( l2, l3 ) ->
Timeline.empty
|> Timeline.insert
{ events = l1
@ -243,7 +245,8 @@ suite =
)
]
, describe "JSON"
[ fuzz fuzzer "Encode + Decode gives same output"
[ fuzz fuzzer
"Encode + Decode gives same output"
(\timeline ->
timeline
|> Json.encode Timeline.coder
@ -254,7 +257,8 @@ suite =
)
]
, describe "Weird loops"
[ fuzz TestFilter.fuzzer "Weird loops stop looping"
[ fuzz TestFilter.fuzzer
"Weird loops stop looping"
(\filter ->
Timeline.empty
|> Timeline.insert
@ -283,7 +287,8 @@ suite =
)
]
, describe "Sync"
[ fuzz TestFilter.fuzzer "Sync fills gaps"
[ fuzz TestFilter.fuzzer
"Sync fills gaps"
(\filter ->
Timeline.empty
|> Timeline.addSync
@ -293,7 +298,7 @@ suite =
, end = "token_2"
}
|> Timeline.addSync
{ events = [ "f", "g", "h"]
{ events = [ "f", "g", "h" ]
, filter = filter
, start = Just "token_3"
, end = "token_4"
@ -305,9 +310,10 @@ suite =
, end = "token_3"
}
|> 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 ->
Timeline.empty
|> Timeline.addSync
@ -317,31 +323,36 @@ suite =
, end = "token_2"
}
|> Timeline.addSync
{ events = [ "f", "g", "h"]
{ events = [ "f", "g", "h" ]
, filter = filter
, start = Just "token_3"
, end = "token_4"
}
|> 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"
(\(start, end) timeline filter ->
, fuzz3 (Fuzz.pair Fuzz.string Fuzz.string)
fuzzer
TestFilter.fuzzer
"Getting /sync is the same as getting from the token"
(\( start, end ) timeline filter ->
let
t : Timeline
t = Timeline.addSync
{ events = [ "a", "b", "c" ]
, filter = filter
, start = Just start
, end = end
}
timeline
t =
Timeline.addSync
{ events = [ "a", "b", "c" ]
, filter = filter
, start = Just start
, end = end
}
timeline
in
Expect.equal
(Timeline.mostRecentEvents filter t)
(Timeline.mostRecentEventsFrom filter end t)
Expect.equal
(Timeline.mostRecentEvents filter t)
(Timeline.mostRecentEventsFrom filter end t)
)
, fuzz TestFilter.fuzzer "Weird loops stop looping"
, fuzz TestFilter.fuzzer
"Weird loops stop looping"
(\filter ->
Timeline.empty
|> Timeline.insert