Envelope refactor
Effectively, the Envelope type has been moved to the Types module, effectively keeping it separate from other data types.3-event
parent
3e54ea9cbe
commit
959642499b
|
@ -1,5 +1,5 @@
|
||||||
module Internal.Values.Envelope exposing
|
module Internal.Values.Envelope exposing
|
||||||
( Envelope(..), init
|
( Envelope, init
|
||||||
, map, mapMaybe, mapList
|
, map, mapMaybe, mapList
|
||||||
, Settings, mapSettings, extractSettings
|
, Settings, mapSettings, extractSettings
|
||||||
, mapContext
|
, mapContext
|
||||||
|
@ -46,6 +46,7 @@ import Internal.Config.Default as Default
|
||||||
import Internal.Tools.Decode as D
|
import Internal.Tools.Decode as D
|
||||||
import Internal.Tools.Encode as E
|
import Internal.Tools.Encode as E
|
||||||
import Internal.Values.Context as Context exposing (Context)
|
import Internal.Values.Context as Context exposing (Context)
|
||||||
|
import Internal.Values.Settings as Settings
|
||||||
import Json.Decode as D
|
import Json.Decode as D
|
||||||
import Json.Encode as E
|
import Json.Encode as E
|
||||||
|
|
||||||
|
@ -55,26 +56,19 @@ need the same values. The Envelope type wraps settings, tokens and values around
|
||||||
each data type so they can all enjoy those values without needing to explicitly
|
each data type so they can all enjoy those values without needing to explicitly
|
||||||
define them in their type.
|
define them in their type.
|
||||||
-}
|
-}
|
||||||
type Envelope a
|
type alias Envelope a =
|
||||||
= Envelope
|
{ content : a
|
||||||
{ content : a
|
, context : Context
|
||||||
, context : Context
|
, settings : Settings
|
||||||
, settings : Settings
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Custom settings that can be manipulated by the user. These serve as a
|
{-| Settings value from
|
||||||
configuration for how the Elm SDK should behave.
|
[Internal.Values.Settings](Internal-Values-Settings#Settings). Can be used to
|
||||||
|
manipulate the Matrix Vault.
|
||||||
Custom settings are always part of the Envelope, allowing all functions to
|
|
||||||
behave under the user's preferred settings.
|
|
||||||
|
|
||||||
-}
|
-}
|
||||||
type alias Settings =
|
type alias Settings =
|
||||||
{ currentVersion : String
|
Settings.Settings
|
||||||
, deviceName : String
|
|
||||||
, syncTime : Int
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Decode an enveloped type from a JSON value. The decoder also imports any
|
{-| Decode an enveloped type from a JSON value. The decoder also imports any
|
||||||
|
@ -82,67 +76,25 @@ potential tokens, values and settings included in the JSON.
|
||||||
-}
|
-}
|
||||||
decoder : D.Decoder a -> D.Decoder (Envelope a)
|
decoder : D.Decoder a -> D.Decoder (Envelope a)
|
||||||
decoder xDecoder =
|
decoder xDecoder =
|
||||||
D.map3 (\a b c -> Envelope { content = a, context = b, settings = c })
|
D.map3 Envelope
|
||||||
(D.field "content" xDecoder)
|
(D.field "content" xDecoder)
|
||||||
(D.field "context" Context.decoder)
|
(D.field "context" Context.decoder)
|
||||||
(D.field "settings" decoderSettings)
|
(D.field "settings" Settings.decoder)
|
||||||
|
|
||||||
|
|
||||||
{-| Decode settings from a JSON value.
|
|
||||||
-}
|
|
||||||
decoderSettings : D.Decoder Settings
|
|
||||||
decoderSettings =
|
|
||||||
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 an enveloped type into a JSON value. The function encodes all
|
{-| Encode an enveloped type into a JSON value. The function encodes all
|
||||||
non-standard settings, tokens and values.
|
non-standard settings, tokens and values.
|
||||||
-}
|
-}
|
||||||
encode : (a -> E.Value) -> Envelope a -> E.Value
|
encode : (a -> E.Value) -> Envelope a -> E.Value
|
||||||
encode encodeX (Envelope data) =
|
encode encodeX data =
|
||||||
E.object
|
E.object
|
||||||
[ ( "content", encodeX data.content )
|
[ ( "content", encodeX data.content )
|
||||||
, ( "context", Context.encode data.context )
|
, ( "context", Context.encode data.context )
|
||||||
, ( "settings", encodeSettings data.settings )
|
, ( "settings", Settings.encode data.settings )
|
||||||
, ( "version", E.string Default.currentVersion )
|
, ( "version", E.string Default.currentVersion )
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
{-| Encode the settings into a JSON value.
|
|
||||||
-}
|
|
||||||
encodeSettings : Settings -> E.Value
|
|
||||||
encodeSettings 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
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
{-| Map a function, then get its content. This is useful for getting information
|
{-| Map a function, then get its content. This is useful for getting information
|
||||||
from a data type inside an Envelope.
|
from a data type inside an Envelope.
|
||||||
|
|
||||||
|
@ -155,7 +107,7 @@ from a data type inside an Envelope.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
extract : (a -> b) -> Envelope a -> b
|
extract : (a -> b) -> Envelope a -> b
|
||||||
extract f (Envelope data) =
|
extract f data =
|
||||||
f data.content
|
f data.content
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,7 +117,7 @@ This can be helpful if you have a UI that displays custom settings to a user.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
extractSettings : (Settings -> b) -> Envelope a -> b
|
extractSettings : (Settings -> b) -> Envelope a -> b
|
||||||
extractSettings f (Envelope data) =
|
extractSettings f data =
|
||||||
f data.settings
|
f data.settings
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,15 +138,10 @@ from the [Internal.Config.Default](Internal-Config-Default) module.
|
||||||
-}
|
-}
|
||||||
init : a -> Envelope a
|
init : a -> Envelope a
|
||||||
init x =
|
init x =
|
||||||
Envelope
|
{ content = x
|
||||||
{ content = x
|
, context = Context.init
|
||||||
, context = Context.init
|
, settings = Settings.init
|
||||||
, settings =
|
}
|
||||||
{ currentVersion = Default.currentVersion
|
|
||||||
, deviceName = Default.deviceName
|
|
||||||
, syncTime = Default.syncTime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Map a function on the content of the Envelope.
|
{-| Map a function on the content of the Envelope.
|
||||||
|
@ -208,23 +155,18 @@ init x =
|
||||||
|
|
||||||
-}
|
-}
|
||||||
map : (a -> b) -> Envelope a -> Envelope b
|
map : (a -> b) -> Envelope a -> Envelope b
|
||||||
map f (Envelope data) =
|
map f data =
|
||||||
Envelope
|
{ content = f data.content
|
||||||
{ content = f data.content
|
, context = data.context
|
||||||
, context = data.context
|
, settings = data.settings
|
||||||
, settings = data.settings
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Update the Context in the Envelope.
|
{-| Update the Context in the Envelope.
|
||||||
-}
|
-}
|
||||||
mapContext : (Context -> Context) -> Envelope a -> Envelope a
|
mapContext : (Context -> Context) -> Envelope a -> Envelope a
|
||||||
mapContext f (Envelope data) =
|
mapContext f data =
|
||||||
Envelope
|
{ data | context = f data.context }
|
||||||
{ content = data.content
|
|
||||||
, context = f data.context
|
|
||||||
, settings = data.settings
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Map the contents of a function, where the result is wrapped in a `List`
|
{-| Map the contents of a function, where the result is wrapped in a `List`
|
||||||
|
@ -279,23 +221,19 @@ mapMaybe f =
|
||||||
|
|
||||||
-}
|
-}
|
||||||
mapSettings : (Settings -> Settings) -> Envelope a -> Envelope a
|
mapSettings : (Settings -> Settings) -> Envelope a -> Envelope a
|
||||||
mapSettings f (Envelope data) =
|
mapSettings f data =
|
||||||
Envelope
|
{ data | settings = f data.settings }
|
||||||
{ content = data.content
|
|
||||||
, context = data.context
|
|
||||||
, settings = f data.settings
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
toList : Envelope (List a) -> List (Envelope a)
|
toList : Envelope (List a) -> List (Envelope a)
|
||||||
toList (Envelope data) =
|
toList data =
|
||||||
List.map
|
List.map
|
||||||
(\content -> map (always content) (Envelope data))
|
(\content -> map (always content) data)
|
||||||
data.content
|
data.content
|
||||||
|
|
||||||
|
|
||||||
toMaybe : Envelope (Maybe a) -> Maybe (Envelope a)
|
toMaybe : Envelope (Maybe a) -> Maybe (Envelope a)
|
||||||
toMaybe (Envelope data) =
|
toMaybe data =
|
||||||
Maybe.map
|
Maybe.map
|
||||||
(\content -> map (always content) (Envelope data))
|
(\content -> map (always content) data)
|
||||||
data.content
|
data.content
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
module Internal.Values.Event exposing
|
module Internal.Values.Event exposing
|
||||||
( Event
|
( Event
|
||||||
, content, eventId, eventType, originServerTs, roomId, sender, stateKey
|
|
||||||
, UnsignedData(..), age, prevContent, redactedBecause, transactionId
|
, UnsignedData(..), age, prevContent, redactedBecause, transactionId
|
||||||
, encode, decoder
|
, encode, decoder
|
||||||
, IEvent
|
|
||||||
)
|
)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
@ -17,11 +15,6 @@ of a room.
|
||||||
@docs Event
|
@docs Event
|
||||||
|
|
||||||
|
|
||||||
## Get information
|
|
||||||
|
|
||||||
@docs content, eventId, eventType, originServerTs, roomId, sender, stateKey
|
|
||||||
|
|
||||||
|
|
||||||
## Unsigned data
|
## Unsigned data
|
||||||
|
|
||||||
@docs UnsignedData, age, prevContent, redactedBecause, transactionId
|
@docs UnsignedData, age, prevContent, redactedBecause, transactionId
|
||||||
|
@ -37,7 +30,6 @@ import Internal.Config.Default as Default
|
||||||
import Internal.Tools.Decode as D
|
import Internal.Tools.Decode as D
|
||||||
import Internal.Tools.Encode as E
|
import Internal.Tools.Encode as E
|
||||||
import Internal.Tools.Timestamp as Timestamp exposing (Timestamp)
|
import Internal.Tools.Timestamp as Timestamp exposing (Timestamp)
|
||||||
import Internal.Values.Envelope as Envelope
|
|
||||||
import Json.Decode as D
|
import Json.Decode as D
|
||||||
import Json.Encode as E
|
import Json.Encode as E
|
||||||
|
|
||||||
|
@ -45,10 +37,6 @@ import Json.Encode as E
|
||||||
{-| The Event type occurs everywhere on a user's timeline.
|
{-| The Event type occurs everywhere on a user's timeline.
|
||||||
-}
|
-}
|
||||||
type alias Event =
|
type alias Event =
|
||||||
Envelope.Envelope IEvent
|
|
||||||
|
|
||||||
|
|
||||||
type alias IEvent =
|
|
||||||
{ content : E.Value
|
{ content : E.Value
|
||||||
, eventId : String
|
, eventId : String
|
||||||
, originServerTs : Timestamp
|
, originServerTs : Timestamp
|
||||||
|
@ -67,7 +55,7 @@ type UnsignedData
|
||||||
= UnsignedData
|
= UnsignedData
|
||||||
{ age : Maybe Int
|
{ age : Maybe Int
|
||||||
, prevContent : Maybe E.Value
|
, prevContent : Maybe E.Value
|
||||||
, redactedBecause : Maybe IEvent
|
, redactedBecause : Maybe Event
|
||||||
, transactionId : Maybe String
|
, transactionId : Maybe String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,33 +63,13 @@ type UnsignedData
|
||||||
{-| Get the event's age, if at all provided by the homeserver.
|
{-| Get the event's age, if at all provided by the homeserver.
|
||||||
-}
|
-}
|
||||||
age : Event -> Maybe Int
|
age : Event -> Maybe Int
|
||||||
age envelope =
|
age event =
|
||||||
Envelope.extract
|
Maybe.andThen (\(UnsignedData data) -> data.age) event.unsigned
|
||||||
(\event ->
|
|
||||||
Maybe.andThen
|
|
||||||
(\(UnsignedData data) -> data.age)
|
|
||||||
event.unsigned
|
|
||||||
)
|
|
||||||
envelope
|
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the body of this event, as created by the user that sent it.
|
|
||||||
-}
|
|
||||||
content : Event -> E.Value
|
|
||||||
content =
|
|
||||||
Envelope.extract .content
|
|
||||||
|
|
||||||
|
|
||||||
{-| Decode an Event from a JSON value.
|
|
||||||
-}
|
|
||||||
decoder : D.Decoder Event
|
decoder : D.Decoder Event
|
||||||
decoder =
|
decoder =
|
||||||
Envelope.decoder decoderInternal
|
D.map8 Event
|
||||||
|
|
||||||
|
|
||||||
decoderInternal : D.Decoder IEvent
|
|
||||||
decoderInternal =
|
|
||||||
D.map8 IEvent
|
|
||||||
(D.field "content" D.value)
|
(D.field "content" D.value)
|
||||||
(D.field "eventId" D.string)
|
(D.field "eventId" D.string)
|
||||||
(D.field "originServerTs" Timestamp.decoder)
|
(D.field "originServerTs" Timestamp.decoder)
|
||||||
|
@ -119,19 +87,14 @@ decoderUnsignedData =
|
||||||
D.map4 (\a b c d -> UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d })
|
D.map4 (\a b c d -> UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d })
|
||||||
(D.opField "age" D.int)
|
(D.opField "age" D.int)
|
||||||
(D.opField "prevContent" D.value)
|
(D.opField "prevContent" D.value)
|
||||||
(D.opField "redactedBecause" (D.lazy (\_ -> decoderInternal)))
|
(D.opField "redactedBecause" (D.lazy (\_ -> decoder)))
|
||||||
(D.opField "transactionId" D.string)
|
(D.opField "transactionId" D.string)
|
||||||
|
|
||||||
|
|
||||||
{-| Encode an Event into a JSON value.
|
{-| Encode an Event into a JSON value.
|
||||||
-}
|
-}
|
||||||
encode : Event -> E.Value
|
encode : Event -> E.Value
|
||||||
encode =
|
encode event =
|
||||||
Envelope.encode encodeInternal
|
|
||||||
|
|
||||||
|
|
||||||
encodeInternal : IEvent -> E.Value
|
|
||||||
encodeInternal event =
|
|
||||||
E.maybeObject
|
E.maybeObject
|
||||||
[ ( "content", Just event.content )
|
[ ( "content", Just event.content )
|
||||||
, ( "eventId", Just <| E.string event.eventId )
|
, ( "eventId", Just <| E.string event.eventId )
|
||||||
|
@ -152,113 +115,31 @@ encodeUnsignedData (UnsignedData data) =
|
||||||
E.maybeObject
|
E.maybeObject
|
||||||
[ ( "age", Maybe.map E.int data.age )
|
[ ( "age", Maybe.map E.int data.age )
|
||||||
, ( "prevContent", data.prevContent )
|
, ( "prevContent", data.prevContent )
|
||||||
, ( "redactedBecause", Maybe.map encodeInternal data.redactedBecause )
|
, ( "redactedBecause", Maybe.map encode data.redactedBecause )
|
||||||
, ( "transactionId", Maybe.map E.string data.transactionId )
|
, ( "transactionId", Maybe.map E.string data.transactionId )
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the globally unique identifier for an event.
|
|
||||||
-}
|
|
||||||
eventId : Event -> String
|
|
||||||
eventId =
|
|
||||||
Envelope.extract .eventId
|
|
||||||
|
|
||||||
|
|
||||||
{-| To give a hint what the event's [content](#content) might look like, users
|
|
||||||
can use this eventType value to hint at how the JSON might be decoded.
|
|
||||||
|
|
||||||
Standard examples of event types are `m.room.message`, `m.room.member` and
|
|
||||||
`me.noordstar.game.chess.move`.
|
|
||||||
|
|
||||||
-}
|
|
||||||
eventType : Event -> String
|
|
||||||
eventType =
|
|
||||||
Envelope.extract .eventType
|
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the timestamp of at what time the event was originally received by
|
|
||||||
the original homeserver.
|
|
||||||
|
|
||||||
Generally, this timestamp offers a relatively accurate indicator of when a
|
|
||||||
message was sent. However, this number isn't completely reliable! The timestamp
|
|
||||||
can be far in the past due to long network lag, and a (malicious) homeserver can
|
|
||||||
spoof this number to make it seem like something was sent ridiculously far in
|
|
||||||
the past - or even in the future.
|
|
||||||
|
|
||||||
-}
|
|
||||||
originServerTs : Event -> Timestamp
|
|
||||||
originServerTs =
|
|
||||||
Envelope.extract .originServerTs
|
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the previous `content` value for this event. This field is only a
|
{-| Determine the previous `content` value for this event. This field is only a
|
||||||
`Just value` if the event is a state event, and the Matrix Vault has permission
|
`Just value` if the event is a state event, and the Matrix Vault has permission
|
||||||
to see the previous content.
|
to see the previous content.
|
||||||
-}
|
-}
|
||||||
prevContent : Event -> Maybe E.Value
|
prevContent : Event -> Maybe E.Value
|
||||||
prevContent envelope =
|
prevContent event =
|
||||||
Envelope.extract
|
Maybe.andThen (\(UnsignedData data) -> data.prevContent) event.unsigned
|
||||||
(\event ->
|
|
||||||
Maybe.andThen
|
|
||||||
(\(UnsignedData data) -> data.prevContent)
|
|
||||||
event.unsigned
|
|
||||||
)
|
|
||||||
envelope
|
|
||||||
|
|
||||||
|
|
||||||
{-| If the event has been redacted, the homeserver can display the event that
|
{-| If the event has been redacted, the homeserver can display the event that
|
||||||
redacted it here.
|
redacted it here.
|
||||||
-}
|
-}
|
||||||
redactedBecause : Event -> Maybe Event
|
redactedBecause : Event -> Maybe Event
|
||||||
redactedBecause =
|
redactedBecause event =
|
||||||
Envelope.mapMaybe
|
Maybe.andThen (\(UnsignedData data) -> data.redactedBecause) event.unsigned
|
||||||
(\event ->
|
|
||||||
Maybe.andThen
|
|
||||||
(\(UnsignedData data) -> data.redactedBecause)
|
|
||||||
event.unsigned
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Unique id assigned to the Matrix room. You can use this room id to reference
|
|
||||||
or look up rooms.
|
|
||||||
-}
|
|
||||||
roomId : Event -> String
|
|
||||||
roomId =
|
|
||||||
Envelope.extract .roomId
|
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the fully-qualified ID of the user who sent an event.
|
|
||||||
-}
|
|
||||||
sender : Event -> String
|
|
||||||
sender =
|
|
||||||
Envelope.extract .sender
|
|
||||||
|
|
||||||
|
|
||||||
{-| Determine an event's state key.
|
|
||||||
|
|
||||||
It is present if, and only if, the event is a _state_ event. The key makes the
|
|
||||||
piece of state unique in the room. Note that it is often `Just ""`. If it is not
|
|
||||||
present, its value is `Nothing`.
|
|
||||||
|
|
||||||
State keys starting with an `@` are reserved for referencing user IDs, such as
|
|
||||||
room members. With the exception of a few events, state events set with a given
|
|
||||||
user'd ID as the state key can only be set by that user.
|
|
||||||
|
|
||||||
-}
|
|
||||||
stateKey : Event -> Maybe String
|
|
||||||
stateKey =
|
|
||||||
Envelope.extract .stateKey
|
|
||||||
|
|
||||||
|
|
||||||
{-| If the user has sent this event to the homeserver, then the homeserver might
|
{-| If the user has sent this event to the homeserver, then the homeserver might
|
||||||
display the original transaction id used for the event.
|
display the original transaction id used for the event.
|
||||||
-}
|
-}
|
||||||
transactionId : Event -> Maybe String
|
transactionId : Event -> Maybe String
|
||||||
transactionId envelope =
|
transactionId event =
|
||||||
Envelope.extract
|
Maybe.andThen (\(UnsignedData data) -> data.transactionId) event.unsigned
|
||||||
(\event ->
|
|
||||||
Maybe.andThen
|
|
||||||
(\(UnsignedData data) -> data.transactionId)
|
|
||||||
event.unsigned
|
|
||||||
)
|
|
||||||
envelope
|
|
||||||
|
|
|
@ -11,5 +11,4 @@ import Internal.Values.Envelope as Envelope
|
||||||
|
|
||||||
{-| This is the Vault type.
|
{-| This is the Vault type.
|
||||||
-}
|
-}
|
||||||
type alias Vault =
|
type alias Vault = ()
|
||||||
Envelope.Envelope {}
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ information isn't always applicable, it doesn't always exist.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
|
import Internal.Values.Envelope as Envelope
|
||||||
import Internal.Values.Event as Internal
|
import Internal.Values.Event as Internal
|
||||||
import Json.Encode
|
import Json.Encode
|
||||||
import Time
|
import Time
|
||||||
|
@ -56,14 +57,14 @@ type alias Event =
|
||||||
-}
|
-}
|
||||||
content : Event -> Json.Encode.Value
|
content : Event -> Json.Encode.Value
|
||||||
content (Event event) =
|
content (Event event) =
|
||||||
Internal.content event
|
Envelope.extract .content event
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the globally unique identifier for an event.
|
{-| Determine the globally unique identifier for an event.
|
||||||
-}
|
-}
|
||||||
eventId : Event -> String
|
eventId : Event -> String
|
||||||
eventId (Event event) =
|
eventId (Event event) =
|
||||||
Internal.eventId event
|
Envelope.extract .eventId event
|
||||||
|
|
||||||
|
|
||||||
{-| To give a hint what the event's [content](#content) might look like, users
|
{-| To give a hint what the event's [content](#content) might look like, users
|
||||||
|
@ -75,7 +76,7 @@ Standard examples of event types are `m.room.message`, `m.room.member` and
|
||||||
-}
|
-}
|
||||||
eventType : Event -> String
|
eventType : Event -> String
|
||||||
eventType (Event event) =
|
eventType (Event event) =
|
||||||
Internal.eventType event
|
Envelope.extract .eventType event
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the timestamp of at what time the event was originally received by
|
{-| Determine the timestamp of at what time the event was originally received by
|
||||||
|
@ -90,7 +91,7 @@ the past - or even in the future.
|
||||||
-}
|
-}
|
||||||
originServerTs : Event -> Time.Posix
|
originServerTs : Event -> Time.Posix
|
||||||
originServerTs (Event event) =
|
originServerTs (Event event) =
|
||||||
Internal.originServerTs event
|
Envelope.extract .originServerTs event
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the previous `content` value for this event. This field is only a
|
{-| Determine the previous `content` value for this event. This field is only a
|
||||||
|
@ -99,7 +100,7 @@ to see the previous content.
|
||||||
-}
|
-}
|
||||||
previousContent : Event -> Maybe Json.Encode.Value
|
previousContent : Event -> Maybe Json.Encode.Value
|
||||||
previousContent (Event event) =
|
previousContent (Event event) =
|
||||||
Internal.prevContent event
|
Envelope.extract Internal.prevContent event
|
||||||
|
|
||||||
|
|
||||||
{-| If the event has been redacted, the homeserver can display the event that
|
{-| If the event has been redacted, the homeserver can display the event that
|
||||||
|
@ -107,7 +108,7 @@ redacted it here.
|
||||||
-}
|
-}
|
||||||
redactedBecause : Event -> Maybe Event
|
redactedBecause : Event -> Maybe Event
|
||||||
redactedBecause (Event event) =
|
redactedBecause (Event event) =
|
||||||
Internal.redactedBecause event
|
Envelope.mapMaybe Internal.redactedBecause event
|
||||||
|> Maybe.map Event
|
|> Maybe.map Event
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,14 +117,14 @@ or look up rooms.
|
||||||
-}
|
-}
|
||||||
roomId : Event -> String
|
roomId : Event -> String
|
||||||
roomId (Event event) =
|
roomId (Event event) =
|
||||||
Internal.roomId event
|
Envelope.extract .roomId event
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the fully-qualified ID of the user who sent an event.
|
{-| Determine the fully-qualified ID of the user who sent an event.
|
||||||
-}
|
-}
|
||||||
sender : Event -> String
|
sender : Event -> String
|
||||||
sender (Event event) =
|
sender (Event event) =
|
||||||
Internal.sender event
|
Envelope.extract .sender event
|
||||||
|
|
||||||
|
|
||||||
{-| Determine an event's state key.
|
{-| Determine an event's state key.
|
||||||
|
@ -139,4 +140,4 @@ user'd ID as the state key can only be set by that user.
|
||||||
-}
|
-}
|
||||||
stateKey : Event -> Maybe String
|
stateKey : Event -> Maybe String
|
||||||
stateKey (Event event) =
|
stateKey (Event event) =
|
||||||
Internal.stateKey event
|
Envelope.extract .stateKey event
|
||||||
|
|
|
@ -16,6 +16,7 @@ safely access all exposed data types without risking to create circular imports.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
|
import Internal.Values.Envelope as Envelope
|
||||||
import Internal.Values.Event as Event
|
import Internal.Values.Event as Event
|
||||||
import Internal.Values.Vault as Vault
|
import Internal.Values.Vault as Vault
|
||||||
|
|
||||||
|
@ -23,10 +24,10 @@ import Internal.Values.Vault as Vault
|
||||||
{-| Opaque type for Matrix Event
|
{-| Opaque type for Matrix Event
|
||||||
-}
|
-}
|
||||||
type Event
|
type Event
|
||||||
= Event Event.Event
|
= Event (Envelope.Envelope Event.Event)
|
||||||
|
|
||||||
|
|
||||||
{-| Opaque type for Matrix Vault
|
{-| Opaque type for Matrix Vault
|
||||||
-}
|
-}
|
||||||
type Vault
|
type Vault
|
||||||
= Vault Vault.Vault
|
= Vault (Envelope.Envelope Vault.Vault)
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
module Envelope exposing (..)
|
|
||||||
|
|
||||||
import Context as TestContext
|
|
||||||
import Fuzz exposing (Fuzzer)
|
|
||||||
import Internal.Config.Default as Default
|
|
||||||
import Internal.Values.Envelope exposing (Envelope(..), Settings)
|
|
||||||
import Test exposing (..)
|
|
||||||
|
|
||||||
|
|
||||||
fuzzer : Fuzzer a -> Fuzzer (Envelope a)
|
|
||||||
fuzzer fuzz =
|
|
||||||
Fuzz.map3
|
|
||||||
(\content context settings ->
|
|
||||||
Envelope
|
|
||||||
{ content = content
|
|
||||||
, context = context
|
|
||||||
, settings = settings
|
|
||||||
}
|
|
||||||
)
|
|
||||||
fuzz
|
|
||||||
TestContext.fuzzer
|
|
||||||
fuzzerSettings
|
|
||||||
|
|
||||||
|
|
||||||
fuzzerSettings : Fuzzer Settings
|
|
||||||
fuzzerSettings =
|
|
||||||
Fuzz.map3 Settings
|
|
||||||
(Fuzz.oneOf
|
|
||||||
[ Fuzz.constant Default.currentVersion
|
|
||||||
, Fuzz.string
|
|
||||||
]
|
|
||||||
)
|
|
||||||
(Fuzz.oneOf
|
|
||||||
[ Fuzz.constant Default.deviceName
|
|
||||||
, Fuzz.string
|
|
||||||
]
|
|
||||||
)
|
|
||||||
(Fuzz.oneOf
|
|
||||||
[ Fuzz.constant Default.syncTime
|
|
||||||
, Fuzz.int
|
|
||||||
]
|
|
||||||
)
|
|
|
@ -1,89 +0,0 @@
|
||||||
module Event exposing (..)
|
|
||||||
|
|
||||||
import Envelope as TestEnvelope
|
|
||||||
import Expect
|
|
||||||
import Fuzz exposing (Fuzzer)
|
|
||||||
import Iddict as TestIddict
|
|
||||||
import Internal.Tools.Iddict as Iddict
|
|
||||||
import Internal.Tools.Timestamp as Timestamp
|
|
||||||
import Internal.Values.Envelope as Envelope
|
|
||||||
import Internal.Values.Event as Event
|
|
||||||
import Json.Decode as D
|
|
||||||
import Json.Encode as E
|
|
||||||
import Test exposing (..)
|
|
||||||
import Timestamp as TestTimestamp
|
|
||||||
|
|
||||||
|
|
||||||
{-| Example values that can be used for arbitrary JSON values
|
|
||||||
-}
|
|
||||||
valueFuzzer : Fuzzer E.Value
|
|
||||||
valueFuzzer =
|
|
||||||
Fuzz.oneOf
|
|
||||||
[ Fuzz.map (Iddict.encode E.int) (TestIddict.fuzzer Fuzz.int)
|
|
||||||
, Fuzz.map Timestamp.encode TestTimestamp.fuzzer
|
|
||||||
, Fuzz.map E.int Fuzz.int
|
|
||||||
, Fuzz.map E.string Fuzz.string
|
|
||||||
, Fuzz.map (E.list E.int) (Fuzz.list Fuzz.int)
|
|
||||||
, Fuzz.map (E.list E.string) (Fuzz.list Fuzz.string)
|
|
||||||
, Fuzz.map Event.encode (Fuzz.lazy (\_ -> TestEnvelope.fuzzer fuzzer))
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
fuzzer : Fuzzer Event.IEvent
|
|
||||||
fuzzer =
|
|
||||||
Fuzz.map8
|
|
||||||
(\c ei et o r se sk u ->
|
|
||||||
{ content = c
|
|
||||||
, eventId = ei
|
|
||||||
, eventType = et
|
|
||||||
, originServerTs = o
|
|
||||||
, roomId = r
|
|
||||||
, sender = se
|
|
||||||
, stateKey = sk
|
|
||||||
, unsigned = u
|
|
||||||
}
|
|
||||||
)
|
|
||||||
valueFuzzer
|
|
||||||
Fuzz.string
|
|
||||||
Fuzz.string
|
|
||||||
TestTimestamp.fuzzer
|
|
||||||
Fuzz.string
|
|
||||||
Fuzz.string
|
|
||||||
(Fuzz.maybe Fuzz.string)
|
|
||||||
(Fuzz.maybe unsignedDataFuzzer)
|
|
||||||
|
|
||||||
|
|
||||||
fuzzerFull : Fuzzer Event.Event
|
|
||||||
fuzzerFull =
|
|
||||||
TestEnvelope.fuzzer fuzzer
|
|
||||||
|
|
||||||
|
|
||||||
unsignedDataFuzzer : Fuzzer Event.UnsignedData
|
|
||||||
unsignedDataFuzzer =
|
|
||||||
Fuzz.map4
|
|
||||||
(\age prev redact trans ->
|
|
||||||
Event.UnsignedData
|
|
||||||
{ age = age
|
|
||||||
, prevContent = prev
|
|
||||||
, redactedBecause = redact
|
|
||||||
, transactionId = trans
|
|
||||||
}
|
|
||||||
)
|
|
||||||
(Fuzz.maybe Fuzz.int)
|
|
||||||
(Fuzz.maybe valueFuzzer)
|
|
||||||
(Fuzz.maybe <| Fuzz.lazy (\_ -> fuzzer))
|
|
||||||
(Fuzz.maybe Fuzz.string)
|
|
||||||
|
|
||||||
|
|
||||||
json : Test
|
|
||||||
json =
|
|
||||||
describe "JSON tests"
|
|
||||||
[ fuzz fuzzerFull
|
|
||||||
"JSON encode + JSON decode"
|
|
||||||
(\event ->
|
|
||||||
event
|
|
||||||
|> Event.encode
|
|
||||||
|> D.decodeValue Event.decoder
|
|
||||||
|> Expect.equal (Ok event)
|
|
||||||
)
|
|
||||||
]
|
|
|
@ -1,4 +1,4 @@
|
||||||
module Timestamp exposing (..)
|
module Test.Tools.Timestamp exposing (..)
|
||||||
|
|
||||||
import Fuzz exposing (Fuzzer)
|
import Fuzz exposing (Fuzzer)
|
||||||
import Internal.Tools.Timestamp exposing (Timestamp)
|
import Internal.Tools.Timestamp exposing (Timestamp)
|
|
@ -1,4 +1,4 @@
|
||||||
module Context exposing (..)
|
module Test.Values.Context exposing (..)
|
||||||
|
|
||||||
import Expect
|
import Expect
|
||||||
import Fuzz exposing (Fuzzer)
|
import Fuzz exposing (Fuzzer)
|
|
@ -0,0 +1,65 @@
|
||||||
|
module Test.Values.Envelope exposing (..)
|
||||||
|
|
||||||
|
import Expect
|
||||||
|
import Fuzz exposing (Fuzzer)
|
||||||
|
import Internal.Config.Default as Default
|
||||||
|
import Internal.Values.Envelope as Envelope exposing (Envelope)
|
||||||
|
import Json.Decode as D
|
||||||
|
import Json.Encode as E
|
||||||
|
import Test exposing (..)
|
||||||
|
import Test.Values.Context as TestContext
|
||||||
|
import Test.Values.Settings as TestSettings
|
||||||
|
|
||||||
|
|
||||||
|
fuzzer : Fuzzer a -> Fuzzer (Envelope a)
|
||||||
|
fuzzer fuz =
|
||||||
|
Fuzz.map3 Envelope
|
||||||
|
fuz
|
||||||
|
TestContext.fuzzer
|
||||||
|
TestSettings.fuzzer
|
||||||
|
|
||||||
|
|
||||||
|
suite : Test
|
||||||
|
suite =
|
||||||
|
describe "Envelope value"
|
||||||
|
[ describe "init"
|
||||||
|
[ describe "Default settings"
|
||||||
|
[ fuzz Fuzz.string
|
||||||
|
"currentVersion"
|
||||||
|
(\s ->
|
||||||
|
s
|
||||||
|
|> Envelope.init
|
||||||
|
|> Envelope.extractSettings .currentVersion
|
||||||
|
|> Expect.equal Default.currentVersion
|
||||||
|
)
|
||||||
|
, fuzz Fuzz.string
|
||||||
|
"deviceName"
|
||||||
|
(\s ->
|
||||||
|
s
|
||||||
|
|> Envelope.init
|
||||||
|
|> Envelope.extractSettings .deviceName
|
||||||
|
|> Expect.equal Default.deviceName
|
||||||
|
)
|
||||||
|
, fuzz Fuzz.string
|
||||||
|
"syncTime"
|
||||||
|
(\s ->
|
||||||
|
s
|
||||||
|
|> Envelope.init
|
||||||
|
|> Envelope.extractSettings .syncTime
|
||||||
|
|> Expect.equal Default.syncTime
|
||||||
|
)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, describe "JSON"
|
||||||
|
[ fuzz2 (fuzzer Fuzz.string)
|
||||||
|
Fuzz.int
|
||||||
|
"JSON encode -> JSON decode"
|
||||||
|
(\envelope indent ->
|
||||||
|
envelope
|
||||||
|
|> Envelope.encode E.string
|
||||||
|
|> E.encode indent
|
||||||
|
|> D.decodeString (Envelope.decoder D.string)
|
||||||
|
|> Expect.equal (Ok envelope)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
]
|
|
@ -0,0 +1,50 @@
|
||||||
|
module Test.Values.Event exposing (..)
|
||||||
|
|
||||||
|
import Fuzz exposing (Fuzzer)
|
||||||
|
import Internal.Values.Event as Event exposing (Event)
|
||||||
|
import Json.Encode as E
|
||||||
|
import Test exposing (..)
|
||||||
|
import Test.Tools.Timestamp as TestTimestamp
|
||||||
|
|
||||||
|
|
||||||
|
fuzzer : Fuzzer Event
|
||||||
|
fuzzer =
|
||||||
|
Fuzz.map8 Event
|
||||||
|
valueFuzzer
|
||||||
|
Fuzz.string
|
||||||
|
TestTimestamp.fuzzer
|
||||||
|
Fuzz.string
|
||||||
|
Fuzz.string
|
||||||
|
(Fuzz.maybe Fuzz.string)
|
||||||
|
Fuzz.string
|
||||||
|
(Fuzz.maybe unsignedDataFuzzer)
|
||||||
|
|
||||||
|
|
||||||
|
unsignedDataFuzzer : Fuzzer Event.UnsignedData
|
||||||
|
unsignedDataFuzzer =
|
||||||
|
Fuzz.map4
|
||||||
|
(\age prev redact trans ->
|
||||||
|
Event.UnsignedData
|
||||||
|
{ age = age
|
||||||
|
, prevContent = prev
|
||||||
|
, redactedBecause = redact
|
||||||
|
, transactionId = trans
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(Fuzz.maybe Fuzz.int)
|
||||||
|
(Fuzz.maybe valueFuzzer)
|
||||||
|
(Fuzz.maybe <| Fuzz.lazy (\_ -> fuzzer))
|
||||||
|
(Fuzz.maybe Fuzz.string)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Example values that can be used for arbitrary JSON values
|
||||||
|
-}
|
||||||
|
valueFuzzer : Fuzzer E.Value
|
||||||
|
valueFuzzer =
|
||||||
|
Fuzz.oneOf
|
||||||
|
[ Fuzz.map E.int Fuzz.int
|
||||||
|
, Fuzz.map E.string Fuzz.string
|
||||||
|
, Fuzz.map (E.list E.int) (Fuzz.list Fuzz.int)
|
||||||
|
, Fuzz.map (E.list E.string) (Fuzz.list Fuzz.string)
|
||||||
|
, Fuzz.map Event.encode (Fuzz.lazy (\_ -> fuzzer))
|
||||||
|
]
|
|
@ -12,7 +12,7 @@ import Types
|
||||||
|
|
||||||
fuzzer : Fuzzer Matrix.Vault
|
fuzzer : Fuzzer Matrix.Vault
|
||||||
fuzzer =
|
fuzzer =
|
||||||
Fuzz.constant <| Types.Vault <| Envelope.init {}
|
Fuzz.constant <| Types.Vault <| Envelope.init ()
|
||||||
|
|
||||||
|
|
||||||
settings : Test
|
settings : Test
|
||||||
|
|
Loading…
Reference in New Issue