-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generalize Codec to admit 'Format instead of forcing byte[] (#24)
- Loading branch information
Showing
2 changed files
with
27 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,55 @@ | ||
namespace FsCodec | ||
|
||
open System | ||
|
||
/// Provides Codecs that render to a UTF-8 array suitable for storage in Event Stores, based on explicit functions you supply | ||
/// Provides Codecs that render to store-supported form (e.g., a UTF-8 byte array) suitable for storage in Event Stores, based on explicit functions you supply | ||
/// Does not involve conventions / Type Shapes / Reflection or specific Json processing libraries - see FsCodec.*.Codec for batteries-included Coding/Decoding | ||
type Codec = | ||
|
||
/// Generate a <code>IUnionEncoder</code> Codec suitable using the supplied pair of <c>encode</c> and <c>tryDecode</code> functions. | ||
// Leaving this helper private until we have a real use case which will e.g. enable us to decide whether to align the signature with the up/down functions | ||
// employed in the convention-based Codec | ||
// (IME, while many systems have some code touching the metadata, it's not something one typically wants to encourage) | ||
static member private Create<'Union,'Context> | ||
( /// Maps a 'Union to an Event Type Name with UTF-8 arrays representing the <c>Data</c> and <c>Meta</c> together with the correlationId, causationId and timestamp. | ||
encode : 'Context option * 'Union -> string * byte[] * byte[] * string * string * System.DateTimeOffset option, | ||
/// Attempts to map from an Event's Data to a <c>'Union</c> case, or <c>None</c> if not mappable. | ||
tryDecode : ITimelineEvent<byte[]> -> 'Union option) | ||
: IUnionEncoder<'Union, byte[], 'Context> = | ||
{ new IUnionEncoder<'Union, byte[], 'Context> with | ||
static member private Create<'Union,'Format,'Context> | ||
( /// Maps a 'Union to an Event Type Name, a pair of <>'Format</c>'s representing the <c>Data</c> and <c>Meta</c> together with the <c>correlationId</c>, <c>causationId</c> and <c>timestamp</c>. | ||
encode : 'Context option * 'Union -> string * 'Format * 'Format * string * string * System.DateTimeOffset option, | ||
/// Attempts to map from an Event's stored data to a <c>'Union</c> case, or <c>None</c> if not mappable. | ||
tryDecode : ITimelineEvent<'Format> -> 'Union option) | ||
: IUnionEncoder<'Union, 'Format, 'Context> = | ||
{ new IUnionEncoder<'Union, 'Format, 'Context> with | ||
member __.Encode(context, union) = | ||
let eventType, data, metadata, correlationId, causationId, timestamp = encode (context,union) | ||
Core.EventData.Create(eventType, data, metadata, correlationId, causationId, ?timestamp=timestamp) :> _ | ||
member __.TryDecode encoded = | ||
tryDecode encoded } | ||
|
||
/// Generate a <code>IUnionEncoder</code> Codec suitable using the supplied <c>encode</c> and <c>tryDecode</code> functions to map to/from UTF8. | ||
/// <c>mapCausation</c> provides metadata generation and correlation/causationId mapping based on the Context passed to the encoder | ||
static member Create<'Context,'Union> | ||
/// Generate a <code>IUnionEncoder</code> Codec suitable using the supplied <c>encode</c> and <c>tryDecode</code> functions to map to/from the stored form. | ||
/// <c>mapCausation</c> provides metadata generation and correlation/causationId mapping based on the <c>context</c> passed to the encoder | ||
static member Create<'Context,'Union,'Format> | ||
( /// Maps from the TypeShape <c>UnionConverter</c> <c>'Contract</c> case the Event has been mapped to (with the raw event data as context) | ||
/// to the representation (typically a Discriminated Union) that is to be presented to the programming model. | ||
tryDecode : FsCodec.ITimelineEvent<byte[]> -> 'Union option, | ||
tryDecode : FsCodec.ITimelineEvent<'Format> -> 'Union option, | ||
/// Maps a fresh Event resulting from a Decision in the Domain representation type down to the TypeShape <c>UnionConverter</c> <c>'Contract</c> | ||
/// The function is also expected to derive | ||
/// a <c>meta</c> object that will be serialized with the same settings (if it's not <c>None</c>) | ||
/// and an Event Creation <c>timestamp</c>. | ||
encode : 'Union -> string * byte[] * DateTimeOffset option, | ||
encode : 'Union -> string * 'Format * DateTimeOffset option, | ||
/// Uses the 'Context passed to the Encode call and the 'Meta emitted by <c>down</c> to a) the final metadata b) the <c>correlationId</c> and c) the correlationId | ||
mapCausation : 'Context option * 'Union -> byte[] * string * string, | ||
/// Configuration to be used by the underlying <c>Newtonsoft.Json</c> Serializer when encoding/decoding. Defaults to same as <c>Settings.Create()</c> | ||
?settings, | ||
/// Enables one to fail encoder generation if union contains nullary cases. Defaults to <c>false</c>, i.e. permitting them | ||
?rejectNullaryCases) | ||
: FsCodec.IUnionEncoder<'Union,byte[],'Context> = | ||
mapCausation : 'Context option * 'Union -> 'Format * string * string) | ||
: FsCodec.IUnionEncoder<'Union,'Format,'Context> = | ||
let encode (context,union) = | ||
let et, d, t = encode union | ||
let m, correlationId, causationId = mapCausation (context, union) | ||
et, d, m, correlationId, causationId, t | ||
Codec.Create(encode,tryDecode) | ||
|
||
/// Generate a <code>IUnionEncoder</code> Codec using the supplied pair of <c>encode</c> and <c>tryDecode</code> functions. | ||
static member Create<'Union> | ||
static member Create<'Union,'Format when 'Format : null> | ||
( /// Maps a <c>'Union</c> to an Event Type Name and a UTF-8 array representing the <c>Data</c>. | ||
encode : 'Union -> string * byte[], | ||
encode : 'Union -> string * 'Format, | ||
/// Attempts to map an Event Type Name and a UTF-8 <c>Data</c> array to a <c>'Union</c> case, or <c>None</c> if not mappable. | ||
tryDecode : string * byte[] -> 'Union option) | ||
: IUnionEncoder<'Union, byte[], obj> = | ||
let encode' (_context,union) = let et, d = encode union in et, d, null, null, null, None | ||
let tryDecode' (encoded : FsCodec.ITimelineEvent<_>) = tryDecode (encoded.EventType,encoded.Data) | ||
tryDecode : string * 'Format -> 'Union option) | ||
: IUnionEncoder<'Union, 'Format, obj> = | ||
let encode' (_context : obj,union) = let (et, d : 'Format) = encode union in et, d, null, null, null, None | ||
let tryDecode' (encoded : FsCodec.ITimelineEvent<'Format>) = tryDecode (encoded.EventType,encoded.Data) | ||
Codec.Create(encode', tryDecode') |