Add documentation + add `sameForVersion` function
parent
dbbd009a58
commit
1fcb754e55
|
@ -1,4 +1,4 @@
|
|||
module Internal.Api.SendMessageEvent.V1.Api exposing (sendMessageEventV1, sendMessageEventV2, SendMessageEventOutputV1, SendMessageEventInputV1)
|
||||
module Internal.Api.SendMessageEvent.Api exposing (sendMessageEventV1, sendMessageEventV2, SendMessageEventOutputV1, SendMessageEventInputV1)
|
||||
|
||||
import Internal.Api.Request as R
|
||||
import Internal.Api.SendMessageEvent.V1.SpecObjects as SO1
|
||||
|
|
|
@ -2,9 +2,6 @@ module Internal.Api.SendMessageEvent.Main exposing (..)
|
|||
|
||||
import Internal.Api.SendMessageEvent.Api as Api
|
||||
import Internal.Tools.VersionControl as VC
|
||||
import Internal.Tools.Exceptions as X
|
||||
import Task exposing (Task)
|
||||
|
||||
|
||||
sendMessageEvent : List String -> Maybe (SendMessageEventInput -> SendMessageEventOutput)
|
||||
sendMessageEvent versions =
|
||||
|
@ -12,78 +9,23 @@ sendMessageEvent versions =
|
|||
{ current = Api.sendMessageEventV1
|
||||
, version = "r0.0.0"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV1
|
||||
, upcast = identity
|
||||
, version = "r0.0.1"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV1
|
||||
, upcast = identity
|
||||
, version = "r0.1.0"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV1
|
||||
, upcast = identity
|
||||
, version = "r0.2.0"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV1
|
||||
, upcast = identity
|
||||
, version = "r0.3.0"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV1
|
||||
, upcast = identity
|
||||
, version = "r0.5.0"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV1
|
||||
, upcast = identity
|
||||
, version = "r0.6.0"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV1
|
||||
, upcast = identity
|
||||
, version = "r0.6.1"
|
||||
}
|
||||
|> VC.sameForVersion "r0.0.1"
|
||||
|> VC.sameForVersion "r0.1.0"
|
||||
|> VC.sameForVersion "r0.2.0"
|
||||
|> VC.sameForVersion "r0.3.0"
|
||||
|> VC.sameForVersion "r0.5.0"
|
||||
|> VC.sameForVersion "r0.6.0"
|
||||
|> VC.sameForVersion "r0.6.1"
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV2
|
||||
, upcast = identity
|
||||
, version = "v1.1"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV2
|
||||
, upcast = identity
|
||||
, version = "v1.2"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV2
|
||||
, upcast = identity
|
||||
, version = "v1.3"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV2
|
||||
, upcast = identity
|
||||
, version = "v1.4"
|
||||
}
|
||||
|> VC.addMiddleLayer
|
||||
{ downcast = identity
|
||||
, current = Api.sendMessageEventV2
|
||||
, upcast = identity
|
||||
, version = "v1.5"
|
||||
}
|
||||
|> VC.sameForVersion "v1.2"
|
||||
|> VC.sameForVersion "v1.3"
|
||||
|> VC.sameForVersion "v1.4"
|
||||
|> VC.sameForVersion "v1.5"
|
||||
|> VC.mostRecentFromVersionList versions
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
module Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
|
||||
|
||||
{-| Module that helps while decoding JSON.
|
||||
|
||||
|
||||
# Optional field decoders
|
||||
|
||||
@docs opField, opFieldWithDefault
|
||||
|
||||
-}
|
||||
|
||||
import Json.Decode as D
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
module Internal.Tools.EncodeExtra exposing (..)
|
||||
module Internal.Tools.EncodeExtra exposing (maybeObject)
|
||||
|
||||
{-| Module that helps with encoding objects into JSON.
|
||||
|
||||
|
||||
# Optional body object
|
||||
|
||||
@docs maybeObject
|
||||
|
||||
-}
|
||||
|
||||
import Json.Encode as E
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
module Internal.Tools.VersionControl exposing
|
||||
( VersionControl, withBottomLayer
|
||||
, MiddleLayer, addMiddleLayer
|
||||
, toDict, fromVersion, fromVersionList
|
||||
, mostRecentFromVersionList, sameForVersion
|
||||
)
|
||||
|
||||
{-| This module helps you create multiple functions for different (spec) versions
|
||||
while still having only one input, one output.
|
||||
|
||||
The module can be best described as a layered version type.
|
||||
|
||||
|----------------------------------------------|
|
||||
| VersionControl |
|
||||
| input output |
|
||||
| | ^ |
|
||||
|---------------------- | -------------- | ----|
|
||||
| |
|
||||
|---------------------- | -------------- | ----|
|
||||
| MiddleLayer v3 | | |
|
||||
| [---> current ---] |
|
||||
| | | |
|
||||
| downcast upcast |
|
||||
| | ^ |
|
||||
|---------------------- | -------------- | ----|
|
||||
| |
|
||||
|---------------------- | -------------- | ----|
|
||||
| MiddleLayer v2 | | |
|
||||
| [---> current ---] |
|
||||
| | | |
|
||||
| downcast upcast |
|
||||
| | ^ |
|
||||
|---------------------- | -------------- | ----|
|
||||
| |
|
||||
|---------------------- | -------------- | ----|
|
||||
| BottomLayer v1 | | |
|
||||
| \---> current ---/ |
|
||||
| |
|
||||
|----------------------------------------------|
|
||||
|
||||
This method means you will only need to write one downcast, one current and one upcast
|
||||
whenever you introduce a new version. This means you can instantly update all functions
|
||||
without having to write every version!
|
||||
|
||||
The VersionControl keeps a `Dict` type but also tracks the version order.
|
||||
This way, you can either get the VersionControl type to render the function for
|
||||
the most recent supported version, or you can choose for yourself which version
|
||||
you prefer to use.
|
||||
|
||||
|
||||
# Making VersionControl
|
||||
|
||||
@docs VersionControl, withBottomLayer
|
||||
|
||||
|
||||
# Adding more versions
|
||||
|
||||
@docs MiddleLayer, addMiddleLayer
|
||||
|
||||
|
||||
# Getting functions
|
||||
|
||||
@docs toDict, fromVersion, mostRecentFromVerionList, fromVersionList
|
||||
|
||||
-}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
|
||||
|
||||
{-| The bottom layer is the final version option.
|
||||
|
||||
If even this version is not approved, there will be no function to execute.
|
||||
|
||||
-}
|
||||
type alias BottomLayer cin cout =
|
||||
{ current : cin -> cout, version : String }
|
||||
|
||||
|
||||
{-| The middle layer is an optional function to execute.
|
||||
|
||||
If the version is approved, it is executed - otherwise, the next version will be considered.
|
||||
|
||||
-}
|
||||
type alias MiddleLayer cin cout din dout =
|
||||
{ current : cin -> cout
|
||||
, downcast : cin -> din
|
||||
, upcast : dout -> cout
|
||||
, version : String
|
||||
}
|
||||
|
||||
|
||||
{-| The VersionControl layer is the layer that keeps track of all potential versions.
|
||||
-}
|
||||
type VersionControl cin cout
|
||||
= VersionControl
|
||||
{ latestVersion : cin -> cout
|
||||
, order : List String
|
||||
, versions : Dict String (cin -> cout)
|
||||
}
|
||||
|
||||
|
||||
{-| Add an extra version to the VersionControl. This will completely change the input and output
|
||||
of every function, as all functions will abide by the most recent version's specifics.
|
||||
-}
|
||||
addMiddleLayer : MiddleLayer cin cout din dout -> VersionControl din dout -> VersionControl cin cout
|
||||
addMiddleLayer { current, downcast, upcast, version } (VersionControl d) =
|
||||
VersionControl
|
||||
{ latestVersion = current
|
||||
, order = version :: d.order
|
||||
, versions =
|
||||
d.versions
|
||||
|> Dict.map (\_ f -> downcast >> f >> upcast)
|
||||
|> Dict.insert version current
|
||||
}
|
||||
|
||||
|
||||
{-| Provided that a version has been passed to the VersionControl, you will receive the appropriate version.
|
||||
-}
|
||||
fromVersion : String -> VersionControl a b -> Maybe (a -> b)
|
||||
fromVersion version (VersionControl { versions }) =
|
||||
Dict.get version versions
|
||||
|
||||
|
||||
{-| Provided a list of versions, this function will provide a list of compatible versions to you in your preferred order.
|
||||
|
||||
If you just care about getting the most recent function, you will be better off using `mostRecentFromVersionList`,
|
||||
but this function can help if you care about knowing which Matrix spec version you're using.
|
||||
|
||||
-}
|
||||
fromVersionList : List String -> VersionControl a b -> List ( String, a -> b )
|
||||
fromVersionList versionList vc =
|
||||
List.filterMap
|
||||
(\version ->
|
||||
vc
|
||||
|> fromVersion version
|
||||
|> Maybe.map (\f -> ( version, f ))
|
||||
)
|
||||
versionList
|
||||
|
||||
|
||||
{-| Get a dict of all available functions.
|
||||
-}
|
||||
toDict : VersionControl a b -> Dict String (a -> b)
|
||||
toDict (VersionControl d) =
|
||||
d.versions
|
||||
|
||||
|
||||
{-| Get the most recent event based on a list of versions.
|
||||
-}
|
||||
mostRecentFromVersionList : List String -> VersionControl a b -> Maybe (a -> b)
|
||||
mostRecentFromVersionList versionList ((VersionControl { order }) as vc) =
|
||||
order
|
||||
|> List.filter (\o -> List.member o versionList)
|
||||
|> List.filterMap (\v -> fromVersion v vc)
|
||||
|> List.head
|
||||
|
||||
{-| Sometimes, no changes are needed and a function works just the same as the one in the previous version.
|
||||
In that case, you can amend with a `sameForVersion` function to indicate that the spec is
|
||||
identical for this version.
|
||||
-}
|
||||
sameForVersion : String -> VersionControl a b -> VersionControl a b
|
||||
sameForVersion version (VersionControl data) =
|
||||
VersionControl
|
||||
{ data
|
||||
| order = version :: data.order
|
||||
, versions = Dict.insert version data.latestVersion data.versions
|
||||
}
|
||||
|
||||
|
||||
{-| You cannot create an empty VersionControl layer, you must always start with a BottomLayer
|
||||
and then stack MiddleLayer types on top until you've reached the version that you're happy with.
|
||||
-}
|
||||
withBottomLayer : BottomLayer a b -> VersionControl a b
|
||||
withBottomLayer { current, version } =
|
||||
VersionControl
|
||||
{ latestVersion = current
|
||||
, order = List.singleton version
|
||||
, versions = Dict.singleton version current
|
||||
}
|
Loading…
Reference in New Issue