Skip to content

Commit 891cba7

Browse files
committed
start implementing isomorphic serialization between cs/fs
1 parent 4c6af3e commit 891cba7

File tree

8 files changed

+267
-1
lines changed

8 files changed

+267
-1
lines changed

CsDataModel/CsDataModel.csproj

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="MongoDB.Driver" Version="3.1.0" />
11+
</ItemGroup>
12+
13+
</Project>

CsDataModel/DataModel.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
namespace CsDataModel;
2+
using MongoDB.Bson;
3+
4+
public record Pair
5+
{
6+
public required int First { get; init; }
7+
public required string? Second { get; init; }
8+
}
9+
10+
11+
public record Value
12+
{
13+
public record IntValue(int Value) : Value;
14+
public record StringValue(string Value) : Value;
15+
public record PairValue(Pair Value) : Value;
16+
}
17+
18+
19+
public record RecordDataModel
20+
{
21+
public ObjectId Id { get; init; }
22+
23+
public required int Int { get; init; }
24+
public int? IntOpt { get; init; }
25+
26+
public required string String { get; init; }
27+
public string? StringOpt { get; init; }
28+
29+
public required int[] Array { get; init; }
30+
public int[]? ArrayOpt { get; init; }
31+
32+
public required Value Value { get; init; }
33+
public Value? ValueOpt { get; init; }
34+
35+
public required Value[] ValueArray { get; init; }
36+
public Value[]? ValueArrayOpt { get; init; }
37+
38+
public required Pair Record { get; init; }
39+
public Pair? RecordOpt { get; init; }
40+
41+
public required Dictionary<string, int> Map { get; init; }
42+
}

FSharp.MongoDB.Driver.Tests/FSharp.MongoDB.Driver.Tests.fsproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
<ItemGroup>
1010
<Compile Include="TestUtils.fs" />
1111
<Compile Include="Serializers.fs" />
12+
<Compile Include="Isomorphic.fs" />
1213
<Compile Include="AcceptanceTests.fs" />
1314
</ItemGroup>
1415

1516
<ItemGroup>
1617
<ProjectReference Include="..\FSharp.MongoDB.Driver\FSharp.MongoDB.Driver.fsproj" />
18+
<ProjectReference Include="..\CsDataModel\CsDataModel.csproj" />
19+
<ProjectReference Include="..\FsDataModel\FsDataModel.fsproj" />
1720
</ItemGroup>
1821

1922
<ItemGroup>
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
module FSharp.MongoDB.Driver.Isomorphic.Tests
2+
open MongoDB.Driver
3+
open FsUnit
4+
open NUnit.Framework
5+
open CsDataModel;
6+
open FsDataModel;
7+
open MongoDB.Bson
8+
9+
let mutable client: MongoClient = Unchecked.defaultof<MongoClient>
10+
let mutable db: IMongoDatabase = Unchecked.defaultof<IMongoDatabase>
11+
12+
[<OneTimeSetUp>]
13+
let init() =
14+
let connectionString = "mongodb://localhost"
15+
let dbname = "FSharp-MongoDB-Driver"
16+
client <- new MongoClient(connectionString)
17+
db <- client.GetDatabase(dbname)
18+
db.DropCollection("IsomophicDataModel")
19+
FSharp.MongoDB.Driver.Register()
20+
21+
[<OneTimeTearDown>]
22+
let teardown() =
23+
client.Dispose()
24+
25+
[<Test>]
26+
let ``Isomorphic Some``() =
27+
28+
let csModel =
29+
let map =
30+
let map = System.Collections.Generic.Dictionary<string, int>()
31+
map.Add("1", 1)
32+
map.Add("2", 2)
33+
map
34+
35+
RecordDataModel(
36+
Int = 42,
37+
IntOpt = 666,
38+
39+
String = "String",
40+
StringOpt = "StringOpt",
41+
42+
Array = [| 1; 2; 3 |],
43+
ArrayOpt = [| 5; 6; 7; 8 |],
44+
45+
Value = CsDataModel.Value.IntValue(42),
46+
ValueOpt = CsDataModel.Value.StringValue("ValueStringOpt"),
47+
48+
ValueArray = [| CsDataModel.Value.IntValue(42)
49+
CsDataModel.Value.StringValue("String")
50+
CsDataModel.Value.PairValue(CsDataModel.Pair(First = 99, Second = "SecondPair")) |],
51+
ValueArrayOpt = [| CsDataModel.Value.IntValue(101) |],
52+
53+
Record = CsDataModel.Pair(First = 1, Second = "Second"),
54+
RecordOpt = CsDataModel.Pair(First = -1, Second = "SecondOpt"),
55+
56+
Map = map)
57+
58+
59+
let fsModel =
60+
{ Id = ObjectId()
61+
62+
Int = 42
63+
IntOpt = Some 666
64+
65+
String = "String"
66+
StringOpt = Some "StringOpt"
67+
68+
Array = [| 1; 2; 3 |]
69+
ArrayOpt = Some [| 5; 6; 7; 8 |]
70+
71+
Value = Value.IntValue 42
72+
ValueOpt = Some <| Value.StringValue "ValueStringOpt"
73+
74+
ValueArray = [| Value.IntValue 42; Value.StringValue "String"; Value.PairValue { First = 99; Second = Some "SecondPair" } |]
75+
ValueArrayOpt = Some [| Value.IntValue 101 |]
76+
77+
Record = { First = 1; Second = Some "Second" }
78+
RecordOpt = Some { First = -1; Second = Some "SecondOpt" }
79+
80+
Map = Map [ "1", 1; "2", 2 ] }
81+
82+
let csCollection = db.GetCollection<CsDataModel.RecordDataModel> "IsomophicDataModel"
83+
csCollection.InsertOne(csModel)
84+
85+
let fsCollection = db.GetCollection<FsDataModel.RecordDataModel> "IsomophicDataModel"
86+
let fromDb = fsCollection.Find(fun x -> x.Id = csModel.Id).First()
87+
fromDb |> should equal fsModel
88+
89+
[<Test>]
90+
let ``Isomorphic None``() =
91+
92+
let csModel =
93+
let map =
94+
let map = System.Collections.Generic.Dictionary<string, int>()
95+
map.Add("1", 1)
96+
map.Add("2", 2)
97+
map
98+
99+
RecordDataModel(
100+
Int = 42,
101+
102+
String = "String",
103+
104+
Array = [| 1; 2; 3 |],
105+
106+
Value = CsDataModel.Value.IntValue(42),
107+
108+
ValueArray = [| CsDataModel.Value.IntValue(42)
109+
CsDataModel.Value.StringValue("String")
110+
CsDataModel.Value.PairValue(CsDataModel.Pair(First = 99, Second = "SecondPair")) |],
111+
112+
Record = CsDataModel.Pair(First = 1, Second = "Second"),
113+
114+
Map = map)
115+
116+
117+
let fsModel =
118+
{ Id = ObjectId()
119+
120+
Int = 42
121+
IntOpt = None
122+
123+
String = "String"
124+
StringOpt = None
125+
126+
Array = [| 1; 2; 3 |]
127+
ArrayOpt = None
128+
129+
Value = Value.IntValue 42
130+
ValueOpt = None
131+
132+
ValueArray = [| Value.IntValue 42; Value.StringValue "String"; Value.PairValue { First = 99; Second = Some "SecondPair" } |]
133+
ValueArrayOpt = None
134+
135+
Record = { First = 1; Second = Some "Second" }
136+
RecordOpt = None
137+
138+
Map = Map [ "1", 1; "2", 2 ] }
139+
140+
let csCollection = db.GetCollection<CsDataModel.RecordDataModel> "IsomophicDataModel"
141+
csCollection.InsertOne(csModel)
142+
143+
let fsCollection = db.GetCollection<FsDataModel.RecordDataModel> "IsomophicDataModel"
144+
let fromDb = fsCollection.Find(fun x -> x.Id = csModel.Id).First()
145+
fromDb |> should equal fsModel

