From 02ec61414650de74db2211ab89174fb38049dc23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Nor=C3=B0fj=C3=B6r=C3=B0?= Date: Fri, 17 Nov 2023 02:11:32 -0500 Subject: [PATCH] refactor!: Rename IEventCodec.TryDecode to Decode (#107) --- CHANGELOG.md | 1 + README.md | 28 +++++++++---------- src/FsCodec.Box/Compression.fs | 2 +- src/FsCodec.Box/CoreCodec.fs | 2 +- src/FsCodec/Codec.fs | 22 +++++++-------- src/FsCodec/FsCodec.fs | 6 ++-- .../VerbatimUtf8ConverterTests.fs | 8 +++--- .../CodecTests.fs | 4 +-- .../FsCodec.SystemTextJson.Tests/Examples.fsx | 22 +++++++-------- .../InteropTests.fs | 4 +-- tests/FsCodec.Tests/CompressionTests.fs | 6 ++-- 11 files changed, 53 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 766941b6..ddbbf10d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The `Unreleased` section name is replaced by the expected version of next releas ### Added ### Changed +- `IEventCodec.TryDecode`: Rename to `Decode` (to align with the primary assumption of a `Try` prefix per BCL conventions: It won't throw, no matter what!) [#107](https://github.com/jet/FsCodec/pull/107) :pray: [@nordfjord](https://github.com/nordfjord) ### Removed ### Fixed diff --git a/README.md b/README.md index 8e6098c9..2e336fab 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The components within this repository are delivered as multi-targeted Nuget pack - [![Codec NuGet](https://img.shields.io/nuget/v/FsCodec.svg)](https://www.nuget.org/packages/FsCodec/) `FsCodec` Defines interfaces with trivial implementation helpers. - No dependencies. - [`FsCodec.IEventCodec`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/FsCodec.fs#L19): defines a base interface for serializers. - - [`FsCodec.Codec`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/Codec.fs#L5): enables plugging in a serializer and/or Union Encoder of your choice (typically this is used to supply a pair `encode` and `tryDecode` functions) + - [`FsCodec.Codec`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/Codec.fs#L5): enables plugging in custom serialization (a trivial implementation of the interface that simply delegates to a pair of `encode` and `decode` functions you supply) - [`FsCodec.StreamName`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/StreamName.fs): strongly-typed wrapper for a Stream Name, together with factory functions and active patterns for parsing same - [`FsCodec.StreamId`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/StreamId.fs): strongly-typed wrapper for a Stream Id, together with factory functions and active patterns for parsing same - [![Box Codec NuGet](https://img.shields.io/nuget/v/FsCodec.Box.svg)](https://www.nuget.org/packages/FsCodec.Box/) `FsCodec.Box`: See [`FsCodec.Box.Codec`](#boxcodec); `IEventCodec` implementation that provides a null encode/decode step in order to enable decoupling of serialization/deserialization concerns from the encoding aspect, typically used together with [`Equinox.MemoryStore`](https://www.fuget.org/packages/Equinox.MemoryStore) @@ -30,8 +30,8 @@ The purpose of the `FsCodec` package is to provide a minimal interface on which - [`FsCodec.IEventData`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/FsCodec.fs#L4) represents a single event and/or related metadata in raw form (i.e. still as a UTF8 string etc, not yet bound to a specific Event Type) - [`FsCodec.ITimelineEvent`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/FsCodec.fs#L23) represents a single stored event and/or related metadata in raw form (i.e. still as a UTF8 string etc, not yet bound to a specific Event Type). Inherits `IEventData`, adding `Index` and `IsUnfold` in order to represent the position on the timeline that the event logically occupies. -- [`FsCodec.IEventCodec`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/FsCodec.fs#L31) presents `Encode: 'Context option * 'Event -> IEventData` and `TryDecode: ITimelineEvent -> 'Event option` methods that can be used in low level application code to generate `IEventData`s or decode `ITimelineEvent`s based on a contract defined by `'Union` -- [`FsCodec.Codec.Create`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/Codec.fs#L27) implements `IEventCodec` in terms of supplied `encode: 'Event -> string * byte[]` and `tryDecode: string * byte[] -> 'Event option` functions (other overloads are available for advanced cases) +- [`FsCodec.IEventCodec`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/FsCodec.fs#L31) presents `Encode: 'Context option * 'Event -> IEventData` and `Decode: ITimelineEvent -> 'Event voption` methods that can be used in low level application code to generate `IEventData`s or decode `ITimelineEvent`s based on a contract defined by `'Union` +- [`FsCodec.Codec.Create`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/Codec.fs#L27) implements `IEventCodec` in terms of supplied `encode: 'Event -> string * byte[]` and `decode: string * byte[] -> 'Event voption` functions (other overloads are available for advanced cases) - [`FsCodec.Core.EventData.Create`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/FsCodec.fs#L44) is a low level helper to create an `IEventData` directly for purposes such as tests etc. - [`FsCodec.Core.TimelineEvent.Create`](https://github.com/jet/FsCodec/blob/master/src/FsCodec/FsCodec.fs#L58) is a low level helper to create an `ITimelineEvent` directly for purposes such as tests etc. @@ -479,7 +479,7 @@ type IEventCodec<'Event, 'Format, 'Context> = /// Encodes a 'Event instance into a 'Format representation abstract Encode: context: 'Context * value: 'Event -> IEventData<'Format> /// Decodes a formatted representation into a 'Event instance. Does not throw exception on undefined EventTypes - abstract TryDecode: encoded: ITimelineEvent<'Format> -> 'Event voption + abstract Decode: encoded: ITimelineEvent<'Format> -> 'Event voption ``` `IEventCodec` represents a standard contract for the encoding and decoding of events used in event sourcing and event based notification scenarios: @@ -728,13 +728,13 @@ module private Stream = /// Inverse of `id`; decodes a StreamId into its constituent parts; throws if the presented StreamId does not adhere to the expected format let decodeId: FsCodec.StreamId -> ClientId = FsCodec.StreamId.dec ClientId.parse /// Inspects a stream name; if for this Category, decodes the elements into application level ids. Throws if it's malformed. - let tryDecode: FsCodec.StreamName -> ClientId voption = FsCodec.StreamName.tryFind Category >> ValueOption.map decodeId + let decode: FsCodec.StreamName -> ClientId voption = FsCodec.StreamName.tryFind Category >> ValueOption.map decodeId module Reactions = /// Active Pattern to determine whether a given {category}-{streamId} StreamName represents the stream associated with this Aggregate /// Yields a strongly typed id from the streamId if the Category matches - let [] (|For|_|) = Stream.tryDecode + let [] (|For|_|) = Stream.decode let private dec = Streams.codec /// Yields decoded events and relevant strongly typed ids if the Category of the Stream Name matches @@ -772,12 +772,12 @@ let streamCodec<'E when 'E :> TypeShape.UnionContract.IUnionContract> : Codec<'E Codec.Create<'E>(serdes = Store.serdes) let dec = streamCodec -let [] (|TryDecodeEvent|_|) (codec: Codec<'E>) event = codec.TryDecode event +let [] (|DecodeEvent|_|) (codec: Codec<'E>) event = codec.Decode event let runCodecExplicit () = for stream, event in events do match stream, event with - | Reactions.For clientId, TryDecodeEvent dec e -> + | Reactions.For clientId, DecodeEvent dec e -> printfn $"Client %s{ClientId.toString clientId}, event %A{e}" | FsCodec.StreamName.Split struct (cat, sid), e -> printfn $"Unhandled Event: Category %s{cat}, Ids %s{FsCodec.StreamId.toString sid}, Index %d{e.Index}, Event: %A{e.EventType}" @@ -817,7 +817,7 @@ module ReactionsBasic = let dec = streamCodec let (|DecodeSingle|_|): FsCodec.StreamName * Event -> (ClientId * Events.Event) option = function - | Reactions.For clientId, TryDecodeEvent dec event -> Some (clientId, event) + | Reactions.For clientId, DecodeEvent dec event -> Some (clientId, event) | _ -> None ``` @@ -862,8 +862,8 @@ module Streams = System.Text.Encoding.UTF8.GetString(x.Span) /// Uses the supplied codec to decode the supplied event record `x` /// (iff at LogEventLevel.Debug, detail fails to `log` citing the `streamName` and body) - let tryDecode<'E> (log: Serilog.ILogger) (codec: Codec<'E>) (streamName: FsCodec.StreamName) (x: Event) = - match codec.TryDecode x with + let decode<'E> (log: Serilog.ILogger) (codec: Codec<'E>) (streamName: FsCodec.StreamName) (x: Event) = + match codec.Decode x with | ValueNone -> if log.IsEnabled Serilog.Events.LogEventLevel.Debug then log.ForContext("event", render x.Data, true) @@ -872,12 +872,12 @@ module Streams = | ValueSome x -> ValueSome x /// Attempts to decode the supplied Event using the supplied Codec - let [] (|TryDecode|_|) (codec: Codec<'E>) struct (streamName, event) = - tryDecode Serilog.Log.Logger codec streamName event + let [] (|Decode|_|) (codec: Codec<'E>) struct (streamName, event) = + decode Serilog.Log.Logger codec streamName event module Array = let inline chooseV f xs = [| for item in xs do match f item with ValueSome v -> yield v | ValueNone -> () |] /// Yields the subset of events that successfully decoded (could be Array.empty) let decode<'E> (codec: Codec<'E>) struct (streamName, events: Event[]): 'E[] = - events |> Array.chooseV (tryDecode<'E> Serilog.Log.Logger codec streamName) + events |> Array.chooseV (decode<'E> Serilog.Log.Logger codec streamName) let (|Decode|) = decode ``` diff --git a/src/FsCodec.Box/Compression.fs b/src/FsCodec.Box/Compression.fs index 48d4f785..f1129ff7 100644 --- a/src/FsCodec.Box/Compression.fs +++ b/src/FsCodec.Box/Compression.fs @@ -15,7 +15,7 @@ module private EncodedMaybeCompressed = let [] Deflate = 1 // Deprecated encoding produced by versions pre 3.0.0-rc.13; no longer produced let [] Brotli = 2 // Default encoding as of 3.0.0-rc.13 - (* Decompression logic: triggered by extension methods below at the point where the Codec's TryDecode retrieves the Data or Meta properties *) + (* Decompression logic: triggered by extension methods below at the point where the Codec's Decode retrieves the Data or Meta properties *) // In versions pre 3.0.0-rc.13, the compression was implemented as follows; NOTE: use of Flush vs Close saves space but is unconventional // let private deflate (eventBody: ReadOnlyMemory): System.IO.MemoryStream = diff --git a/src/FsCodec.Box/CoreCodec.fs b/src/FsCodec.Box/CoreCodec.fs index 80ccc0ea..91a47312 100755 --- a/src/FsCodec.Box/CoreCodec.fs +++ b/src/FsCodec.Box/CoreCodec.fs @@ -44,7 +44,7 @@ type Codec private () = let meta' = match meta with ValueSome x -> encoder.Encode<'Meta> x | ValueNone -> Unchecked.defaultof<'Body> EventData(enc.CaseName, enc.Payload, meta', eventId, correlationId, causationId, timestamp) - member _.TryDecode encoded = + member _.Decode encoded = match dataCodec.TryDecode { CaseName = encoded.EventType; Payload = encoded.Data } with | None -> ValueNone | Some contract -> up.Invoke(encoded, contract) |> ValueSome } diff --git a/src/FsCodec/Codec.fs b/src/FsCodec/Codec.fs index d5462c6d..ef5726fc 100755 --- a/src/FsCodec/Codec.fs +++ b/src/FsCodec/Codec.fs @@ -7,7 +7,7 @@ open System [] type Codec = - /// Generate an IEventCodec suitable using the supplied pair of encode and tryDecode functions. + /// Generate an IEventCodec suitable using the supplied pair of encode and decode 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) @@ -16,7 +16,7 @@ type Codec = // eventId, correlationId, causationId and timestamp. encode: Func<'Context, 'Event, struct (string * 'Format * 'Format * Guid * string * string * DateTimeOffset)>, // Attempts to map from an Event's stored data to Some 'Event, or None if not mappable. - tryDecode: Func, 'Event voption>) + decode: Func, 'Event voption>) : IEventCodec<'Event, 'Format, 'Context> = { new IEventCodec<'Event, 'Format, 'Context> with @@ -24,10 +24,10 @@ type Codec = let struct (eventType, data, metadata, eventId, correlationId, causationId, timestamp) = encode.Invoke(context, event) Core.EventData(eventType, data, metadata, eventId, correlationId, causationId, timestamp) - member _.TryDecode encoded = - tryDecode.Invoke encoded } + member _.Decode encoded = + decode.Invoke encoded } - /// Generate an IEventCodec suitable using the supplied encode and tryDecode functions to map to/from the stored form. + /// Generate an IEventCodec suitable using the supplied encode and decode functions to map to/from the stored form. /// mapCausation provides metadata generation and correlation/causationId mapping based on the context passed to the encoder static member Create<'Event, 'Format, 'Context> ( // Maps a fresh 'Event resulting from the Domain representation type down to the TypeShape UnionConverter 'Contract @@ -37,7 +37,7 @@ type Codec = encode: Func<'Event, struct (string * 'Format * DateTimeOffset voption)>, // Maps from the TypeShape UnionConverter 'Contract case the Event has been mapped to (with the raw event data as context) // to the 'Event representation (typically a Discriminated Union) that is to be presented to the programming model. - tryDecode: Func, 'Event voption>, + decode: Func, 'Event voption>, // Uses the 'Context passed to the Encode call and the 'Meta emitted by down to a) the final metadata b) the correlationId and c) the correlationId mapCausation: Func<'Context, 'Event, struct ('Format * Guid * string * string)>) : IEventCodec<'Event, 'Format, 'Context> = @@ -47,19 +47,19 @@ type Codec = let ts = match t with ValueSome x -> x | ValueNone -> DateTimeOffset.UtcNow let struct (m, eventId, correlationId, causationId) = mapCausation.Invoke(context, event) struct (et, d, m, eventId, correlationId, causationId, ts) - Codec.Create(encode, tryDecode) + Codec.Create(encode, decode) - /// Generate an IEventCodec using the supplied pair of encode and tryDecode functions. + /// Generate an IEventCodec using the supplied pair of encode and decode functions. static member Create<'Event, 'Format> ( // Maps a 'Event to an Event Type Name and an encoded body (to be used as the Data). encode: Func<'Event, struct (string * 'Format)>, // Attempts to map an Event Type Name and an encoded Data to Some 'Event case, or None if not mappable. - tryDecode: Func) + decode: Func) : IEventCodec<'Event, 'Format, unit> = let encode' _context event = let struct (eventType, data : 'Format) = encode.Invoke event struct (eventType, data, Unchecked.defaultof<'Format> (* metadata *), Guid.NewGuid() (* eventId *), null (* correlationId *), null (* causationId *), DateTimeOffset.UtcNow (* timestamp *)) - let tryDecode' (encoded : ITimelineEvent<'Format>) = tryDecode.Invoke(encoded.EventType, encoded.Data) - Codec.Create(encode', tryDecode') + let decode' (encoded : ITimelineEvent<'Format>) = decode.Invoke(encoded.EventType, encoded.Data) + Codec.Create(encode', decode') diff --git a/src/FsCodec/FsCodec.fs b/src/FsCodec/FsCodec.fs index 3f7143cd..5f82223e 100755 --- a/src/FsCodec/FsCodec.fs +++ b/src/FsCodec/FsCodec.fs @@ -35,7 +35,7 @@ type IEventCodec<'Event, 'Format, 'Context> = /// Encodes a 'Event instance into a 'Format representation abstract Encode: context: 'Context * value : 'Event -> IEventData<'Format> /// Decodes a formatted representation into a 'Event instance. Returns None on undefined EventTypes - abstract TryDecode: encoded: ITimelineEvent<'Format> -> 'Event voption + abstract Decode: encoded: ITimelineEvent<'Format> -> 'Event voption namespace FsCodec.Core @@ -132,6 +132,6 @@ type EventCodec<'Event, 'Format, 'Context> private () = let encoded = native.Encode(context, event) upConvert encoded - member _.TryDecode target = + member _.Decode target = let encoded = downConvert target - native.TryDecode encoded } + native.Decode encoded } diff --git a/tests/FsCodec.NewtonsoftJson.Tests/VerbatimUtf8ConverterTests.fs b/tests/FsCodec.NewtonsoftJson.Tests/VerbatimUtf8ConverterTests.fs index 9972f0ae..2016698e 100644 --- a/tests/FsCodec.NewtonsoftJson.Tests/VerbatimUtf8ConverterTests.fs +++ b/tests/FsCodec.NewtonsoftJson.Tests/VerbatimUtf8ConverterTests.fs @@ -67,7 +67,7 @@ module VerbatimUtf8Tests = // not a module or CI will fail for net461 test <@ res.Contains """"d":{"embed":"\""}""" @> let des = JsonConvert.DeserializeObject(res) let loaded = FsCodec.Core.TimelineEvent.Create(-1L, des.e[0].c, ReadOnlyMemory des.e[0].d) - let decoded = eventCodec.TryDecode loaded |> ValueOption.get + let decoded = eventCodec.Decode loaded |> ValueOption.get input =! decoded let defaultSettings = Options.CreateDefault() @@ -79,7 +79,7 @@ module VerbatimUtf8Tests = // not a module or CI will fail for net461 let ser = JsonConvert.SerializeObject(e, defaultSettings) let des = JsonConvert.DeserializeObject(ser, defaultSettings) let loaded = FsCodec.Core.TimelineEvent.Create(-1L, des.e[0].c, ReadOnlyMemory des.e[0].d) - let decoded = defaultEventCodec.TryDecode loaded |> ValueOption.get + let decoded = defaultEventCodec.Decode loaded |> ValueOption.get x =! decoded // https://github.com/JamesNK/Newtonsoft.Json/issues/862 // doesnt apply to this case @@ -87,7 +87,7 @@ module VerbatimUtf8Tests = // not a module or CI will fail for net461 let x = ES { embed = "2016-03-31T07:02:00+07:00" } let encoded = defaultEventCodec.Encode((), x) let adapted = FsCodec.Core.TimelineEvent.Create(-1L, encoded) - let decoded = defaultEventCodec.TryDecode adapted |> ValueOption.get + let decoded = defaultEventCodec.Decode adapted |> ValueOption.get test <@ x = decoded @> //// NB while this aspect works, we don't support it as it gets messy when you then use the VerbatimUtf8Converter @@ -95,7 +95,7 @@ module VerbatimUtf8Tests = // not a module or CI will fail for net461 //let [] ``Codec can roundtrip strings`` (value: string) = // let x = SS value // let encoded = sEncoder.Encode x - // let decoded = sEncoder.TryDecode encoded |> Option.get + // let decoded = sEncoder.Decode encoded |> Option.get // test <@ x = decoded @> module VerbatimUtf8NullHandling = diff --git a/tests/FsCodec.SystemTextJson.Tests/CodecTests.fs b/tests/FsCodec.SystemTextJson.Tests/CodecTests.fs index 3a36fe7d..cec26192 100644 --- a/tests/FsCodec.SystemTextJson.Tests/CodecTests.fs +++ b/tests/FsCodec.SystemTextJson.Tests/CodecTests.fs @@ -60,7 +60,7 @@ let [] roundtrips value = test <@ wrapped.EventId = System.Guid.Empty && (let d = System.DateTimeOffset.UtcNow - wrapped.Timestamp abs d.TotalMinutes < 1) @> - let decoded = eventCodec.TryDecode wrapped |> ValueOption.get + let decoded = eventCodec.Decode wrapped |> ValueOption.get let expected = match value with | AO ({ opt = Some null } as v) -> AO { v with opt = None } @@ -69,7 +69,7 @@ let [] roundtrips value = test <@ expected = decoded @> // Also validate the adapters work when put in series (NewtonsoftJson tests are responsible for covering the individual hops) - let decodedMultiHop = multiHopCodec.TryDecode wrapped |> ValueOption.get + let decodedMultiHop = multiHopCodec.Decode wrapped |> ValueOption.get test <@ expected = decodedMultiHop @> let [] ``EventData.Create basics`` () = diff --git a/tests/FsCodec.SystemTextJson.Tests/Examples.fsx b/tests/FsCodec.SystemTextJson.Tests/Examples.fsx index ad29d2ee..2346bda1 100755 --- a/tests/FsCodec.SystemTextJson.Tests/Examples.fsx +++ b/tests/FsCodec.SystemTextJson.Tests/Examples.fsx @@ -191,12 +191,12 @@ module private Stream = /// Inverse of `id`; decodes a StreamId into its constituent parts; throws if the presented StreamId does not adhere to the expected format let decodeId: FsCodec.StreamId -> ClientId = FsCodec.StreamId.dec ClientId.parse /// Inspects a stream name; if for this Category, decodes the elements into application level ids. Throws if it's malformed. - let tryDecode: FsCodec.StreamName -> ClientId voption = FsCodec.StreamName.tryFind Category >> ValueOption.map decodeId + let decode: FsCodec.StreamName -> ClientId voption = FsCodec.StreamName.tryFind Category >> ValueOption.map decodeId module Reaction = /// Active Pattern to determine whether a given {category}-{streamId} StreamName represents the stream associated with this Aggregate /// Yields a strongly typed id from the streamId if the Category matches - let [] (|For|_|) = Stream.tryDecode + let [] (|For|_|) = Stream.decode module Events = @@ -244,12 +244,12 @@ let streamCodec<'E when 'E :> TypeShape.UnionContract.IUnionContract> : Codec<'E Codec.Create<'E>(serdes = Store.serdes) let dec = streamCodec -let [] (|TryDecodeEvent|_|) (codec: Codec<'E>) event = codec.TryDecode event +let [] (|DecodeEvent|_|) (codec: Codec<'E>) event = codec.Decode event let runCodecExplicit () = for stream, event in events do match stream, event with - | Reaction.For clientId, TryDecodeEvent dec e -> + | Reaction.For clientId, DecodeEvent dec e -> printfn $"Client %s{ClientId.toString clientId}, event %A{e}" | FsCodec.StreamName.Split struct (cat, sid), e -> printfn $"Unhandled Event: Category %s{cat}, Ids %s{FsCodec.StreamId.toString sid}, Index %d{e.Index}, Event: %A{e.EventType}" @@ -273,7 +273,7 @@ module ReactionsBasic = let dec = streamCodec let (|DecodeSingle|_|): FsCodec.StreamName * Event -> (ClientId * Events.Event) option = function - | Reaction.For clientId, TryDecodeEvent dec event -> Some (clientId, event) + | Reaction.For clientId, DecodeEvent dec event -> Some (clientId, event) | _ -> None let reactSingle (clientId: ClientId) (event: Events.Event) = @@ -314,8 +314,8 @@ module Streams = System.Text.Encoding.UTF8.GetString(x.Span) /// Uses the supplied codec to decode the supplied event record `x` /// (iff at LogEventLevel.Debug, detail fails to `log` citing the `streamName` and body) - let tryDecode<'E> (log: Serilog.ILogger) (codec: Codec<'E>) (streamName: FsCodec.StreamName) (x: Event) = - match codec.TryDecode x with + let decode<'E> (log: Serilog.ILogger) (codec: Codec<'E>) (streamName: FsCodec.StreamName) (x: Event) = + match codec.Decode x with | ValueNone -> if log.IsEnabled Serilog.Events.LogEventLevel.Debug then log.ForContext("event", render x.Data, true) @@ -324,12 +324,12 @@ module Streams = | ValueSome x -> ValueSome x /// Attempts to decode the supplied Event using the supplied Codec - let [] (|TryDecode|_|) (codec: Codec<'E>) struct (streamName, event) = - tryDecode Serilog.Log.Logger codec streamName event + let [] (|Decode|_|) (codec: Codec<'E>) struct (streamName, event) = + decode Serilog.Log.Logger codec streamName event module Array = let inline chooseV f xs = [| for item in xs do match f item with ValueSome v -> yield v | ValueNone -> () |] /// Yields the subset of events that successfully decoded (could be Array.empty) let decode<'E> (codec: Codec<'E>) struct (streamName, events: Event[]): 'E[] = - events |> Array.chooseV (tryDecode<'E> Serilog.Log.Logger codec streamName) + events |> Array.chooseV (decode<'E> Serilog.Log.Logger codec streamName) let (|Decode|) = decode (* When using Propulsion, Events are typically delivered as an array of contiguous events together with a StreamName @@ -339,7 +339,7 @@ module Reactions = /// Active Pattern to determine whether a given {category}-{streamId} StreamName represents the stream associated with this Aggregate /// Yields a strongly typed id from the streamId if the Category matches - let [] (|For|_|) = Stream.tryDecode + let [] (|For|_|) = Stream.decode let private dec = Streams.codec /// Yields decoded events and relevant strongly typed ids if the Category of the Stream Name matches diff --git a/tests/FsCodec.SystemTextJson.Tests/InteropTests.fs b/tests/FsCodec.SystemTextJson.Tests/InteropTests.fs index 091db447..611ec4f9 100644 --- a/tests/FsCodec.SystemTextJson.Tests/InteropTests.fs +++ b/tests/FsCodec.SystemTextJson.Tests/InteropTests.fs @@ -20,7 +20,7 @@ let [] ``encodes correctly`` () = test <@ res.Contains """"d":{"embed":"\""}""" @> let des = JsonConvert.DeserializeObject(res) let loaded = FsCodec.Core.TimelineEvent.Create(-1L, des.e[0].c, ReadOnlyMemory des.e[0].d) - let decoded = indirectCodec.TryDecode loaded |> ValueOption.get + let decoded = indirectCodec.Decode loaded |> ValueOption.get input =! decoded type EmbeddedString = { embed : string } @@ -44,5 +44,5 @@ let [] ``round-trips diverse bodies correctly`` (x: U, encodeDirect, d let ser = JsonConvert.SerializeObject(e, defaultSettings) let des = JsonConvert.DeserializeObject(ser, defaultSettings) let loaded = FsCodec.Core.TimelineEvent.Create(-1L, des.e[0].c, ReadOnlyMemory des.e[0].d) - let decoded = decoder.TryDecode loaded |> ValueOption.get + let decoded = decoder.Decode loaded |> ValueOption.get x =! decoded diff --git a/tests/FsCodec.Tests/CompressionTests.fs b/tests/FsCodec.Tests/CompressionTests.fs index 45e94365..7fcb07da 100644 --- a/tests/FsCodec.Tests/CompressionTests.fs +++ b/tests/FsCodec.Tests/CompressionTests.fs @@ -7,7 +7,7 @@ open Xunit let inline roundtrip (sut : FsCodec.IEventCodec<_, _, _>) value = let encoded = sut.Encode((), value = value) let loaded = FsCodec.Core.TimelineEvent.Create(-1L, encoded) - sut.TryDecode loaded + sut.Decode loaded (* Base Fixture Round-trips a String encoded as ReadOnlyMemory UTF-8 blob *) @@ -18,8 +18,8 @@ module StringUtf8 = let dec (b : ReadOnlySpan) : string = System.Text.Encoding.UTF8.GetString b let stringUtf8Encoder = let encode e = struct (eventType, enc e) - let tryDecode s (b : ReadOnlyMemory) = if s = eventType then ValueSome (dec b.Span) else invalidOp "Invalid eventType value" - FsCodec.Codec.Create(encode, tryDecode) + let decode s (b : ReadOnlyMemory) = if s = eventType then ValueSome (dec b.Span) else invalidOp "Invalid eventType value" + FsCodec.Codec.Create(encode, decode) let sut = stringUtf8Encoder