From 4c25eca03c1da886c8ee6cd23acc18b619451655 Mon Sep 17 00:00:00 2001 From: Pierre Chalamet Date: Sat, 28 Dec 2024 10:20:11 +0100 Subject: [PATCH] add voption support --- .../Serialization/FSharpValueSerializer.fs | 1 + .../FSharpValueOptionSerializer.fs | 44 ++++++++++ .../FSharpValueOptionSerializationTests.fs | 83 +++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 src/FSharp.MongoDB.Bson/Serialization/Serializers/FSharpValueOptionSerializer.fs create mode 100644 tests/FSharp.MongoDB.Bson.Tests/FSharpValueOptionSerializationTests.fs diff --git a/src/FSharp.MongoDB.Bson/Serialization/FSharpValueSerializer.fs b/src/FSharp.MongoDB.Bson/Serialization/FSharpValueSerializer.fs index 1ad09ee..07b6c92 100644 --- a/src/FSharp.MongoDB.Bson/Serialization/FSharpValueSerializer.fs +++ b/src/FSharp.MongoDB.Bson/Serialization/FSharpValueSerializer.fs @@ -45,6 +45,7 @@ module FSharpValueSerializer = match typ with | IsList typ -> Some (mkGenericUsingDef> typ) | IsMap typ -> Some (mkGenericUsingDef> typ) + | IsValueOption typ -> Some (mkGenericUsingDef> typ) | IsOption typ -> Some (mkGenericUsingDef> typ) | IsSet typ -> Some (mkGenericUsingDef> typ) | IsUnion typ -> Some (mkGeneric> [| typ |]) diff --git a/src/FSharp.MongoDB.Bson/Serialization/Serializers/FSharpValueOptionSerializer.fs b/src/FSharp.MongoDB.Bson/Serialization/Serializers/FSharpValueOptionSerializer.fs new file mode 100644 index 0000000..8d6af4a --- /dev/null +++ b/src/FSharp.MongoDB.Bson/Serialization/Serializers/FSharpValueOptionSerializer.fs @@ -0,0 +1,44 @@ +(* Copyright (c) 2013 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *) + +namespace FSharp.MongoDB.Bson.Serialization.Serializers + +open System.Diagnostics +open MongoDB.Bson +open MongoDB.Bson.Serialization +open MongoDB.Bson.Serialization.Serializers + +/// +/// Serializer for F# voption types that writes the value in the ValueSome case and null in +/// the None case. +/// +type FSharpValueOptionSerializer<'T>() = + inherit SerializerBase<'T voption>() + + let serializer = lazy (BsonSerializer.LookupSerializer<'T>()) + + override _.Serialize (context, args, value) = + let writer = context.Writer + + match value with + | ValueSome x -> serializer.Value.Serialize(context, args, x :> obj) + | ValueNone -> writer.WriteNull() + + override _.Deserialize (context, args) = + let reader = context.Reader + + match reader.GetCurrentBsonType() with + | BsonType.Null -> reader.ReadNull(); ValueNone + | _ -> ValueSome (serializer.Value.Deserialize(context, args)) \ No newline at end of file diff --git a/tests/FSharp.MongoDB.Bson.Tests/FSharpValueOptionSerializationTests.fs b/tests/FSharp.MongoDB.Bson.Tests/FSharpValueOptionSerializationTests.fs new file mode 100644 index 0000000..3939a37 --- /dev/null +++ b/tests/FSharp.MongoDB.Bson.Tests/FSharpValueOptionSerializationTests.fs @@ -0,0 +1,83 @@ +(* Copyright (c) 2015 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *) + +namespace FSharp.MongoDB.Bson.Tests.Serialization + +open MongoDB.Bson + +open FsUnit +open NUnit.Framework + +module FSharpOptionSerialization = + + type Primitive = + { Bool : bool option + Int : int option + String : string option + Float : float option } + + [] + let ``test serialize optional primitives (none) in a record type``() = + let value = { Bool = None + Int = None + String = None + Float = None } + + let result = serialize value + let expected = BsonDocument() + + result |> should equal expected + + [] + let ``test deserialize optional primitives (none) in a record type)``() = + let doc = BsonDocument() + + let result = deserialize doc typeof + let expected = { Bool = None + Int = None + String = None + Float = None } + + result |> should equal expected + + [] + let ``test serialize optional primitives (some) in a record type``() = + let value = { Bool = Some false + Int = Some 0 + String = Some "0.0" + Float = Some 0.0 } + + let result = serialize value + let expected = BsonDocument([ BsonElement("Bool", BsonBoolean false) + BsonElement("Int", BsonInt32 0) + BsonElement("String", BsonString "0.0") + BsonElement("Float", BsonDouble 0.0) ]) + + result |> should equal expected + + [] + let ``test deserialize optional primitives (some) in a record type``() = + let doc = BsonDocument([ BsonElement("Bool", BsonBoolean true) + BsonElement("Int", BsonInt32 1) + BsonElement("String", BsonString "1.0") + BsonElement("Float", BsonDouble 1.0) ]) + + let result = deserialize doc typeof + let expected = { Bool = Some true + Int = Some 1 + String = Some "1.0" + Float = Some 1.0 } + + result |> should equal expected