Skip to content

Instantly share code, notes, and snippets.

@ArtemyB
Last active September 27, 2022 18:37
Show Gist options
  • Save ArtemyB/bf89fc22132f5caee4079f6dced736d2 to your computer and use it in GitHub Desktop.
Save ArtemyB/bf89fc22132f5caee4079f6dced736d2 to your computer and use it in GitHub Desktop.
System.Text.Json-based F#-friendly serialization configuration for ArangoDBNetStandard
module ArangoDBNetStandardFSharpSystemTextJsonSerialization
open System
open System.IO
module SystemTextJson =
open System.Text.Json
open System.Text.Json.Serialization
let UpperCaseNamingPolicy =
{ new JsonNamingPolicy() with
override this.ConvertName(name) = name.ToUpper() }
let ArangoCamelCaseNamingPolicy = {
new JsonNamingPolicy() with
member this.ConvertName(name) =
match name with
| "Id" -> "_id"
| "Key" -> "_key"
| "Revision" -> "_rev"
| "From" -> "_from"
| "To" -> "_to"
| _ -> JsonNamingPolicy.CamelCase.ConvertName(name)
}
let defaultUnionEncoding =
JsonUnionEncoding.Default
||| JsonUnionEncoding.ExternalTag
||| JsonUnionEncoding.UnwrapSingleFieldCases
||| JsonUnionEncoding.UnwrapRecordCases
||| JsonUnionEncoding.UnwrapFieldlessTags
let fsharpConverter (additionalOverrides: seq<Type * JsonFSharpOptions>) =
JsonFSharpConverter(
unionEncoding = defaultUnionEncoding,
unionTagCaseInsensitive = true,
allowNullFields = false,
overrides = dict additionalOverrides
)
let initSerializerOptions (additionalFSharpConverterOverrides: seq<Type * JsonFSharpOptions>) =
let o = new JsonSerializerOptions(JsonSerializerDefaults.Web)
o.PropertyNameCaseInsensitive <- true
o.DefaultIgnoreCondition <- JsonIgnoreCondition.WhenWritingDefault
o.NumberHandling <- JsonNumberHandling.AllowReadingFromString
o.PropertyNamingPolicy <- ArangoCamelCaseNamingPolicy
let fsharpConverter = fsharpConverter additionalFSharpConverterOverrides
o.Converters.Add(fsharpConverter)
o
let serializerOptions =
initSerializerOptions []
let deserializeFromStream (stream: Stream) (serializerOptions: JsonSerializerOptions) : 'T =
if isNull stream && not stream.CanRead then
Unchecked.defaultof<'T>
else
JsonSerializer.Deserialize(stream, serializerOptions)
let serializeToBytes (data: 'T) (options: JsonSerializerOptions option) =
let o = defaultArg options serializerOptions
JsonSerializer.SerializeToUtf8Bytes(data, o)
let defaultSerialize (data: 'T) =
JsonSerializer.Serialize(data, serializerOptions)
let defaultSerializeUntypd (t: Type) (data: obj) =
JsonSerializer.Serialize(data, t, serializerOptions)
type DefaultSerializer =
static member Serialize(data: 'T) =
JsonSerializer.Serialize(data, serializerOptions)
static member Serialize(data: obj, t: Type) =
JsonSerializer.Serialize(data, t, serializerOptions)
static member Deserialize(jsonEl: JsonElement, t: Type) =
JsonSerializer.Deserialize(jsonEl, t, serializerOptions)
static member Deserialize(jsonString: string, t: Type) =
JsonSerializer.Deserialize(jsonString, t, serializerOptions)
open ArangoDBNetStandard.Serialization
let systemTextJsonApiClientSerialization (serializerOptions: System.Text.Json.JsonSerializerOptions) =
{ new IApiClientSerialization with
member this.DeserializeFromStream(stream: Stream) : 'T =
SystemTextJson.deserializeFromStream stream serializerOptions
member this.Serialize<'T>(data: 'T, serializationOptions: ApiClientSerializationOptions): byte [] =
SystemTextJson.serializeToBytes data (Some serializerOptions)
member this.SerializeToString<'T>(item: 'T, serializationOptions: ApiClientSerializationOptions): string =
SystemTextJson.DefaultSerializer.Serialize(item)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment