@@ -41,6 +41,7 @@ namespace FsCodec.Core
4141
4242open FsCodec
4343open System
44+ open System.ComponentModel
4445
4546/// <summary >An Event about to be written, see <c >IEventData</c > for further information.</summary >
4647[<NoComparison; NoEquality>]
@@ -61,16 +62,31 @@ type EventData<'Format>(eventType, data, meta, eventId, correlationId, causation
6162 member _.CausationId = causationId
6263 member _.Timestamp = timestamp
6364
64- static member Map < 'Mapped >( f : Func < 'Format , 'Mapped >)
65- ( x : IEventData < 'Format >): IEventData < 'Mapped > =
65+ static member MapBodies < 'Mapped >( f : Func < IEventData < 'Format > , 'Format , ' Mapped>): Func < IEventData < 'Format >, IEventData < 'Mapped >> =
66+ Func <_, _>( fun x ->
6667 { new IEventData< 'Mapped> with
6768 member _. EventType = x.EventType
68- member _.Data = f.Invoke x.Data
69- member _.Meta = f.Invoke x.Meta
69+ member _. Data = f.Invoke( x , x.Data)
70+ member _. Meta = f.Invoke( x , x.Meta)
7071 member _. EventId = x.EventId
7172 member _. CorrelationId = x.CorrelationId
7273 member _. CausationId = x.CausationId
73- member _.Timestamp = x.Timestamp }
74+ member _. Timestamp = x.Timestamp })
75+
76+ // Original ugly signature
77+ [<Obsolete " Superseded by MapBodies / EventData.mapBodies; more importantly, the original signature mixed F# and C# types so was messy in all contexts" ; EditorBrowsable( EditorBrowsableState.Never) >]
78+ static member Map < 'Mapped >( f : Func < 'Format , 'Mapped >) ( x : IEventData < 'Format >): IEventData < 'Mapped > =
79+ EventData.MapBodies( Func<_, _, _>( fun _x -> f.Invoke)) .Invoke( x)
80+
81+ /// F#-specific wrappers; for C#, use EventData.MapBodies directly
82+ // These helper modules may move up to the FsCodec namespace in V4, along with breaking changes moving IsUnfold and Context from ITimelineEvent to IEventData
83+ // If you have helpers that should be in the box alongside these, raise an Issue please
84+ module EventData =
85+
86+ let mapBodies_ < 'Format , 'Mapped > ( f : IEventData < 'Format > -> 'Format -> 'Mapped ) =
87+ EventData.MapBodies( Func< IEventData< 'Format>, 'Format, 'Mapped> f) .Invoke
88+ let mapBodies < 'Format , 'Mapped > ( f : 'Format -> 'Mapped ) =
89+ EventData.MapBodies( Func< IEventData< 'Format>, 'Format, 'Mapped>( fun _ -> f)) .Invoke
7490
7591/// <summary >An Event or Unfold that's been read from a Store and hence has a defined <c >Index</c > on the Event Timeline.</summary >
7692[<NoComparison; NoEquality>]
@@ -90,7 +106,7 @@ type TimelineEvent<'Format>(index, eventType, data, meta, eventId, correlationId
90106 TimelineEvent( index, inner.EventType, inner.Data, inner.Meta, inner.EventId, inner.CorrelationId, inner.CausationId, inner.Timestamp, isUnfold, Option.toObj context, size) :> _
91107
92108 override _.ToString () = sprintf " %s %s @%i " ( if isUnfold then " Unfold" else " Event" ) eventType index
93-
109+
94110 interface ITimelineEvent< 'Format> with
95111 member _.Index = index
96112 member _.IsUnfold = isUnfold
@@ -104,36 +120,66 @@ type TimelineEvent<'Format>(index, eventType, data, meta, eventId, correlationId
104120 member _.CausationId = causationId
105121 member _.Timestamp = timestamp
106122
107- static member Map < 'Mapped >( f : Func < 'Format , 'Mapped >)
108- ( x : ITimelineEvent < 'Format >): ITimelineEvent < 'Mapped > =
123+ static member MapBodies < 'Mapped >( f : Func < ITimelineEvent < 'Format > , 'Format , ' Mapped>): Func < ITimelineEvent < 'Format >, ITimelineEvent < 'Mapped >> =
124+ Func <_, _>( fun x ->
109125 { new ITimelineEvent< 'Mapped> with
110126 member _. Index = x.Index
111127 member _. IsUnfold = x.IsUnfold
112128 member _. Context = x.Context
113129 member _. Size = x.Size
114130 member _. EventType = x.EventType
115- member _.Data = f.Invoke x.Data
116- member _.Meta = f.Invoke x.Meta
131+ member _. Data = f.Invoke( x , x.Data)
132+ member _. Meta = f.Invoke( x , x.Meta)
117133 member _. EventId = x.EventId
118134 member _. CorrelationId = x.CorrelationId
119135 member _. CausationId = x.CausationId
120- member _.Timestamp = x.Timestamp }
136+ member _. Timestamp = x.Timestamp })
137+ // Original ugly signature
138+ [<Obsolete " Superseded by MapBodies / TimeLineEvent.mapBodies; more importantly, the original signature mixed F# and C# types so was messy in all contexts" ; EditorBrowsable( EditorBrowsableState.Never) >]
139+ static member Map < 'Mapped >( f : Func < 'Format , 'Mapped >) ( x : ITimelineEvent < 'Format >): ITimelineEvent < 'Mapped > =
140+ TimelineEvent.MapBodies( Func<_, _, _>( fun _x -> f.Invoke)) .Invoke( x)
141+
142+ /// F#-specific wrappers; for C#, use TimelineEvent.MapBodies directly
143+ module TimelineEvent =
144+
145+ let mapBodies_ < 'Format , 'Mapped > ( f : ITimelineEvent < 'Format > -> 'Format -> 'Mapped ) =
146+ TimelineEvent.MapBodies( Func< ITimelineEvent< 'Format>, 'Format, 'Mapped> f) .Invoke
147+ let mapBodies < 'Format , 'Mapped > ( f : 'Format -> 'Mapped ) =
148+ TimelineEvent.MapBodies( Func< ITimelineEvent< 'Format>, 'Format, 'Mapped>( fun _ -> f)) .Invoke
121149
122150[<AbstractClass; Sealed>]
123151type EventCodec < 'Event , 'Format , 'Context > private () =
124152
125- static member Map < 'TargetFormat >( native : IEventCodec < 'Event , 'Format , 'Context >, up : Func < 'Format , 'TargetFormat >, down : Func < 'TargetFormat , 'Format >)
153+ static member MapBodies < 'TargetFormat >(
154+ native : IEventCodec < 'Event , 'Format , 'Context >,
155+ up : Func < IEventData < 'Format >, 'Format , 'TargetFormat >,
156+ down : Func < 'TargetFormat , 'Format >)
126157 : IEventCodec < 'Event , 'TargetFormat , 'Context > =
127158
128- let upConvert = EventData.Map up
129- let downConvert = TimelineEvent.Map down
159+ let upConvert = EventData.MapBodies up
160+ let downConvert = TimelineEvent.MapBodies ( fun _ x -> down.Invoke x )
130161
131162 { new IEventCodec< 'Event, 'TargetFormat, 'Context> with
132163
133164 member _.Encode ( context , event ) =
134165 let encoded = native.Encode( context, event)
135- upConvert encoded
166+ upConvert.Invoke encoded
136167
137168 member _.Decode target =
138- let encoded = downConvert target
169+ let encoded = downConvert.Invoke target
139170 native.Decode encoded }
171+
172+ // NOTE To be be replaced by MapBodies/EventCodec.mapBodies for symmetry with TimelineEvent and EventData
173+ // TO BE be Obsoleted and whenever FsCodec.Box is next released
174+ [<EditorBrowsable( EditorBrowsableState.Never) >]
175+ static member Map < 'TargetFormat >( native : IEventCodec < 'Event , 'Format , 'Context >, up : Func < 'Format , 'TargetFormat >, down : Func < 'TargetFormat , 'Format >)
176+ : IEventCodec < 'Event , 'TargetFormat , 'Context > =
177+ EventCodec.MapBodies( native, Func<_, _, _>( fun _x -> up.Invoke), down)
178+
179+ /// F#-specific wrappers; for C#, use EventCodec.MapBodies directly
180+ module EventCodec =
181+
182+ let mapBodies_ ( up : IEventData < 'Format > -> 'Format -> 'TargetFormat ) ( down : 'TargetFormat -> 'Format ) x =
183+ EventCodec< 'Event, 'Format, 'Context>. MapBodies< 'TargetFormat>( x, up, down)
184+ let mapBodies ( up : 'Format -> 'TargetFormat ) ( down : 'TargetFormat -> 'Format ) x =
185+ EventCodec< 'Event, 'Format, 'Context>. MapBodies< 'TargetFormat>( x, Func<_, _, _>( fun _ -> up), down)
0 commit comments