Compare commits

..

No commits in common. "acd13ac67a7f06f0d7c8097d6a03969d411dc388" and "d1fbc87730b2143bbd9f34db938c808d5f4438e0" have entirely different histories.

12 changed files with 106 additions and 266 deletions

View File

@ -112,30 +112,14 @@ decodedDictSize from to =
{-| Documentation used for all functions and data types in JSON coders
-}
docs :
{ context : TypeDocs
, envelope : TypeDocs
, event : TypeDocs
{ event : TypeDocs
, hashdict : TypeDocs
, mashdict : TypeDocs
, settings : TypeDocs
, stateManager : TypeDocs
, unsigned : TypeDocs
}
docs =
{ context =
{ name = "Context"
, description =
[ "The Context is the set of variables that the user (mostly) cannot control."
, "The Context contains tokens, values and other bits that the Vault receives from the Matrix API."
]
}
, envelope =
{ name = "Envelope"
, description =
[ "The Envelope module wraps existing data types with lots of values and settings that can be adjusted manually."
]
}
, event =
{ event =
{ name = "Event"
, description =
[ "The Event type represents a single value that contains all the information for a single event in the room."
@ -154,12 +138,6 @@ docs =
[ "The mashdict exclusively stores values for which the hashing algorithm returns a value, and it ignores the outcome for all other scenarios."
]
}
, settings =
{ name = "Settings"
, description =
[ "The settings type is a data type to configure settings in the enveloped data type."
]
}
, stateManager =
{ name = "StateManager"
, description =
@ -190,25 +168,12 @@ failures =
}
{-| Objects contain multiple fields. These fields are here described, explaining
what they do and what they are for.
-}
-- TODO
fields :
{ context :
{ accessToken : Desc
, baseUrl : Desc
, password : Desc
, refreshToken : Desc
, username : Desc
, transaction : Desc
, versions : Desc
}
, envelope :
{ content : Desc
, context : Desc
, settings : Desc
}
, event :
{ event :
{ content : Desc
, eventId : Desc
, originServerTs : Desc
@ -218,11 +183,6 @@ fields :
, eventType : Desc
, unsigned : Desc
}
, settings :
{ currentVersion : Desc
, deviceName : Desc
, syncTime : Desc
}
, unsigned :
{ age : Desc
, prevContent : Desc
@ -231,21 +191,7 @@ fields :
}
}
fields =
{ context =
{ accessToken = []
, baseUrl = []
, password = []
, refreshToken = []
, username = []
, transaction = []
, versions = []
}
, envelope =
{ content = []
, context = []
, settings = []
}
, event =
{ event =
{ content = []
, eventId = []
, originServerTs = []
@ -255,11 +201,6 @@ fields =
, eventType = []
, unsigned = []
}
, settings =
{ currentVersion = []
, deviceName = []
, syncTime = []
}
, unsigned =
{ age = []
, prevContent = []
@ -269,17 +210,11 @@ fields =
}
{-| This message will be shown when a [Hashdict](Internal-Tools-Hashdict)
encounters a hash-value pair where the value does not hash to the provided hash.
-}
invalidHashInHashdict : String
invalidHashInHashdict =
"Invalid hash function: not all elements hash to their JSON-stored hashes"
{-| This message will be shown when a [Mashdict](Internal-Tools-Mashdict)
encounters a hash-value pair where the value does not hash to the provided hash.
-}
invalidHashInMashdict : String
invalidHashInMashdict =
"Invalid hash function: not all elements hash to their JSON-stored hashes"

View File

@ -81,8 +81,6 @@ type Hashdict a
}
{-| Define how Hashdict can be encoded to and decoded from a JSON object.
-}
coder : (a -> String) -> Json.Coder a -> Json.Coder (Hashdict a)
coder f c1 =
Json.andThen

View File

@ -1,11 +1,12 @@
module Internal.Tools.Json exposing
( Coder, string, bool, int, float, value
, Encoder, encode, Decoder, decode, Value
, succeed, fail, andThen, lazy, map
, succeed, fail, andThen, lazy
, Docs(..), RequiredField(..), toDocs
, list, slowDict, fastDict, maybe
, Field, field
, object2, object3, object4, object5, object6, object7, object8, object9, object10, object11
, map
)
{-|
@ -39,7 +40,7 @@ module to build its encoders and decoders.
## Optional coding
@docs succeed, fail, andThen, lazy, map
@docs succeed, fail, andThen, lazy
## Documentation
@ -68,7 +69,7 @@ Once all fields are constructed, the user can create JSON objects.
import Dict as SlowDict
import FastDict
import Internal.Config.Log exposing (Log)
import Internal.Config.Log exposing (Log, log)
import Internal.Tools.DecodeExtra as D
import Internal.Tools.EncodeExtra as E
import Json.Decode as D
@ -175,8 +176,6 @@ type RequiredField
| OptionalFieldWithDefault String
{-| Represents an arbitary JavaScript value.
-}
type alias Value =
E.Value
@ -383,14 +382,7 @@ field =
{ fieldName = fieldName
, toField = toField
, description = description
, encoder =
\o ->
-- If the value matches the default, do not record
if o == Tuple.first default then
Nothing
else
Maybe.Just (encoder o)
, encoder = encoder >> Maybe.Just
, decoder = D.opFieldWithDefault fieldName default decoder
, docs = docs
, requiredness =
@ -425,8 +417,6 @@ int =
}
{-| Define a lazy coder. This is useful when defining recursive structures.
-}
lazy : (() -> Coder value) -> Coder value
lazy f =
Coder
@ -1147,9 +1137,6 @@ toEncodeField (Field data) =
( data.fieldName, data.toField >> data.encoder )
{-| Do not do anything useful with a JSON value, just bring it to Elm as a
JavaScript value.
-}
value : Coder Value
value =
Coder

View File

@ -93,8 +93,6 @@ type Mashdict a
}
{-| Define how a Mashdict can be encoded to and decoded from a JSON object.
-}
coder : (a -> Maybe String) -> Json.Coder a -> Json.Coder (Mashdict a)
coder f c1 =
Json.andThen

View File

@ -1,5 +1,5 @@
module Internal.Values.Context exposing
( Context, init, coder, encode, decoder
( Context, init, encode, decoder
, APIContext, apiFormat
, setAccessToken, getAccessToken
, setBaseUrl, getBaseUrl
@ -14,7 +14,7 @@ the Matrix API.
## Context
@docs Context, init, coder, encode, decoder
@docs Context, init, encode, decoder
## APIContext
@ -50,8 +50,10 @@ information that can be inserted.
-}
import Internal.Config.Leaks as L
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Tools.DecodeExtra as D
import Internal.Tools.EncodeExtra as E
import Json.Decode as D
import Json.Encode as E
{-| The Context type stores all the information in the Vault. This data type is
@ -95,78 +97,33 @@ apiFormat context =
}
{-| Define how a Context can be encoded to and decoded from a JSON object.
-}
coder : Json.Coder Context
coder =
Json.object7
{ name = Text.docs.context.name
, description = Text.docs.context.description
, init = Context
}
(Json.field.optional.value
{ fieldName = "accessToken"
, toField = .accessToken
, description = Text.fields.context.accessToken
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "baseUrl"
, toField = .baseUrl
, description = Text.fields.context.baseUrl
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "password"
, toField = .password
, description = Text.fields.context.password
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "refreshToken"
, toField = .refreshToken
, description = Text.fields.context.refreshToken
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "username"
, toField = .username
, description = Text.fields.context.username
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "transaction"
, toField = .transaction
, description = Text.fields.context.transaction
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "versions"
, toField = .versions
, description = Text.fields.context.versions
, coder = Json.list Json.string
}
)
{-| Decode a Context type from a JSON value.
-}
decoder : Json.Decoder Context
decoder : D.Decoder Context
decoder =
Json.decode coder
D.map7 Context
(D.opField "accessToken" D.string)
(D.opField "baseUrl" D.string)
(D.opField "password" D.string)
(D.opField "refreshToken" D.string)
(D.opField "username" D.string)
(D.opField "transaction" D.string)
(D.opField "versions" (D.list D.string))
{-| Encode a Context type into a JSON value.
-}
encode : Json.Encoder Context
encode =
Json.encode coder
encode : Context -> E.Value
encode context =
E.maybeObject
[ ( "accessToken", Maybe.map E.string context.accessToken )
, ( "baseUrl", Maybe.map E.string context.baseUrl )
, ( "password", Maybe.map E.string context.password )
, ( "refreshToken", Maybe.map E.string context.refreshToken )
, ( "username", Maybe.map E.string context.username )
, ( "transaction", Maybe.map E.string context.transaction )
, ( "versions", Maybe.map (E.list E.string) context.versions )
]
{-| A basic, untouched version of the Context, containing no information.

View File

@ -4,7 +4,7 @@ module Internal.Values.Envelope exposing
, Settings, mapSettings, extractSettings
, mapContext
, getContent, extract
, coder, encode, decoder
, encode, decoder
)
{-| The Envelope module wraps existing data types with lots of values and
@ -38,14 +38,17 @@ settings that can be adjusted manually.
## JSON coders
@docs coder, encode, decoder
@docs encode, decoder
-}
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Config.Default as Default
import Internal.Tools.DecodeExtra as D
import Internal.Tools.EncodeExtra as E
import Internal.Values.Context as Context exposing (Context)
import Internal.Values.Settings as Settings
import Json.Decode as D
import Json.Encode as E
{-| There are lots of different data types in the Elm SDK, and many of them
@ -68,54 +71,28 @@ type alias Settings =
Settings.Settings
{-| Define how an Envelope can be encoded to and decoded from a JSON object.
-}
coder : Json.Coder a -> Json.Coder (Envelope a)
coder c1 =
Json.object3
{ name = Text.docs.envelope.name
, description = Text.docs.envelope.description
, init = Envelope
}
(Json.field.required
{ fieldName = "content"
, toField = .content
, description = Text.fields.envelope.content
, coder = c1
}
)
(Json.field.required
{ fieldName = "context"
, toField = .context
, description = Text.fields.envelope.context
, coder = Context.coder
}
)
(Json.field.optional.withDefault
{ fieldName = "settings"
, toField = .settings
, description = Text.fields.envelope.settings
, coder = Settings.coder
, default = Tuple.pair Settings.init []
, defaultToString = always "<Default settings>"
}
)
{-| Decode an enveloped type from a JSON value. The decoder also imports any
potential tokens, values and settings included in the JSON.
-}
decoder : Json.Coder a -> Json.Decoder (Envelope a)
decoder c1 =
Json.decode (coder c1)
decoder : D.Decoder a -> D.Decoder (Envelope a)
decoder xDecoder =
D.map3 Envelope
(D.field "content" xDecoder)
(D.field "context" Context.decoder)
(D.field "settings" Settings.decoder)
{-| Encode an enveloped type into a JSON value. The function encodes all
non-standard settings, tokens and values.
-}
encode : Json.Coder a -> Json.Encoder (Envelope a)
encode c1 =
Json.encode (coder c1)
encode : (a -> E.Value) -> Envelope a -> E.Value
encode encodeX data =
E.object
[ ( "content", encodeX data.content )
, ( "context", Context.encode data.context )
, ( "settings", Settings.encode data.settings )
, ( "version", E.string Default.currentVersion )
]
{-| Map a function, then get its content. This is useful for getting information

View File

@ -26,6 +26,7 @@ of a room.
-}
import Internal.Config.Default as Default
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Tools.Timestamp as Timestamp exposing (Timestamp)
@ -64,8 +65,6 @@ age event =
Maybe.andThen (\(UnsignedData data) -> data.age) event.unsigned
{-| Define how an Event can be encoded to and decoded from a JSON object.
-}
coder : Json.Coder Event
coder =
Json.object8

View File

@ -1,6 +1,6 @@
module Internal.Values.Settings exposing
( Settings, init
, coder, encode, decoder
, encode, decoder
)
{-|
@ -16,13 +16,15 @@ data types.
## JSON coders
@docs coder, encode, decoder
@docs encode, decoder
-}
import Internal.Config.Default as Default
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Tools.DecodeExtra as D
import Internal.Tools.EncodeExtra as E
import Json.Decode as D
import Json.Encode as E
{-| Custom settings that can be manipulated by the user. These serve as a
@ -39,56 +41,46 @@ type alias Settings =
}
{-| Define how a Settings type can be encoded to and decoded from a JSON object.
-}
coder : Json.Coder Settings
coder =
Json.object3
{ name = Text.docs.settings.name
, description = Text.docs.settings.description
, init = Settings
}
(Json.field.optional.withDefault
{ fieldName = "currentVersion"
, toField = .currentVersion
, description = Text.fields.settings.currentVersion
, coder = Json.string
, default = Tuple.pair Default.currentVersion []
, defaultToString = identity
}
)
(Json.field.optional.withDefault
{ fieldName = "deviceName"
, toField = .deviceName
, description = Text.fields.settings.deviceName
, coder = Json.string
, default = Tuple.pair Default.deviceName []
, defaultToString = identity
}
)
(Json.field.optional.withDefault
{ fieldName = "syncTime"
, toField = .syncTime
, description = Text.fields.settings.syncTime
, coder = Json.int
, default = Tuple.pair Default.syncTime []
, defaultToString = String.fromInt
}
)
{-| Decode settings from a JSON value.
-}
decoder : Json.Decoder Settings
decoder : D.Decoder Settings
decoder =
Json.decode coder
D.map3 Settings
(D.opFieldWithDefault "currentVersion" Default.currentVersion D.string)
(D.opFieldWithDefault "deviceName" Default.deviceName D.string)
(D.opFieldWithDefault "syncTime" Default.syncTime D.int)
{-| Encode the settings into a JSON value.
-}
encode : Json.Encoder Settings
encode =
Json.encode coder
encode : Settings -> E.Value
encode settings =
let
differentFrom : b -> b -> Maybe b
differentFrom defaultValue currentValue =
if currentValue == defaultValue then
Nothing
else
Just currentValue
in
E.maybeObject
[ ( "currentVersion"
, settings.currentVersion
|> differentFrom Default.currentVersion
|> Maybe.map E.string
)
, ( "deviceName"
, settings.deviceName
|> differentFrom Default.deviceName
|> Maybe.map E.string
)
, ( "syncTime"
, settings.syncTime
|> differentFrom Default.syncTime
|> Maybe.map E.int
)
]
{-| Create a new Settings module based on default values

View File

@ -93,8 +93,6 @@ cleanKey key (StateManager manager) =
|> StateManager
{-| Define how a StateManager can be encoded to and decoded from a JSON object.
-}
coder : Json.Coder StateManager
coder =
Event.coder

View File

@ -138,6 +138,6 @@ json =
context
|> Context.encode
|> D.decodeValue Context.decoder
|> Expect.equal (Ok ( context, [] ))
|> Expect.equal (Ok context)
)
]

View File

@ -3,7 +3,6 @@ module Test.Values.Envelope exposing (..)
import Expect
import Fuzz exposing (Fuzzer)
import Internal.Config.Default as Default
import Internal.Tools.Json as Json
import Internal.Values.Envelope as Envelope exposing (Envelope)
import Json.Decode as D
import Json.Encode as E
@ -57,10 +56,10 @@ suite =
"JSON encode -> JSON decode"
(\envelope indent ->
envelope
|> Envelope.encode Json.string
|> Envelope.encode E.string
|> E.encode indent
|> D.decodeString (Envelope.decoder Json.string)
|> Expect.equal (Ok ( envelope, [] ))
|> D.decodeString (Envelope.decoder D.string)
|> Expect.equal (Ok envelope)
)
]
]

View File

@ -61,7 +61,7 @@ suite =
, test "JSON decode {} is init"
("{}"
|> D.decodeString Settings.decoder
|> Expect.equal (Ok ( Settings.init, [] ))
|> Expect.equal (Ok Settings.init)
|> always
)
]
@ -74,7 +74,7 @@ suite =
|> Settings.encode
|> E.encode indent
|> D.decodeString Settings.decoder
|> Expect.equal (Ok ( settings, [] ))
|> Expect.equal (Ok settings)
)
]
]