Skip to content

Commit

Permalink
start implementing isomorphic serialization between cs/fs
Browse files Browse the repository at this point in the history
  • Loading branch information
pchalamet committed Dec 26, 2024
1 parent 4c6af3e commit 891cba7
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 1 deletion.
13 changes: 13 additions & 0 deletions CsDataModel/CsDataModel.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MongoDB.Driver" Version="3.1.0" />
</ItemGroup>

</Project>
42 changes: 42 additions & 0 deletions CsDataModel/DataModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace CsDataModel;
using MongoDB.Bson;

public record Pair
{
public required int First { get; init; }
public required string? Second { get; init; }
}


public record Value
{
public record IntValue(int Value) : Value;
public record StringValue(string Value) : Value;
public record PairValue(Pair Value) : Value;
}


public record RecordDataModel
{
public ObjectId Id { get; init; }

public required int Int { get; init; }
public int? IntOpt { get; init; }

public required string String { get; init; }
public string? StringOpt { get; init; }

public required int[] Array { get; init; }
public int[]? ArrayOpt { get; init; }

public required Value Value { get; init; }
public Value? ValueOpt { get; init; }

public required Value[] ValueArray { get; init; }
public Value[]? ValueArrayOpt { get; init; }

public required Pair Record { get; init; }
public Pair? RecordOpt { get; init; }

public required Dictionary<string, int> Map { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
<ItemGroup>
<Compile Include="TestUtils.fs" />
<Compile Include="Serializers.fs" />
<Compile Include="Isomorphic.fs" />
<Compile Include="AcceptanceTests.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\FSharp.MongoDB.Driver\FSharp.MongoDB.Driver.fsproj" />
<ProjectReference Include="..\CsDataModel\CsDataModel.csproj" />
<ProjectReference Include="..\FsDataModel\FsDataModel.fsproj" />
</ItemGroup>

<ItemGroup>
Expand Down
145 changes: 145 additions & 0 deletions FSharp.MongoDB.Driver.Tests/Isomorphic.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
module FSharp.MongoDB.Driver.Isomorphic.Tests
open MongoDB.Driver
open FsUnit
open NUnit.Framework
open CsDataModel;
open FsDataModel;
open MongoDB.Bson

let mutable client: MongoClient = Unchecked.defaultof<MongoClient>
let mutable db: IMongoDatabase = Unchecked.defaultof<IMongoDatabase>

[<OneTimeSetUp>]
let init() =
let connectionString = "mongodb://localhost"
let dbname = "FSharp-MongoDB-Driver"
client <- new MongoClient(connectionString)
db <- client.GetDatabase(dbname)
db.DropCollection("IsomophicDataModel")
FSharp.MongoDB.Driver.Register()

[<OneTimeTearDown>]
let teardown() =
client.Dispose()

[<Test>]
let ``Isomorphic Some``() =

let csModel =
let map =
let map = System.Collections.Generic.Dictionary<string, int>()
map.Add("1", 1)
map.Add("2", 2)
map

RecordDataModel(
Int = 42,
IntOpt = 666,

String = "String",
StringOpt = "StringOpt",

Array = [| 1; 2; 3 |],
ArrayOpt = [| 5; 6; 7; 8 |],

Value = CsDataModel.Value.IntValue(42),
ValueOpt = CsDataModel.Value.StringValue("ValueStringOpt"),

ValueArray = [| CsDataModel.Value.IntValue(42)
CsDataModel.Value.StringValue("String")
CsDataModel.Value.PairValue(CsDataModel.Pair(First = 99, Second = "SecondPair")) |],
ValueArrayOpt = [| CsDataModel.Value.IntValue(101) |],

Record = CsDataModel.Pair(First = 1, Second = "Second"),
RecordOpt = CsDataModel.Pair(First = -1, Second = "SecondOpt"),

Map = map)


let fsModel =
{ Id = ObjectId()

Int = 42
IntOpt = Some 666

String = "String"
StringOpt = Some "StringOpt"

Array = [| 1; 2; 3 |]
ArrayOpt = Some [| 5; 6; 7; 8 |]

Value = Value.IntValue 42
ValueOpt = Some <| Value.StringValue "ValueStringOpt"

ValueArray = [| Value.IntValue 42; Value.StringValue "String"; Value.PairValue { First = 99; Second = Some "SecondPair" } |]
ValueArrayOpt = Some [| Value.IntValue 101 |]

Record = { First = 1; Second = Some "Second" }
RecordOpt = Some { First = -1; Second = Some "SecondOpt" }

Map = Map [ "1", 1; "2", 2 ] }

let csCollection = db.GetCollection<CsDataModel.RecordDataModel> "IsomophicDataModel"
csCollection.InsertOne(csModel)

let fsCollection = db.GetCollection<FsDataModel.RecordDataModel> "IsomophicDataModel"
let fromDb = fsCollection.Find(fun x -> x.Id = csModel.Id).First()
fromDb |> should equal fsModel

[<Test>]
let ``Isomorphic None``() =

let csModel =
let map =
let map = System.Collections.Generic.Dictionary<string, int>()
map.Add("1", 1)
map.Add("2", 2)
map

RecordDataModel(
Int = 42,

String = "String",

Array = [| 1; 2; 3 |],

Value = CsDataModel.Value.IntValue(42),

ValueArray = [| CsDataModel.Value.IntValue(42)
CsDataModel.Value.StringValue("String")
CsDataModel.Value.PairValue(CsDataModel.Pair(First = 99, Second = "SecondPair")) |],

Record = CsDataModel.Pair(First = 1, Second = "Second"),

Map = map)


let fsModel =
{ Id = ObjectId()

Int = 42
IntOpt = None

String = "String"
StringOpt = None

Array = [| 1; 2; 3 |]
ArrayOpt = None

Value = Value.IntValue 42
ValueOpt = None

ValueArray = [| Value.IntValue 42; Value.StringValue "String"; Value.PairValue { First = 99; Second = Some "SecondPair" } |]
ValueArrayOpt = None

Record = { First = 1; Second = Some "Second" }
RecordOpt = None

Map = Map [ "1", 1; "2", 2 ] }

let csCollection = db.GetCollection<CsDataModel.RecordDataModel> "IsomophicDataModel"
csCollection.InsertOne(csModel)

let fsCollection = db.GetCollection<FsDataModel.RecordDataModel> "IsomophicDataModel"
let fromDb = fsCollection.Find(fun x -> x.Id = csModel.Id).First()
fromDb |> should equal fsModel
2 changes: 1 addition & 1 deletion FSharp.MongoDB.Driver.Tests/Serializers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ let init() =
let connectionString = "mongodb://localhost"
let dbname = "FSharp-MongoDB-Driver"
client <- new MongoClient(connectionString)
client.DropDatabase(dbname)
db <- client.GetDatabase(dbname)
db.DropCollection("CollectionItem")
FSharp.MongoDB.Driver.Register()

[<OneTimeTearDown>]
Expand Down
35 changes: 35 additions & 0 deletions FsDataModel/DataModel.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace FsDataModel
open MongoDB.Bson;

type Pair =
{ First: int
Second: string option }

[<RequireQualifiedAccess>]
type Value =
| IntValue of Value:int
| StringValue of Value: string
| PairValue of Value:Pair

type RecordDataModel =
{ Id: ObjectId

Int: int
IntOpt: int option

String: string
StringOpt: string option

Array: int array
ArrayOpt: int array option

Value: Value
ValueOpt: Value option

ValueArray: Value array
ValueArrayOpt: Value array option

Record: Pair
RecordOpt: Pair option

Map: Map<string, int> }
16 changes: 16 additions & 0 deletions FsDataModel/FsDataModel.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<Compile Include="DataModel.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="MongoDB.Driver" Version="3.1.0" />
</ItemGroup>

</Project>
12 changes: 12 additions & 0 deletions MongoDB.Driver.FSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.MongoDB.Driver", "FS
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.MongoDB.Driver.Tests", "FSharp.MongoDB.Driver.Tests\FSharp.MongoDB.Driver.Tests.fsproj", "{DE725DAC-C637-4DA7-A30D-69061D33D1B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsDataModel", "CsDataModel\CsDataModel.csproj", "{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsDataModel", "FsDataModel\FsDataModel.fsproj", "{2CDD99F6-79F9-446A-9954-EA675C7380E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -28,6 +32,14 @@ Global
{DE725DAC-C637-4DA7-A30D-69061D33D1B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE725DAC-C637-4DA7-A30D-69061D33D1B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE725DAC-C637-4DA7-A30D-69061D33D1B2}.Release|Any CPU.Build.0 = Release|Any CPU
{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}.Release|Any CPU.Build.0 = Release|Any CPU
{2CDD99F6-79F9-446A-9954-EA675C7380E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2CDD99F6-79F9-446A-9954-EA675C7380E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CDD99F6-79F9-446A-9954-EA675C7380E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CDD99F6-79F9-446A-9954-EA675C7380E6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 891cba7

Please sign in to comment.