FSharp.MongoDB.Driver.Tests/Serializers.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ let init() =
5353
let connectionString = "mongodb://localhost"
5454
let dbname = "FSharp-MongoDB-Driver"
5555
client <- new MongoClient(connectionString)
56-
client.DropDatabase(dbname)
5756
db <- client.GetDatabase(dbname)
57+
db.DropCollection("CollectionItem")
5858
FSharp.MongoDB.Driver.Register()
5959

6060
[<OneTimeTearDown>]

FsDataModel/DataModel.fs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
namespace FsDataModel
2+
open MongoDB.Bson;
3+
4+
type Pair =
5+
{ First: int
6+
Second: string option }
7+
8+
[<RequireQualifiedAccess>]
9+
type Value =
10+
| IntValue of Value:int
11+
| StringValue of Value: string
12+
| PairValue of Value:Pair
13+
14+
type RecordDataModel =
15+
{ Id: ObjectId
16+
17+
Int: int
18+
IntOpt: int option
19+
20+
String: string
21+
StringOpt: string option
22+
23+
Array: int array
24+
ArrayOpt: int array option
25+
26+
Value: Value
27+
ValueOpt: Value option
28+
29+
ValueArray: Value array
30+
ValueArrayOpt: Value array option
31+
32+
Record: Pair
33+
RecordOpt: Pair option
34+
35+
Map: Map<string, int> }

FsDataModel/FsDataModel.fsproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Include="DataModel.fs" />
10+
</ItemGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="MongoDB.Driver" Version="3.1.0" />
14+
</ItemGroup>
15+
16+
</Project>

MongoDB.Driver.FSharp.sln

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.MongoDB.Driver", "FS
1414
EndProject
1515
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.MongoDB.Driver.Tests", "FSharp.MongoDB.Driver.Tests\FSharp.MongoDB.Driver.Tests.fsproj", "{DE725DAC-C637-4DA7-A30D-69061D33D1B2}"
1616
EndProject
17+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsDataModel", "CsDataModel\CsDataModel.csproj", "{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}"
18+
EndProject
19+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsDataModel", "FsDataModel\FsDataModel.fsproj", "{2CDD99F6-79F9-446A-9954-EA675C7380E6}"
20+
EndProject
1721
Global
1822
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1923
Debug|Any CPU = Debug|Any CPU
@@ -28,6 +32,14 @@ Global
2832
{DE725DAC-C637-4DA7-A30D-69061D33D1B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
2933
{DE725DAC-C637-4DA7-A30D-69061D33D1B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
3034
{DE725DAC-C637-4DA7-A30D-69061D33D1B2}.Release|Any CPU.Build.0 = Release|Any CPU
35+
{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36+
{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
37+
{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
38+
{F46BAC39-2436-4EC4-B376-CE8AAA206B6D}.Release|Any CPU.Build.0 = Release|Any CPU
39+
{2CDD99F6-79F9-446A-9954-EA675C7380E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40+
{2CDD99F6-79F9-446A-9954-EA675C7380E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
41+
{2CDD99F6-79F9-446A-9954-EA675C7380E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
42+
{2CDD99F6-79F9-446A-9954-EA675C7380E6}.Release|Any CPU.Build.0 = Release|Any CPU
3143
EndGlobalSection
3244
GlobalSection(SolutionProperties) = preSolution
3345
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)