diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index ee4bb5e..3cf5904 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
- dotnet-version: 6.0.x
+ dotnet-version: 7.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
diff --git a/CSharpTypes/CSharpTypes.csproj b/CSharpTypes/CSharpTypes.csproj
index 4fda753..e6e0601 100644
--- a/CSharpTypes/CSharpTypes.csproj
+++ b/CSharpTypes/CSharpTypes.csproj
@@ -1,9 +1,9 @@
- net6.0
+ net7.0
-
\ No newline at end of file
+
diff --git a/CSharpTypes/OrderId.cs b/CSharpTypes/OrderId.cs
index 0e1cac3..016ecd2 100644
--- a/CSharpTypes/OrderId.cs
+++ b/CSharpTypes/OrderId.cs
@@ -1,6 +1,7 @@
using Newtonsoft.Json;
using Saithe;
using System;
+using System.Diagnostics.CodeAnalysis;
namespace CSharpTypes
{
@@ -8,7 +9,7 @@ namespace CSharpTypes
/// Order identifier, simple wrapper around long value. Since it wraps long we need to use the JsonConverter
///
[JsonConverter(typeof(ParseTypeJsonConverter))]
- public struct OrderId : IEquatable
+ public struct OrderId : IEquatable, IParsable
{
public readonly long Value;
@@ -38,7 +39,7 @@ public override string ToString()
{
return Value.ToString();
}
- public static bool TryParse(string str, out OrderId result)
+ private static bool TryParse(string str, out OrderId result)
{
result = Empty;
if (string.IsNullOrEmpty(str))
@@ -53,12 +54,16 @@ public static bool TryParse(string str, out OrderId result)
}
return false;
}
- public static OrderId Parse(string str)
+ private static OrderId Parse(string str)
{
OrderId res;
if (TryParse(str, out res))
return res;
throw new Exception("Could not parse product id");
}
+
+ public static OrderId Parse(string s, IFormatProvider provider) => Parse(s);
+
+ public static bool TryParse([NotNullWhen(true)] string s, IFormatProvider provider, [MaybeNullWhen(false)] out OrderId result) => TryParse(s, out result);
}
}
diff --git a/CSharpTypes/ParseValueType.cs b/CSharpTypes/ParseValueType.cs
index ed8aa63..c7b9f1c 100644
--- a/CSharpTypes/ParseValueType.cs
+++ b/CSharpTypes/ParseValueType.cs
@@ -1,11 +1,12 @@
-using System;
+using System;
using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
using Saithe;
namespace CSharpTypes
{
[TypeConverter(typeof(ParseTypeConverter))]
- public class ParseValueType : IEquatable
+ public class ParseValueType : IEquatable, IParsable
{
public readonly string Value;
@@ -26,7 +27,7 @@ public static ParseValueType Parse(string value)
public override bool Equals(object obj)
{
return Value.Equals(obj as ParseValueType);
- }
+ }
public override int GetHashCode()
{
return Value.GetHashCode();
@@ -34,8 +35,21 @@ public override int GetHashCode()
public bool Equals(ParseValueType other)
{
- if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(null, other)) return false;
return Value.Equals(other.Value);
}
+
+ public static ParseValueType Parse(string s, IFormatProvider provider) => Parse(s);
+
+ public static bool TryParse([NotNullWhen(true)] string s, IFormatProvider provider, [MaybeNullWhen(false)] out ParseValueType result)
+ {
+ try{
+ result = Parse(s);
+ return true;
+ }catch(Exception){
+ result = default;
+ return false;
+ }
+ }
}
}
diff --git a/CSharpTypes/ProductId.cs b/CSharpTypes/ProductId.cs
index 6b33d51..b7d3790 100644
--- a/CSharpTypes/ProductId.cs
+++ b/CSharpTypes/ProductId.cs
@@ -1,11 +1,12 @@
using System;
using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
using Saithe;
namespace CSharpTypes
{
[TypeConverter(typeof(ParseTypeConverter))]
- public struct ProductId: IEquatable
+ public struct ProductId: IEquatable, IParsable
{
public readonly long Value;
@@ -35,7 +36,7 @@ public override string ToString()
{
return $"ProductId/{Value}";
}
- public static bool TryParse(string str, out ProductId result)
+ private static bool TryParse(string str, out ProductId result)
{
result = Empty;
if (string.IsNullOrEmpty(str))
@@ -53,12 +54,16 @@ public static bool TryParse(string str, out ProductId result)
}
return false;
}
- public static ProductId Parse(string str)
+ private static ProductId Parse(string str)
{
ProductId res;
if (TryParse(str, out res))
return res;
throw new Exception("Could not parse product id");
}
+
+ public static ProductId Parse(string s, IFormatProvider provider) => Parse(s);
+
+ public static bool TryParse([NotNullWhen(true)] string s, IFormatProvider provider, [MaybeNullWhen(false)] out ProductId result) => TryParse(s, out result);
}
}
diff --git a/MvcApp/Models.fs b/MvcApp/Models.fs
index e4fc57c..44deaa0 100644
--- a/MvcApp/Models.fs
+++ b/MvcApp/Models.fs
@@ -27,29 +27,58 @@ let parseId prefix str =
| None -> raise (FormatException str)
[]
-[>)>]
+[)>]
type CustomerId =
{ Value : Guid }
static member Default : CustomerId = { Value=Guid.Empty }
static member Parse(str : string) : CustomerId = { Value = parseId "c-" str }
override this.ToString() = sprintf "c-%s" (toStr this.Value)
+ interface IParsable with
+ static member Parse(s:string, f:IFormatProvider) = CustomerId.Parse(s)
+ static member TryParse(s:string, f:IFormatProvider, result:byref) =
+ try
+ result <- CustomerId.Parse(s)
+ true
+ with _ ->
+ result <- Unchecked.defaultof<_>
+ false
+and private CustomerId_T1 = ParseTypeConverter
[]
-[>)>]
+[)>]
type ProductId =
{ Value : Guid }
static member Default : ProductId = { Value=Guid.Empty }
static member Parse(str : string) : ProductId = { Value = parseId "p-" str }
override this.ToString() = sprintf "p-%s" (toStr this.Value)
+ interface IParsable with
+ static member Parse(s:string, f:IFormatProvider) = ProductId.Parse(s)
+ static member TryParse(s:string, f:IFormatProvider, result:byref) =
+ try
+ result <- ProductId.Parse(s)
+ true
+ with _ ->
+ result <- Unchecked.defaultof<_>
+ false
+and private ProductId_T1 = ParseTypeConverter
[]
-[>)>]
+[)>]
type OrderId =
{ Value : Guid }
static member Default : OrderId = { Value=Guid.Empty }
static member Parse(str : string) : OrderId = { Value = parseId "o-" str }
override this.ToString() = sprintf "o-%s" (toStr this.Value)
-
+ interface IParsable with
+ static member Parse(s:string, f:IFormatProvider) = OrderId.Parse(s)
+ static member TryParse(s:string, f:IFormatProvider, result:byref) =
+ try
+ result <- OrderId.Parse(s)
+ true
+ with _ ->
+ result <- Unchecked.defaultof<_>
+ false
+and private OrderId_T1 = ParseTypeConverter
type Customer = {Id:CustomerId; FirstName:string ; LastName:string; Version:int}
diff --git a/MvcApp/MvcApp.fsproj b/MvcApp/MvcApp.fsproj
index 5d398ab..c6e56c2 100644
--- a/MvcApp/MvcApp.fsproj
+++ b/MvcApp/MvcApp.fsproj
@@ -1,6 +1,6 @@
- net6.0
+ net7.0
@@ -17,4 +17,4 @@
-
\ No newline at end of file
+
diff --git a/Saithe/ParseTypeConverters.fs b/Saithe/ParseTypeConverters.fs
index 987357c..f64e3c9 100644
--- a/Saithe/ParseTypeConverters.fs
+++ b/Saithe/ParseTypeConverters.fs
@@ -4,16 +4,18 @@ open System.ComponentModel
open System
open System.Reflection
open Newtonsoft.Json
+module internal MethodInfos=
+ let matchParse (t:MethodInfo) = t.Name<>null && (t.Name.Equals("Parse") || t.Name.EndsWith(".Parse")) && t.GetParameters().Length = 2
-type ParseTypeConverter<'T (*when 'T :> IParsable<'T>*) >() = //when 'T : (static member parse : string -> 'T)
+type ParseTypeConverter<'T when 'T :> IParsable<'T> >() =
inherit TypeConverter()
let strT = typeof
let t = typeof<'T>
- let parse_method = t.GetTypeInfo().GetMethod("Parse")
+ let parse_method = t.GetMethods() |> Array.find MethodInfos.matchParse
let parse s =
try
- box (parse_method.Invoke(null, [| s |]))
+ box (parse_method.Invoke(null, [| s; null |]))
with :? TargetInvocationException as e -> raise (e.GetBaseException())
override this.CanConvertFrom(context, sourceType) = (strT = sourceType || sourceType = t)
@@ -30,15 +32,15 @@ type ParseTypeConverter<'T (*when 'T :> IParsable<'T>*) >() = //when 'T : (stati
if destinationType = t then box (parse value)
else box (value.ToString())
-type public ParseTypeJsonConverter<'T>() =
+type public ParseTypeJsonConverter<'T when 'T :> IParsable<'T> >() =
inherit JsonConverter()
let t = typeof<'T>
- let parse_method = t.GetTypeInfo().GetMethod("Parse")
+ let parse_method = t.GetMethods() |> Array.find MethodInfos.matchParse
let parse s =
try
- box (parse_method.Invoke(null, [| s |]))
+ box (parse_method.Invoke(null, [| s ; null |]))
with :? TargetInvocationException as e -> raise (e.GetBaseException())
override this.CanConvert(objectType) = objectType = t
diff --git a/Saithe/Saithe.fsproj b/Saithe/Saithe.fsproj
index 60ac0a1..711cfc7 100644
--- a/Saithe/Saithe.fsproj
+++ b/Saithe/Saithe.fsproj
@@ -1,6 +1,6 @@
- netstandard2.0
+ net7.0
Saithe
wallymathieu
diff --git a/Tests/Handle_discriminated_union.fs b/Tests/Handle_discriminated_union.fs
index 2159a16..21ae781 100644
--- a/Tests/Handle_discriminated_union.fs
+++ b/Tests/Handle_discriminated_union.fs
@@ -7,9 +7,8 @@ open Newtonsoft.Json
open System.ComponentModel
open System.Globalization
-
-[>)>]
-[>)>]
+[)>]
+[)>]
type ParseValueType =
| ValueType of string
| Empty
@@ -24,6 +23,18 @@ type ParseValueType =
match this with
| Empty -> ""
| ValueType value -> sprintf "P_%s" value
+ interface IParsable with
+ static member Parse(s:string, f:IFormatProvider) = ParseValueType.Parse(s)
+ static member TryParse(s:string, f:IFormatProvider, result:byref) =
+ try
+ result <- ParseValueType.Parse(s)
+ true
+ with _ ->
+ result <- Unchecked.defaultof<_>
+ false
+and private ParseValueType_T1 = ParseTypeConverter
+and private ParseValueType_T2 = ParseTypeJsonConverter
+
[]
[]
diff --git a/Tests/Parse_fs_type.fs b/Tests/Parse_fs_type.fs
index 0000fff..ad139ea 100644
--- a/Tests/Parse_fs_type.fs
+++ b/Tests/Parse_fs_type.fs
@@ -6,7 +6,7 @@ open Newtonsoft.Json
open System.ComponentModel
open System.Globalization
-[>)>]
+[)>]
type ParseValueType={ Value:string }
with
static member Parse (str:string)=
@@ -15,6 +15,16 @@ with
| _ -> raise (FormatException str)
override this.ToString()=
sprintf "P_%s" this.Value
+ interface IParsable with
+ static member Parse(s:string, f:IFormatProvider) = ParseValueType.Parse(s)
+ static member TryParse(s:string, f:IFormatProvider, result:byref) =
+ try
+ result <- ParseValueType.Parse(s)
+ true
+ with _ ->
+ result <- Unchecked.defaultof<_>
+ false
+and private ParseValueType_T1 = ParseTypeConverter
[]
[]
diff --git a/Tests/Tests.fsproj b/Tests/Tests.fsproj
index 2b07e5f..c73bc48 100644
--- a/Tests/Tests.fsproj
+++ b/Tests/Tests.fsproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Tests
Tests
@@ -27,4 +27,4 @@
-
\ No newline at end of file
+
diff --git a/appveyor.yml b/appveyor.yml
index 9acad0f..d138369 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,6 @@
image: Visual Studio 2022
+install:
+ - cmd: choco install dotnetcore-sdk --pre -y
build_script:
- dotnet restore
diff --git a/global.json b/global.json
index 7ecd3c2..17a759e 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,7 @@
{
"sdk": {
- "version": "6.0.0",
- "rollForward": "latestFeature"
+ "version": "7.0.0",
+ "rollForward": "latestFeature",
+ "allowPrerelease": true
}
}