From adc7e06db6c57495a693be9be7ba21667923fd09 Mon Sep 17 00:00:00 2001 From: alexinea Date: Wed, 25 Dec 2019 16:27:30 +0800 Subject: [PATCH 01/15] Update Cosmos.Extensions.Optionals. --- .../Cosmos.Extensions.Optionals.csproj | 6 +- .../Cosmos.Extensions.Optionals.xml | 581 +++++++++++++++--- .../Cosmos/Optionals/NamedOptionalBuilder.cs | 220 +++++++ .../Cosmos/Optionals/Optional.MaybeT.cs | 360 +++++++++++ .../Cosmos/Optionals/Optional.Named.cs | 14 + .../Cosmos/Optionals/Optional.Wrapped.cs | 110 ++++ 6 files changed, 1209 insertions(+), 82 deletions(-) create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/NamedOptionalBuilder.cs create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.MaybeT.cs create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Named.cs create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Wrapped.cs diff --git a/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.csproj b/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.csproj index c31ef258..6f0841ea 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.csproj +++ b/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.csproj @@ -1,6 +1,6 @@  - + netstandard2.1;netstandard2.0;net461;net451 @@ -13,10 +13,10 @@ - + - + \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.xml b/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.xml index 9af3e883..c745671b 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.xml +++ b/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.xml @@ -2073,6 +2073,11 @@ + + + Hashcode for key + + @@ -2377,6 +2382,32 @@ + + + Index + + + + + + Index + + + + + + Deconstruct + + + + + + + Deconstruct + + + + @@ -2591,6 +2622,34 @@ + + + Index + + + + + + Index + + + + + + Deconstruct + + + + + + + + Deconstruct + + + + + @@ -2811,6 +2870,36 @@ + + + Index + + + + + + Index + + + + + + Deconstruct + + + + + + + + + Deconstruct + + + + + + @@ -3037,6 +3126,38 @@ + + + Index + + + + + + Index + + + + + + Deconstruct + + + + + + + + + + Deconstruct + + + + + + + @@ -3269,6 +3390,40 @@ + + + Index + + + + + + Index + + + + + + Deconstruct + + + + + + + + + + + Deconstruct + + + + + + + + @@ -3507,6 +3662,42 @@ + + + Index + + + + + + Index + + + + + + Deconstruct + + + + + + + + + + + + Deconstruct + + + + + + + + + @@ -3667,6 +3858,224 @@ Nothing + + + Named optional builder + + + + + Create the named optional builder + + + + + + + + + + + + Interface for named optional builder + + + + + May + + + + + + + + May + + + + + + + + + Interface for named optional builder + + + + + May + + + + + + + + May + + + + + + + + + Build + + + + + + Interface for named optional builder + + + + + May + + + + + + + + May + + + + + + + + + Build + + + + + + Interface for named optional builder + + + + + May + + + + + + + + May + + + + + + + + + Build + + + + + + Interface for named optional builder + + + + + May + + + + + + + + May + + + + + + + + + Build + + + + + + Interface for named optional builder + + + + + May + + + + + + + + May + + + + + + + + + Build + + + + + + Interface for named optional builder + + + + + May + + + + + + + + May + + + + + + + + + Build + + + + + + Interface for named optional builder + + + + + Build + + + None @@ -3809,6 +4218,15 @@ Optional utilities + + Optional utilities + + + Optional utilities + + + Optional utilities + @@ -3887,85 +4305,6 @@ - - - Wrapped optional - - - - - For some value - - - - - - - - For some value - - - - - - - - - For nothing - - - - - - - For nothing - - - - - - - - For nothing - - - - - - - For nothing - - - - - - - - - Create an instance of from the given value. - - - - - - - - Create an instance of from the given value. - - - - - - - - - - Create an instance of from the given value. - - - - - Some @@ -4278,6 +4617,90 @@ + + + Get an instance of builder, to build a named Maybe. + + + + + Wrapped optional + + + + + For some value + + + + + + + + For some value + + + + + + + + + For nothing + + + + + + + For nothing + + + + + + + + For nothing + + + + + + + For nothing + + + + + + + + + Create an instance of from the given value. + + + + + + + + Create an instance of from the given value. + + + + + + + + + + Create an instance of from the given value. + + + + + Optional type diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/NamedOptionalBuilder.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/NamedOptionalBuilder.cs new file mode 100644 index 00000000..8514dc82 --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/NamedOptionalBuilder.cs @@ -0,0 +1,220 @@ +using Cosmos.Optionals.Internals; +using Cosmos.Optionals.NamedOptionals; + +namespace Cosmos.Optionals { + /// + /// Named optional builder + /// + public class NamedOptionalBuilder : INamedOptionalBuilder { + private NamedOptionalBuilder() { } + + /// + /// Create the named optional builder + /// + /// + public static NamedOptionalBuilder Create() => new NamedOptionalBuilder(); + + /// + public INamedOptionalBuilder May(T value) { + return new NamedOptionalLevel1Builder(value, NamedMaybeConstants.KEY); + } + + /// + public INamedOptionalBuilder May(T value, string key) { + return new NamedOptionalLevel1Builder(value, key); + } + + internal class NamedOptionalLevel1Builder : INamedOptionalBuilder { + private readonly OptionalHold _hold1; + + public NamedOptionalLevel1Builder(T value, string key) { + _hold1 = new OptionalHold(value, key); + } + + public INamedOptionalBuilder May(T2 value) { + return new NamedOptionalLevel2Builder(_hold1, value, NamedMaybeConstants.KEY2); + } + + public INamedOptionalBuilder May(T2 value, string key) { + return new NamedOptionalLevel2Builder(_hold1, value, key); + } + + public Maybe Build() { + return new Maybe(_hold1.Value, _hold1.Key, true); + } + } + + internal class NamedOptionalLevel2Builder : INamedOptionalBuilder { + private readonly OptionalHold _hold1; + private readonly OptionalHold _hold2; + + public NamedOptionalLevel2Builder(OptionalHold hold1, T2 value, string key) { + _hold1 = hold1; + _hold2 = new OptionalHold(value, key); + } + + public INamedOptionalBuilder May(T3 value) { + return new NamedOptionalLevel3Builder(_hold1, _hold2, value, NamedMaybeConstants.KEY3); + } + + public INamedOptionalBuilder May(T3 value, string key) { + return new NamedOptionalLevel3Builder(_hold1, _hold2, value, key); + } + + public Maybe Build() { + return new Maybe(_hold1, _hold2); + } + } + + internal class NamedOptionalLevel3Builder : INamedOptionalBuilder { + private readonly OptionalHold _hold1; + private readonly OptionalHold _hold2; + private readonly OptionalHold _hold3; + + public NamedOptionalLevel3Builder(OptionalHold hold1, OptionalHold hold2, T3 value, string key) { + _hold1 = hold1; + _hold2 = hold2; + _hold3 = new OptionalHold(value, key); + } + + public INamedOptionalBuilder May(T4 value) { + return new NamedOptionalLevel4Builder(_hold1, _hold2, _hold3, value, NamedMaybeConstants.KEY4); + } + + public INamedOptionalBuilder May(T4 value, string key) { + return new NamedOptionalLevel4Builder(_hold1, _hold2, _hold3, value, key); + } + + public Maybe Build() { + return new Maybe(_hold1, _hold2, _hold3); + } + } + + internal class NamedOptionalLevel4Builder : INamedOptionalBuilder { + private readonly OptionalHold _hold1; + private readonly OptionalHold _hold2; + private readonly OptionalHold _hold3; + private readonly OptionalHold _hold4; + + public NamedOptionalLevel4Builder(OptionalHold hold1, OptionalHold hold2, OptionalHold hold3, T4 value, string key) { + _hold1 = hold1; + _hold2 = hold2; + _hold3 = hold3; + _hold4 = new OptionalHold(value, key); + } + + public INamedOptionalBuilder May(T5 value) { + return new NamedOptionalLevel5Builder(_hold1, _hold2, _hold3, _hold4, value, NamedMaybeConstants.KEY5); + } + + public INamedOptionalBuilder May(T5 value, string key) { + return new NamedOptionalLevel5Builder(_hold1, _hold2, _hold3, _hold4, value, key); + } + + public Maybe Build() { + return new Maybe(_hold1, _hold2, _hold3, _hold4); + } + } + + internal class NamedOptionalLevel5Builder : INamedOptionalBuilder { + private readonly OptionalHold _hold1; + private readonly OptionalHold _hold2; + private readonly OptionalHold _hold3; + private readonly OptionalHold _hold4; + private readonly OptionalHold _hold5; + + public NamedOptionalLevel5Builder(OptionalHold hold1, OptionalHold hold2, OptionalHold hold3, OptionalHold hold4, T5 value, string key) { + _hold1 = hold1; + _hold2 = hold2; + _hold3 = hold3; + _hold4 = hold4; + _hold5 = new OptionalHold(value, key); + } + + public INamedOptionalBuilder May(T6 value) { + return new NamedOptionalLevel6Builder(_hold1, _hold2, _hold3, _hold4, _hold5, value, NamedMaybeConstants.KEY6); + } + + public INamedOptionalBuilder May(T6 value, string key) { + return new NamedOptionalLevel6Builder(_hold1, _hold2, _hold3, _hold4, _hold5, value, key); + } + + public Maybe Build() { + return new Maybe(_hold1, _hold2, _hold3, _hold4, _hold5); + } + } + + internal class NamedOptionalLevel6Builder : INamedOptionalBuilder { + private readonly OptionalHold _hold1; + private readonly OptionalHold _hold2; + private readonly OptionalHold _hold3; + private readonly OptionalHold _hold4; + private readonly OptionalHold _hold5; + private readonly OptionalHold _hold6; + + public NamedOptionalLevel6Builder(OptionalHold hold1, OptionalHold hold2, OptionalHold hold3, OptionalHold hold4, OptionalHold hold5, T6 value, + string key) { + _hold1 = hold1; + _hold2 = hold2; + _hold3 = hold3; + _hold4 = hold4; + _hold5 = hold5; + _hold6 = new OptionalHold(value, key); + } + + public INamedOptionalBuilder May(T7 value) { + return new NamedOptionalLevel7Builder(_hold1, _hold2, _hold3, _hold4, _hold5, _hold6, value, NamedMaybeConstants.KEY7); + } + + public INamedOptionalBuilder May(T7 value, string key) { + return new NamedOptionalLevel7Builder(_hold1, _hold2, _hold3, _hold4, _hold5, _hold6, value, key); + } + + public Maybe Build() { + return new Maybe(_hold1, _hold2, _hold3, _hold4, _hold5, _hold6); + } + } + + internal class NamedOptionalLevel7Builder : INamedOptionalBuilder { + private readonly OptionalHold _hold1; + private readonly OptionalHold _hold2; + private readonly OptionalHold _hold3; + private readonly OptionalHold _hold4; + private readonly OptionalHold _hold5; + private readonly OptionalHold _hold6; + private readonly OptionalHold _hold7; + + public NamedOptionalLevel7Builder(OptionalHold hold1, OptionalHold hold2, OptionalHold hold3, OptionalHold hold4, OptionalHold hold5, + OptionalHold hold6, T7 value, + string key) { + _hold1 = hold1; + _hold2 = hold2; + _hold3 = hold3; + _hold4 = hold4; + _hold5 = hold5; + _hold6 = hold6; + _hold7 = new OptionalHold(value, key); + } + + public Maybe Build() { + return new Maybe(_hold1, _hold2, _hold3, _hold4, _hold5, _hold6, _hold7); + } + } + + internal class OptionalHold { + public OptionalHold(T holdValue, string holdKey) { + Value = holdValue; + Key = holdKey; + } + + public T Value { get; } + public string Key { get; } + + private Maybe ToMaybe() => new Maybe(Value, Key, true); + + public static implicit operator Maybe(OptionalHold hold) { + return hold.ToMaybe(); + } + } + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.MaybeT.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.MaybeT.cs new file mode 100644 index 00000000..febb06bf --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.MaybeT.cs @@ -0,0 +1,360 @@ +namespace Cosmos.Optionals { + /// + /// Optional utilities + /// + public static partial class Optional { + + #region From + + /// + /// Some + /// + /// + /// + /// + /// + /// + public static Maybe From(T1 value1, T2 value2) + => new Maybe(value1, value2, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe From(T1 value1, T2 value2, T3 value3) + => new Maybe(value1, value2, value3, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe From(T1 value1, T2 value2, T3 value3, T4 value4) + => new Maybe(value1, value2, value3, value4, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe From(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5) + => new Maybe(value1, value2, value3, value4, value5, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe From(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6) + => new Maybe(value1, value2, value3, value4, value5, value6, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe From(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7) + => new Maybe(value1, value2, value3, value4, value5, value6, value7, true); + + #endregion + + #region From tuple + + /// + /// Some + /// + /// + /// + /// + /// + public static Maybe From((T1, T2) value) + => new Maybe(value.Item1, value.Item2, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + public static Maybe From((T1, T2, T3) value) + => new Maybe(value.Item1, value.Item2, value.Item3, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + public static Maybe From((T1, T2, T3, T4) value) + => new Maybe(value.Item1, value.Item2, value.Item3, value.Item4, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe From((T1, T2, T3, T4, T5) value) + => new Maybe(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe From((T1, T2, T3, T4, T5, T6) value) + => new Maybe(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe From((T1, T2, T3, T4, T5, T6, T7) value) + => new Maybe(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, true); + + #endregion + + #region Some + + /// + /// Some + /// + /// + /// + /// + /// + /// + public static Maybe Some(T1 value1, T2 value2) + => new Maybe(value1, value2, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe Some(T1 value1, T2 value2, T3 value3) + => new Maybe(value1, value2, value3, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe Some(T1 value1, T2 value2, T3 value3, T4 value4) + => new Maybe(value1, value2, value3, value4, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe Some(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5) + => new Maybe(value1, value2, value3, value4, value5, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe Some(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6) + => new Maybe(value1, value2, value3, value4, value5, value6, true); + + /// + /// Some + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe Some(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7) + => new Maybe(value1, value2, value3, value4, value5, value6, value7, true); + + #endregion + + #region None + + /// + /// None + /// + /// + /// + /// + public static Maybe None() + => new Maybe(default, default, false); + + /// + /// None + /// + /// + /// + /// + /// + public static Maybe None() + => new Maybe(default, default, default, false); + + /// + /// None + /// + /// + /// + /// + /// + /// + public static Maybe None() + => new Maybe(default, default, default, default, false); + + /// + /// None + /// + /// + /// + /// + /// + /// + /// + public static Maybe None() + => new Maybe(default, default, default, default, default, false); + + /// + /// None + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe None() + => new Maybe(default, default, default, default, default, default, false); + + /// + /// None + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Maybe None() + => new Maybe(default, default, default, default, default, default, default, false); + + #endregion + + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Named.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Named.cs new file mode 100644 index 00000000..4ed5d421 --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Named.cs @@ -0,0 +1,14 @@ +using System; +using Cosmos.Optionals.NamedOptionals; + +namespace Cosmos.Optionals { + /// + /// Optional utilities + /// + public static partial class Optional { + /// + /// Get an instance of builder, to build a named Maybe. + /// + public static INamedOptionalBuilder Named => NamedOptionalBuilder.Create(); + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Wrapped.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Wrapped.cs new file mode 100644 index 00000000..c8d3cba8 --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Wrapped.cs @@ -0,0 +1,110 @@ +using System; + +namespace Cosmos.Optionals { + /// + /// Optional utilities + /// + public static partial class Optional { + + /// + /// Wrapped optional + /// + public static class Wrapped { + /// + /// For some value + /// + /// + /// + /// + // ReSharper disable once MemberHidesStaticFromOuterClass + public static Some Some(T some) => new Some(some); + + /// + /// For some value + /// + /// + /// + /// + /// + // ReSharper disable once MemberHidesStaticFromOuterClass + public static Some Some(T some) => new Some(some); + + /// + /// For nothing + /// + /// + /// + // ReSharper disable once MemberHidesStaticFromOuterClass + public static None None() => new None(); + + /// + /// For nothing + /// + /// + /// + /// + // ReSharper disable once MemberHidesStaticFromOuterClass + public static None None(TException exception) => new None(exception); + + /// + /// For nothing + /// + /// + /// + public static Some NoneSlim() => new Some(Optional.None()); + + /// + /// For nothing + /// + /// + /// + /// + /// + public static Some NoneSlim(TException exception) => new Some(Optional.None(exception)); + + /// + /// Create an instance of from the given value. + /// + /// + /// + /// + // ReSharper disable once MemberHidesStaticFromOuterClass + public static IOptional From(T value) { + return value is null + ? None() + : Some(value) as IOptional; + } + + /// + /// Create an instance of from the given value. + /// + /// + /// + /// + /// + /// + // ReSharper disable once MemberHidesStaticFromOuterClass + public static IOptional From(T value, Func condition) { + if (condition is null) + throw new ArgumentNullException(nameof(condition)); + if (value is null) + return None(); + return condition(value) ? Some(value) : None() as IOptional; + } + + /// + /// Create an instance of from the given value. + /// + /// + /// + /// + // ReSharper disable once MemberHidesStaticFromOuterClass + public static IOptional From(T? nullable) where T : struct { + return nullable.HasValue + ? Some(nullable.Value) + : None() as IOptional; + } + } + + } +} \ No newline at end of file From 69c019fae60efbef2a77918140109579c4c46e51 Mon Sep 17 00:00:00 2001 From: alexinea Date: Wed, 25 Dec 2019 16:29:48 +0800 Subject: [PATCH 02/15] Removed .NET Framework 4.5.1 dependency on AsyncEX to resolve conflict warnings during compilation. --- .../Cosmos.Extensions.Asyncs.csproj | 7 +- .../Cosmos/Asynchronous/SyncRunner.cs | 6 +- .../Extensions/Extensions.Task.Synchronous.cs | 105 ++++++++++++++++++ .../Cosmos/Extensions/Extensions.Task.cs | 8 +- .../Cosmos/Extensions/Extensions.ValueTask.cs | 6 +- .../Cosmos/Exceptions/ExceptionHelper.cs | 22 ++++ 6 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.Task.Synchronous.cs create mode 100644 src/Cosmos.Extensions/Cosmos/Exceptions/ExceptionHelper.cs diff --git a/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.csproj b/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.csproj index 67bb5004..64538ac8 100644 --- a/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.csproj +++ b/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.csproj @@ -17,15 +17,12 @@ + - + - - - - diff --git a/src/Cosmos.Extensions.Asyncs/Cosmos/Asynchronous/SyncRunner.cs b/src/Cosmos.Extensions.Asyncs/Cosmos/Asynchronous/SyncRunner.cs index ebf1a063..db609106 100644 --- a/src/Cosmos.Extensions.Asyncs/Cosmos/Asynchronous/SyncRunner.cs +++ b/src/Cosmos.Extensions.Asyncs/Cosmos/Asynchronous/SyncRunner.cs @@ -1,7 +1,10 @@ using System; using System.Threading; using System.Threading.Tasks; + +#if !NET451 using Nito.AsyncEx.Synchronous; +#endif namespace Cosmos.Asynchronous { /// @@ -68,8 +71,7 @@ public static TResult FromAsynchronousCallingSafety(Task task, try { return FromAsynchronousCalling(task, cancellationToken); - } - catch { + } catch { return defaultValue; } } diff --git a/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.Task.Synchronous.cs b/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.Task.Synchronous.cs new file mode 100644 index 00000000..b3a584a1 --- /dev/null +++ b/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.Task.Synchronous.cs @@ -0,0 +1,105 @@ +#if NET451 + +using System; +using System.Threading; +using System.Threading.Tasks; +using Cosmos.Exceptions; + +// ReSharper disable once CheckNamespace +namespace Cosmos.Asynchronous { + /// + /// Extensions for task + /// + public static partial class TaskExtensions { + /// + /// Wait and unwrap exception + /// + /// + /// + public static void WaitAndUnwrapException(this Task task) { + if (task is null) + throw new ArgumentNullException(nameof(task)); + task.GetAwaiter().GetResult(); + } + + /// + /// Wait and unwrap exception + /// + /// + /// + /// + public static void WaitAndUnwrapException(this Task task, CancellationToken cancellationToken) { + if (task is null) + throw new ArgumentNullException(nameof(task)); + try { + task.Wait(cancellationToken); + } catch (AggregateException ex) { + throw ExceptionHelper.PrepareForRethrow(ex.InnerException); + } + } + + /// + /// Wait and unwrap exception + /// + /// + /// + /// + /// + public static TResult WaitAndUnwrapException(this Task task) { + if (task is null) + throw new ArgumentNullException(nameof(task)); + return task.GetAwaiter().GetResult(); + } + + /// + /// Wait and unwrap exception + /// + /// + /// + /// + /// + /// + /// + public static TResult WaitAndUnwrapException(this Task task, CancellationToken cancellationToken) { + if (task is null) + throw new ArgumentNullException(nameof(task)); + try { + task.Wait(cancellationToken); + return task.Result; + } catch (AggregateException ex) { + throw ExceptionHelper.PrepareForRethrow(ex.InnerException); + } + } + + /// + /// Wait without exception + /// + /// + /// + public static void WaitWithoutException(this Task task) { + if (task is null) + throw new ArgumentNullException(nameof(task)); + try { + task.Wait(); + } catch (AggregateException) { } + } + + /// + /// Wait without exception + /// + /// + /// + /// + public static void WaitWithoutException(this Task task, CancellationToken cancellationToken) { + if (task is null) + throw new ArgumentNullException(nameof(task)); + try { + task.Wait(cancellationToken); + } catch (AggregateException) { + cancellationToken.ThrowIfCancellationRequested(); + } + } + } +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.Task.cs b/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.Task.cs index 7c27ea71..f7e744b5 100644 --- a/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.Task.cs +++ b/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.Task.cs @@ -1,3 +1,5 @@ +#if !NET451 + using System; using System.Threading.Tasks; using Nito.AsyncEx; @@ -7,7 +9,7 @@ namespace Cosmos.Asynchronous { /// /// Task extensions /// - public static class TaskExtensions { + public static partial class TaskExtensions { /// /// Run in AsyncContext /// @@ -32,4 +34,6 @@ public static T RunInContext(this Task task) { return AsyncContext.Run(() => task); } } -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.ValueTask.cs b/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.ValueTask.cs index 94c32acf..70bf3046 100644 --- a/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.ValueTask.cs +++ b/src/Cosmos.Extensions.Asyncs/Cosmos/Extensions/Extensions.ValueTask.cs @@ -1,3 +1,5 @@ +#if !NET451 + using System.Threading.Tasks; // ReSharper disable once CheckNamespace @@ -14,4 +16,6 @@ public static class ValueTaskExtensions { /// public static T RunInContext(this in ValueTask task) => task.AsTask().RunInContext(); } -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions/Cosmos/Exceptions/ExceptionHelper.cs b/src/Cosmos.Extensions/Cosmos/Exceptions/ExceptionHelper.cs new file mode 100644 index 00000000..c2bf6060 --- /dev/null +++ b/src/Cosmos.Extensions/Cosmos/Exceptions/ExceptionHelper.cs @@ -0,0 +1,22 @@ +using System; +using System.Runtime.ExceptionServices; + +namespace Cosmos.Exceptions { + /// + /// Exception helper + /// + public static class ExceptionHelper { + /// + /// Prepare for rethrow + /// + /// + /// + public static Exception PrepareForRethrow(Exception exception) { + ExceptionDispatchInfo.Capture(exception).Throw(); + + // The code cannot ever get here. We just return a value to work around a badly-designed API (ExceptionDispatchInfo.Throw): + // https://connect.microsoft.com/VisualStudio/feedback/details/689516/exceptiondispatchinfo-api-modifications (http://www.webcitation.org/6XQ7RoJmO) + return exception; + } + } +} \ No newline at end of file From 81f8be106f5c2353996b0c86e6b9770369f5c731 Mon Sep 17 00:00:00 2001 From: alexinea Date: Wed, 25 Dec 2019 16:30:07 +0800 Subject: [PATCH 03/15] Update commands and README.MD. --- README.md | 2 +- build/version.props | 2 +- src/Cosmos.Extensions/Cosmos.Extensions.xml | 303 ++++++++++++++++++++ src/Cosmos.Extensions/Cosmos/Try`1.cs | 4 + 4 files changed, 309 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 782a037c..69b97b1e 100644 --- a/README.md +++ b/README.md @@ -46,4 +46,4 @@ People or projects that have made a great contribbution to this project: Member project of [Cosmosloops Labs.](https://github.com/cosmos-loops). -[Apache 2.0 License](/LICENSE) +[Apache License 2.0](/LICENSE) diff --git a/build/version.props b/build/version.props index ac550179..96d92cb6 100644 --- a/build/version.props +++ b/build/version.props @@ -2,7 +2,7 @@ 0 1 - 2-alpha2-100011 + 2-alpha2-100015 $(VersionMajor).$(VersionMinor).$(VersionPatch) diff --git a/src/Cosmos.Extensions/Cosmos.Extensions.xml b/src/Cosmos.Extensions/Cosmos.Extensions.xml index a472ee43..505bc976 100644 --- a/src/Cosmos.Extensions/Cosmos.Extensions.xml +++ b/src/Cosmos.Extensions/Cosmos.Extensions.xml @@ -970,6 +970,18 @@ + + + Exception helper + + + + + Prepare for rethrow + + + + 参数重绑定操作 @@ -7199,6 +7211,297 @@ + + + Try + + + + + Create a new instance of . + + + + + + + + Lifts a value. + + + + + + + + Lifts + + + + + + + + Extensions for Try + + + + + Select + + + + + + + + + + Select many + + + + + + + + + + Select many + + + + + + + + + + + + Where + + + + + + + + + Try + + + + + + Is failure + + + + + Is success + + + + + Exception + + + + + Value + + + + + == + + + + + + + + != + + + + + + + + + + + + + + + + + Deconstruct + + + + + + + Exception as + + + + + + + Recover + + + + + + + Recover with + + + + + + + Match + + + + + + + + + Map + + + + + + + + Tap + + + + + + + + Bind + + + + + + + + Failure + + + + + + Initializes a new instance of the class. + + The exception to wrapp. + + + + + + + + + + + + + + + + + + + Equals + + + + + + + + + + + + + + + + + + + + + + + + + + + + Success + + + + + + + + + + + + + + + + + + + + + Equals + + + + + + + + + + + + + + + + + + + + + + + + + Generates copy delegates. diff --git a/src/Cosmos.Extensions/Cosmos/Try`1.cs b/src/Cosmos.Extensions/Cosmos/Try`1.cs index 29d95db9..fb3125ad 100644 --- a/src/Cosmos.Extensions/Cosmos/Try`1.cs +++ b/src/Cosmos.Extensions/Cosmos/Try`1.cs @@ -1,6 +1,10 @@ using System; namespace Cosmos { + /// + /// Try + /// + /// public abstract class Try { /// /// Is failure From ebb620466be78153981d0f8c1fc86035881f914b Mon Sep 17 00:00:00 2001 From: alexinea Date: Thu, 2 Jan 2020 16:05:01 +0800 Subject: [PATCH 04/15] Update `NamedOptionalObject`s --- .../Cosmos/Optionals/Either.cs | 3 ++ .../Optionals/Extensions.CollectionAsync.cs | 8 ++--- .../Optionals/Extensions.Collections.cs | 34 +++++++++--------- .../Cosmos/Optionals/Extensions.Optional.cs | 4 +-- .../Cosmos/Optionals/IOptional`1.cs | 5 +++ .../Cosmos/Optionals/Maybe`1.cs | 35 +++++++++++++++---- .../Cosmos/Optionals/Maybe`2.cs | 3 ++ .../Cosmos/Optionals/Maybe`3.cs | 3 ++ .../Cosmos/Optionals/Maybe`4.cs | 3 ++ .../Cosmos/Optionals/Maybe`5.cs | 3 ++ .../Cosmos/Optionals/Maybe`6.cs | 5 ++- .../Cosmos/Optionals/Maybe`7.cs | 5 ++- .../Cosmos/Optionals/Optional.Named.cs | 1 - .../Cosmos/Optionals/Optional`1.cs | 5 ++- .../Cosmos/Optionals/Optional`2.cs | 3 ++ 15 files changed, 87 insertions(+), 33 deletions(-) diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Either.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Either.cs index 4dc14a48..1af08aea 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Either.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Either.cs @@ -30,6 +30,9 @@ internal Either(T value, TException exception, bool hasValue) { /// public TException Exception => _exception; + /// + public string Key => "EitherKey"; + #region Equals /// diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.CollectionAsync.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.CollectionAsync.cs index edc0a975..47887d90 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.CollectionAsync.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.CollectionAsync.cs @@ -29,7 +29,7 @@ public static Task> MapAsync(this Maybe option, Fu someFactory: async valueTask => { if (valueTask == null) throw new InvalidOperationException($"{nameof(mapping)} must not return a null task."); var value = await valueTask.ConfigureAwait(continueOnCapturedContext: false); - return value.Maybe(); + return value.ToMaybe(); }, noneFactory: () => Task.FromResult(Optional.None()) ); @@ -289,7 +289,7 @@ public static async Task> OrAsync(this Maybe option, Func throw new InvalidOperationException($"{nameof(alternativeFactory)} must not return a null task."); var alternative = await alternativeTask.ConfigureAwait(continueOnCapturedContext: false); - return alternative.Maybe(); + return alternative.ToMaybe(); } /// @@ -461,7 +461,7 @@ public static Task> MapAsync if (valueTask is null) throw new InvalidOperationException($"{nameof(mapping)} must not return a null task."); var value = await valueTask.ConfigureAwait(continueOnCapturedContext: false); - return value.Maybe(); + return value.ToMaybe(); }, noneFactory: exception => Task.FromResult(Optional.None(exception)) ); @@ -934,7 +934,7 @@ public static async Task> OrAsync(this Eith throw new InvalidOperationException($"{nameof(alternativeFactory)} must not return a null task."); var alternative = await alternativeTask.ConfigureAwait(continueOnCapturedContext: false); - return alternative.Maybe(); + return alternative.ToMaybe(); } /// diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.Collections.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.Collections.cs index 5f3c8ac4..32102b65 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.Collections.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.Collections.cs @@ -96,14 +96,14 @@ public static Maybe FirstOrNone(this IEnumerable source) { throw new ArgumentNullException(nameof(source)); if (source is IList list) { if (list.Count > 0) - return list[0].Maybe(); + return list[0].ToMaybe(); } else if (source is IReadOnlyList readOnlyList) { if (readOnlyList.Count > 0) - return readOnlyList[0].Maybe(); + return readOnlyList[0].ToMaybe(); } else { using (var enumerator = source.GetEnumerator()) { if (enumerator.MoveNext()) - return enumerator.Current.Maybe(); + return enumerator.Current.ToMaybe(); } } @@ -126,7 +126,7 @@ public static Maybe FirstOrNone(this IEnumerable source, Func throw new ArgumentNullException(nameof(predicate)); foreach (var element in source) { if (predicate(element)) - return element.Maybe(); + return element.ToMaybe(); } return Optional.None(); @@ -145,11 +145,11 @@ public static Maybe LastOrNone(this IEnumerable source) { if (source is IList list) { var count = list.Count; if (count > 0) - return list[count].Maybe(); + return list[count].ToMaybe(); } else if (source is IReadOnlyList readOnlyList) { var count = readOnlyList.Count; if (count > 0) - return readOnlyList[count].Maybe(); + return readOnlyList[count].ToMaybe(); } else { using (var enumerator = source.GetEnumerator()) { if (enumerator.MoveNext()) { @@ -158,7 +158,7 @@ public static Maybe LastOrNone(this IEnumerable source) { t = enumerator.Current; } while (enumerator.MoveNext()); - return t.Maybe(); + return t.ToMaybe(); } } } @@ -184,13 +184,13 @@ public static Maybe LastOrNone(this IEnumerable source, Func p for (var i = list.Count - 1; i >= 0; --i) { var result = list[i]; if (predicate(result)) - return result.Maybe(); + return result.ToMaybe(); } } else if (source is IReadOnlyList readOnlyList) { for (var i = readOnlyList.Count - 1; i >= 0; --i) { var result = readOnlyList[i]; if (predicate(result)) - return result.Maybe(); + return result.ToMaybe(); } } else { using (var enumerator = source.GetEnumerator()) { @@ -204,7 +204,7 @@ public static Maybe LastOrNone(this IEnumerable source, Func p } } - return result.Maybe(); + return result.ToMaybe(); } } } @@ -227,12 +227,12 @@ public static Maybe SingleOrNone(this IEnumerable source) { if (source is IList list) { switch (list.Count) { case 0: return Optional.None(); - case 1: return list[0].Maybe(); + case 1: return list[0].ToMaybe(); } } else if (source is IReadOnlyList readOnlyList) { switch (readOnlyList.Count) { case 0: return Optional.None(); - case 1: return readOnlyList[0].Maybe(); + case 1: return readOnlyList[0].ToMaybe(); } } else { using (var enumerator = source.GetEnumerator()) { @@ -240,7 +240,7 @@ public static Maybe SingleOrNone(this IEnumerable source) { return Optional.None(); var result = enumerator.Current; if (!enumerator.MoveNext()) - return result.Maybe(); + return result.ToMaybe(); } } @@ -270,7 +270,7 @@ public static Maybe SingleOrNone(this IEnumerable source, Func return Optional.None(); } - return result.Maybe(); + return result.ToMaybe(); } } } @@ -292,17 +292,17 @@ public static Maybe ElementAtOrNone(this IEnumerable source, int index) if (index >= 0) { if (source is IList list) { if (index < list.Count) { - return list[index].Maybe(); + return list[index].ToMaybe(); } } else if (source is IReadOnlyList readOnlyList) { if (index < readOnlyList.Count) { - return readOnlyList[index].Maybe(); + return readOnlyList[index].ToMaybe(); } } else { using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (index == 0) { - return enumerator.Current.Maybe(); + return enumerator.Current.ToMaybe(); } index--; diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.Optional.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.Optional.cs index bb5180a6..6a7dde0d 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.Optional.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Extensions.Optional.cs @@ -14,7 +14,7 @@ public static class OptionalExtensions { /// /// /// - public static Maybe Maybe(this T value) { + public static Maybe ToMaybe(this T value) { return Optional.Some(value); } @@ -25,7 +25,7 @@ public static Maybe Maybe(this T value) { /// /// /// - public static Either Maybe(this T value) { + public static Either ToMaybe(this T value) { return Optional.Some(value); } diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/IOptional`1.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/IOptional`1.cs index b066e609..e5a477a8 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/IOptional`1.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/IOptional`1.cs @@ -6,6 +6,11 @@ namespace Cosmos.Optionals { /// /// public interface IOptional { + /// + /// Key + /// + string Key { get; } + /// /// Has value /// diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`1.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`1.cs index 4875ad72..dcae4c85 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`1.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`1.cs @@ -5,8 +5,6 @@ // ReSharper disable InconsistentNaming namespace Cosmos.Optionals { - - /// /// Maybe /// @@ -37,10 +35,8 @@ internal Maybe(T value, string key, bool hasValue) { /// public T Value => _value; - /// - /// Hashcode for key - /// - internal string Key => _key; + /// + public string Key => _key; #region Equals @@ -515,9 +511,36 @@ public Maybe Join(Maybe optionalToJoin) #endregion + #region implicit operator + + /// + /// Convert T to Maybe{T} + /// + /// + /// + public static implicit operator Maybe(T value) { + return Optional.From(value); + } + + /// + /// Convert T from Maybe{T} + /// + /// + /// + public static implicit operator T(Maybe maybe) { + return maybe.ValueOrDefault(); + } + + #endregion + + #region Nothing + /// /// Nothing /// public static Maybe Nothing => Optional.None(); + + #endregion + } } \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`2.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`2.cs index b6f208ae..4a3143e0 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`2.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`2.cs @@ -54,6 +54,9 @@ internal Maybe(Maybe maybe1, Maybe maybe2) { /// public bool HasValue => _hasValue && _o1.HasValue && _o2.HasValue; + /// + public string Key => _o2.Key; + #region Index /// diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`3.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`3.cs index 25247614..779b32a7 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`3.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`3.cs @@ -63,6 +63,9 @@ internal Maybe(Maybe maybe1, Maybe maybe2, Maybe maybe3) { /// public bool HasValue => _hasValue && _o1.HasValue && _o2.HasValue && _o3.HasValue; + + /// + public string Key => _o3.Key; #region Index diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`4.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`4.cs index c1cb2f55..cffb847b 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`4.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`4.cs @@ -73,6 +73,9 @@ internal Maybe(Maybe maybe1, Maybe maybe2, Maybe maybe3, Maybe m /// public bool HasValue => _hasValue && _o1.HasValue && _o2.HasValue && _o3.HasValue && _o4.HasValue; + + /// + public string Key => _o4.Key; #region Index diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`5.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`5.cs index cc7148fa..cc9cafd6 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`5.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`5.cs @@ -83,6 +83,9 @@ internal Maybe(Maybe maybe1, Maybe maybe2, Maybe maybe3, Maybe m /// public bool HasValue => _hasValue && _o1.HasValue && _o2.HasValue && _o3.HasValue && _o4.HasValue && _o5.HasValue; + + /// + public string Key => _o5.Key; #region Index diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`6.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`6.cs index db059f41..8ec5d032 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`6.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`6.cs @@ -94,7 +94,10 @@ internal Maybe(Maybe maybe1, Maybe maybe2, Maybe maybe3, Maybe m /// public bool HasValue => _hasValue && _o1.HasValue && _o2.HasValue && _o3.HasValue && _o4.HasValue && _o5.HasValue && _o6.HasValue; - + + /// + public string Key => _o6.Key; + #region Index /// diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`7.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`7.cs index 07e44c77..c44c1648 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`7.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Maybe`7.cs @@ -104,7 +104,10 @@ internal Maybe(Maybe maybe1, Maybe maybe2, Maybe maybe3, Maybe m /// public bool HasValue => _hasValue && _o1.HasValue && _o2.HasValue && _o3.HasValue && _o4.HasValue && _o5.HasValue && _o6.HasValue && _o7.HasValue; - + + /// + public string Key => _o7.Key; + #region Index /// diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Named.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Named.cs index 4ed5d421..959b0d34 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Named.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Named.cs @@ -1,4 +1,3 @@ -using System; using Cosmos.Optionals.NamedOptionals; namespace Cosmos.Optionals { diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional`1.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional`1.cs index 3685e9e6..e29e9888 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional`1.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional`1.cs @@ -36,7 +36,10 @@ protected Optional(Maybe @internal) { public virtual bool HasValue => Internal.HasValue; /// - public virtual T Value => Internal.Value; + public virtual T Value => Internal.Value; + + /// + public string Key => Internal.Key; /// public bool Contains(T value) => Internal.Contains(value); diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional`2.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional`2.cs index 95cb232d..6c030a19 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional`2.cs +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional`2.cs @@ -40,6 +40,9 @@ protected Optional(Either either) { /// public virtual T Value => Either.Value; + /// + public string Key => Either.Key; + /// public TException Exception => Either.Exception; From da4f8662d322cd8c089a01bc458444e36669ec82 Mon Sep 17 00:00:00 2001 From: alexinea Date: Thu, 2 Jan 2020 16:05:40 +0800 Subject: [PATCH 05/15] Add `DynamicOptional`s --- .../Cosmos.Extensions.Optionals.csproj | 1 + .../Cosmos.Extensions.Optionals.xml | 431 +++++++++++++++++- .../Cosmos/Optionals/DynamicMaybe.cs | 242 ++++++++++ .../Optionals/DynamicOptionalBuilder.cs | 84 ++++ .../DynamicOptionals/DynamicOptionalObject.cs | 150 ++++++ .../IDynamicOptionalBuilder.cs | 28 ++ .../Cosmos/Optionals/IOptional`0.Dynamic.cs | 145 ++++++ .../Cosmos/Optionals/Optional.Dynamic.cs | 13 + 8 files changed, 1089 insertions(+), 5 deletions(-) create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicMaybe.cs create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionalBuilder.cs create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionals/DynamicOptionalObject.cs create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionals/IDynamicOptionalBuilder.cs create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/IOptional`0.Dynamic.cs create mode 100644 src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Dynamic.cs diff --git a/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.csproj b/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.csproj index 6f0841ea..79e599ec 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.csproj +++ b/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.xml b/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.xml index c745671b..bc8dbe0d 100644 --- a/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.xml +++ b/src/Cosmos.Extensions.Optionals/Cosmos.Extensions.Optionals.xml @@ -4,6 +4,235 @@ Cosmos.Extensions.Optionals + + + Dynamic maybe + + + + + + + + + + + + + + Index + + + + + + Index + + + + + + To enumerable + + + + + + Get enumrtator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Where + + + + + + + + Where + + + + + + + + Select + + + + + + + + + To Dictionary + + + + + + To Dictionary + + + + + + Dynamic optional builder + + + + + Create the dynamic optional builder + + + + + + + + + + + + Build + + + + + + Dynamic optional object + + + + + Dynamic optional object + + + + + + + Indexer + + + + + + + Indexer + + + + + + Get dynamic object + + + + + + To enumerable + + + + + + Get enumrtator + + + + + + Contains + + + + + + + Exists + + + + + + + + Gets keys + + + + + Gets values + + + + + Interface for dynamic optional builder + + + + + May + + + + + + + + Silence May + + + + + + + + Build + + + Either @@ -20,6 +249,9 @@ + + + @@ -1302,7 +1534,7 @@ Extensions for optional - + Maybe @@ -1310,7 +1542,7 @@ - + Maybe @@ -1702,12 +1934,157 @@ + + + Interface for Dynamic optional + + + + + Key + + + + + Has value + + + + + Value + + + + + Contains + + + + + + + Exists + + + + + + + Value or + + + + + + + + Value or + + + + + + + + Or + + + + + + + + Or + + + + + + + + Else + + + + + + + + Else + + + + + + + + Convert to dynamic object + + + + + + Gets keys + + + + + Gets values + + + + + Join + + + + + + + + Where + + + + + + + Where + + + + + + + Select + + + + + + + + To Dictionary + + + + + + To Dictionary + + + Interface for optional + + + Key + + Has value @@ -2074,9 +2451,7 @@ - - Hashcode for key - + @@ -2354,6 +2729,20 @@ + + + Convert T to Maybe{T} + + + + + + + Convert T from Maybe{T} + + + + Nothing @@ -2382,6 +2771,9 @@ + + + Index @@ -2622,6 +3014,9 @@ + + + Index @@ -2870,6 +3265,9 @@ + + + Index @@ -3126,6 +3524,9 @@ + + + Index @@ -3390,6 +3791,9 @@ + + + Index @@ -3662,6 +4066,9 @@ + + + Index @@ -4227,6 +4634,9 @@ Optional utilities + + Optional utilities + @@ -4305,6 +4715,11 @@ + + + Get an instance of builder, to build a dynamic Maybe. + + Some @@ -4789,6 +5204,9 @@ + + + @@ -4907,6 +5325,9 @@ + + + diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicMaybe.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicMaybe.cs new file mode 100644 index 00000000..d4f0ced4 --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicMaybe.cs @@ -0,0 +1,242 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Cosmos.Optionals.DynamicOptionals; + +namespace Cosmos.Optionals { + /// + /// Dynamic maybe + /// + public readonly struct DynamicMaybe : IDynamicOptional { + private readonly DynamicOptionalObject _dynamicOptionalObject; + + internal DynamicMaybe(DynamicOptionalObject optionalObject) { + _dynamicOptionalObject = optionalObject ?? throw new ArgumentNullException(nameof(optionalObject)); + } + + /// + public string Key => _dynamicOptionalObject.Key; + + /// + public bool HasValue => _dynamicOptionalObject.Keys.Any(); + + /// + public dynamic Value => _dynamicOptionalObject.GetDynamicObject(); + + #region Index + + /// + /// Index + /// + /// + public Maybe this[int index] => Optional.From(_dynamicOptionalObject[index]); + + /// + /// Index + /// + /// + public Maybe this[string key] => Optional.From(_dynamicOptionalObject[key]); + + #endregion + + #region Enumerable + + /// + /// To enumerable + /// + /// + public IEnumerable> ToEnumerable() { + foreach (var item in _dynamicOptionalObject) + yield return new NamedOptionalBuilder.NamedOptionalLevel1Builder(item.Value, item.Key).Build(); + } + + /// + /// Get enumrtator + /// + /// + public IEnumerator> GetEnumerator() { + foreach (var item in _dynamicOptionalObject) + yield return new NamedOptionalBuilder.NamedOptionalLevel1Builder(item.Value, item.Key).Build(); + } + + #endregion + + #region Contains / Exists + + /// + public bool Contains(string key) { + return _dynamicOptionalObject.Contains(key); + } + + /// + public bool Exists(Func predicate) { + if (predicate is null) + throw new ArgumentNullException(nameof(predicate)); + return _dynamicOptionalObject.Exists(predicate); + } + + #endregion + + #region Value or + + /// + public dynamic ValueOr(string key, dynamic alternative) { + return Contains(key) ? _dynamicOptionalObject[key] : alternative; + } + + /// + public dynamic ValueOr(string key, Func alternativeFactory) { + if (alternativeFactory is null) + throw new ArgumentNullException(nameof(alternativeFactory)); + return Contains(key) ? _dynamicOptionalObject[key] : alternativeFactory(); + } + + #endregion + + #region Or / Else + + /// + public Maybe Or(string key, dynamic alternative) { + return Contains(key) ? this[key] : Optional.Some(alternative); + } + + /// + public Maybe Or(string key, Func alternativeFactory) { + if (alternativeFactory is null) + throw new ArgumentNullException(nameof(alternativeFactory)); + return Contains(key) ? this[key] : Optional.Some(alternativeFactory()); + } + + /// + public Maybe Else(string key, Maybe alternativeMaybe) { + return Contains(key) ? this[key] : alternativeMaybe; + } + + /// + public Maybe Else(string key, Func> alternativeMaybeFactory) { + if (alternativeMaybeFactory is null) + throw new ArgumentNullException(nameof(alternativeMaybeFactory)); + return Contains(key) ? this[key] : alternativeMaybeFactory(); + } + + #endregion + + #region To dynamic + + /// + public dynamic ToDynamicObject() => _dynamicOptionalObject.GetDynamicObject(); + + #endregion + + #region Keys / Values + + /// + public IEnumerable Keys => _dynamicOptionalObject.Keys; + + /// + public IEnumerable Values => _dynamicOptionalObject.Values; + + #endregion + + #region Join + + /// + public DynamicMaybe Join(dynamic value, string key) { + return DynamicOptionalBuilder.Returns(_dynamicOptionalObject).SilenceMay(value, key).Build(); + } + + #endregion + + #region Linq + + /// + /// Where + /// + /// + /// + /// + public DynamicMaybe Where(Func predicate) { + if (predicate is null) + throw new ArgumentNullException(nameof(predicate)); + var dictionary = Filter(_dynamicOptionalObject, predicate).ToDictionary(k => k.Key, v => v.Value); + var queueLikeList = _dynamicOptionalObject.InternalQueueLikeList.Where(s => dictionary.Keys.Contains(s)); + return DynamicOptionalBuilder.Returns(dictionary, queueLikeList).Build(); + } + + /// + /// Where + /// + /// + /// + /// + public DynamicMaybe Where(Func predicate) { + if (predicate is null) + throw new ArgumentNullException(nameof(predicate)); + var dictionary = Filter(_dynamicOptionalObject, predicate).ToDictionary(k => k.Key, v => v.Value); + var queueLikeList = _dynamicOptionalObject.InternalQueueLikeList.Where(s => dictionary.Keys.Contains(s)); + return DynamicOptionalBuilder.Returns(dictionary, queueLikeList).Build(); + } + + private static IEnumerable> Filter(DynamicOptionalObject dynamicOptionalObject, Func predicate) { + foreach (var pair in dynamicOptionalObject) { + if (predicate.Invoke(pair.Key, pair.Value)) + yield return pair; + } + } + + private static IEnumerable> Filter(DynamicOptionalObject dynamicOptionalObject, Func predicate) { + foreach (var pair in dynamicOptionalObject) { + if (predicate.Invoke(pair.Value)) + yield return pair; + } + } + + /// + /// Select + /// + /// + /// + /// + /// + public IEnumerable Select(Func selector) { + if (selector is null) + throw new ArgumentNullException(nameof(selector)); + foreach (var pair in _dynamicOptionalObject) + yield return selector(pair.Key, pair.Value); + } + + /// + /// To Dictionary + /// + /// + public IDictionary ToDictionary() { + var result = new Dictionary(); + foreach (var pair in _dynamicOptionalObject) + result.Add(pair.Key, pair.Value); + return result; + } + + /// + /// To Dictionary + /// + /// + // ReSharper disable once InconsistentNaming + public IDictionary ToDictionary(Func, T> keySelector, Func, V> valueSelector) { + if (keySelector is null) + throw new ArgumentNullException(nameof(keySelector)); + if (valueSelector is null) + throw new ArgumentNullException(nameof(valueSelector)); + var result = new Dictionary(); + foreach (var pair in _dynamicOptionalObject) { + var key = keySelector(pair); + var value = valueSelector(pair); + result.Add(key, value); + } + + return result; + } + + #endregion + + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionalBuilder.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionalBuilder.cs new file mode 100644 index 00000000..fe78e25a --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionalBuilder.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Cosmos.Optionals.DynamicOptionals; + +namespace Cosmos.Optionals { + /// + /// Dynamic optional builder + /// + public class DynamicOptionalBuilder : IDynamicOptionalBuilder { + private readonly Dictionary _dynamicDictionary; + private readonly List _queueLikeList; + private object _dynamicLockObj = new object(); + + private DynamicOptionalBuilder() { + _dynamicDictionary = new Dictionary(); + _queueLikeList = new List(); + } + + private DynamicOptionalBuilder(DynamicOptionalObject dynamicOptionalObject) { +#if NET451 || NET461 || NETSTANDARD2_0 + _dynamicDictionary = new Dictionary(); + foreach (var pair in dynamicOptionalObject) { + _dynamicDictionary.Add(pair.Key, pair.Value); + } +#else + _dynamicDictionary = new Dictionary(dynamicOptionalObject.InternalDynamicDictionary); +#endif + _queueLikeList = new List(dynamicOptionalObject.InternalQueueLikeList); + } + + /// + /// Create the dynamic optional builder + /// + /// + public static DynamicOptionalBuilder Create() => new DynamicOptionalBuilder(); + + internal static DynamicOptionalBuilder Returns(DynamicOptionalObject dynamicOptionalObject) => new DynamicOptionalBuilder(dynamicOptionalObject); + + internal static DynamicOptionalBuilder Returns(IDictionary dynamicDictionary, IEnumerable queueLikeList) => + Returns(new DynamicOptionalObject(dynamicDictionary, queueLikeList)); + + /// + public IDynamicOptionalBuilder May(dynamic value, string key) { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + lock (_dynamicLockObj) { + if (_queueLikeList.Contains(key)) + throw new InvalidOperationException("Key has been repeated in the dictionary."); + _queueLikeList.Add(key); + _dynamicDictionary.Add(key, value); + } + + return this; + } + + /// + public IDynamicOptionalBuilder SilenceMay(dynamic value, string key) { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + lock (_dynamicLockObj) { + if (_queueLikeList.Contains(key)) { + _dynamicDictionary[key] = value; + } else { + _queueLikeList.Add(key); + _dynamicDictionary.Add(key, value); + } + } + + return this; + } + + /// + /// Build + /// + /// + [SuppressMessage("ReSharper", "InconsistentlySynchronizedField")] + public DynamicMaybe Build() { + var dynamicObj = new DynamicOptionalObject(_dynamicDictionary, _queueLikeList); + + return new DynamicMaybe(dynamicObj); + } + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionals/DynamicOptionalObject.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionals/DynamicOptionalObject.cs new file mode 100644 index 00000000..6224ea43 --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionals/DynamicOptionalObject.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Dynamic; +using System.Linq; +using System.Text; + +namespace Cosmos.Optionals.DynamicOptionals { + /// + /// Dynamic optional object + /// + internal class DynamicOptionalObject { + private readonly Dictionary _dynamicDictionary; + private readonly IList _queueLikeList; + + /// + /// Dynamic optional object + /// + /// + /// + public DynamicOptionalObject(IDictionary dynamicDictionary, IEnumerable queueLikeList) { + if (dynamicDictionary != null) { + _dynamicDictionary = new Dictionary(dynamicDictionary); + _queueLikeList = new List(queueLikeList); + } else { + _dynamicDictionary = new Dictionary(); + _queueLikeList = new List(); + } + } + + #region Internal + + internal IReadOnlyDictionary InternalDynamicDictionary => _dynamicDictionary; + + internal IList InternalQueueLikeList => _queueLikeList; + + #endregion + + #region Indexer + + /// + /// Indexer + /// + /// + /// + public dynamic this[int index] { + get { + if (index < 0 || index >= _queueLikeList.Count) + throw new IndexOutOfRangeException($"Index value {index} is out of range."); + return this[_queueLikeList[index]]; + } + } + + /// + /// Indexer + /// + /// + public dynamic this[string key] => _dynamicDictionary.TryGetValue(key, out var result) ? result : default; + + #endregion + + #region Get dynamic object + + /// + /// Get dynamic object + /// + /// + public dynamic GetDynamicObject() { + dynamic dynamicObject = new ExpandoObject(); + foreach (var item in _dynamicDictionary) { + dynamicObject[item.Key] = item.Value; + } + + return dynamicObject; + } + + #endregion + + #region Enumerable + + /// + /// To enumerable + /// + /// + public IEnumerable> ToEnumerable() { + return _dynamicDictionary; + } + + /// + /// Get enumrtator + /// + /// + public IEnumerator> GetEnumerator() { + return _dynamicDictionary.GetEnumerator(); + } + + #endregion + + #region Contains / Exists + + /// + /// Contains + /// + /// + /// + public bool Contains(string key) { + return _queueLikeList.Contains(key) && _dynamicDictionary.ContainsKey(key); + } + + /// + /// Exists + /// + /// + /// + /// + public bool Exists(Func predicate) { + if (predicate is null) + throw new ArgumentNullException(nameof(predicate)); + return _queueLikeList.Any(predicate) && _dynamicDictionary.Keys.Any(predicate); + } + + #endregion + + #region Keys / Values + + public string Key { + get { + var sb = new StringBuilder(); + foreach (var key in Keys) { + sb.Append($"{key}-"); + } + + return sb.Length > 0 ? sb.ToString(0, sb.Length - 1) : "EmptyDynamicOptional"; + } + } + + /// + /// Gets keys + /// + public IEnumerable Keys => new ReadOnlyCollection(_queueLikeList); + + /// + /// Gets values + /// + public IEnumerable Values => new ReadOnlyCollection(_dynamicDictionary.Values.ToList()); + + #endregion + + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionals/IDynamicOptionalBuilder.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionals/IDynamicOptionalBuilder.cs new file mode 100644 index 00000000..98ea5fc3 --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/DynamicOptionals/IDynamicOptionalBuilder.cs @@ -0,0 +1,28 @@ +namespace Cosmos.Optionals.DynamicOptionals { + /// + /// Interface for dynamic optional builder + /// + public interface IDynamicOptionalBuilder { + /// + /// May + /// + /// + /// + /// + IDynamicOptionalBuilder May(dynamic value, string key); + + /// + /// Silence May + /// + /// + /// + /// + IDynamicOptionalBuilder SilenceMay(dynamic value, string key); + + /// + /// Build + /// + /// + DynamicMaybe Build(); + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/IOptional`0.Dynamic.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/IOptional`0.Dynamic.cs new file mode 100644 index 00000000..e4565f33 --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/IOptional`0.Dynamic.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; + +namespace Cosmos.Optionals { + /// + /// Interface for Dynamic optional + /// + public interface IDynamicOptional { + /// + /// Key + /// + string Key { get; } + + /// + /// Has value + /// + bool HasValue { get; } + + /// + /// Value + /// + dynamic Value { get; } + + /// + /// Contains + /// + /// + /// + bool Contains(string key); + + /// + /// Exists + /// + /// + /// + bool Exists(Func predicate); + + /// + /// Value or + /// + /// + /// + /// + dynamic ValueOr(string key, dynamic alternative); + + /// + /// Value or + /// + /// + /// + /// + dynamic ValueOr(string key, Func alternativeFactory); + + /// + /// Or + /// + /// + /// + /// + Maybe Or(string key, dynamic alternative); + + /// + /// Or + /// + /// + /// + /// + Maybe Or(string key, Func alternativeFactory); + + /// + /// Else + /// + /// + /// + /// + Maybe Else(string key, Maybe alternativeMaybe); + + /// + /// Else + /// + /// + /// + /// + Maybe Else(string key, Func> alternativeMaybeFactory); + + /// + /// Convert to dynamic object + /// + /// + dynamic ToDynamicObject(); + + /// + /// Gets keys + /// + IEnumerable Keys { get; } + + /// + /// Gets values + /// + IEnumerable Values { get; } + + /// + /// Join + /// + /// + /// + /// + DynamicMaybe Join(dynamic value, string key); + + /// + /// Where + /// + /// + /// + DynamicMaybe Where(Func predicate); + + /// + /// Where + /// + /// + /// + DynamicMaybe Where(Func predicate); + + /// + /// Select + /// + /// + /// + /// + IEnumerable Select(Func selector); + + /// + /// To Dictionary + /// + /// + IDictionary ToDictionary(); + + /// + /// To Dictionary + /// + /// + // ReSharper disable once InconsistentNaming + IDictionary ToDictionary(Func, T> keySelector, Func, V> valueSelector); + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Dynamic.cs b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Dynamic.cs new file mode 100644 index 00000000..c5002d37 --- /dev/null +++ b/src/Cosmos.Extensions.Optionals/Cosmos/Optionals/Optional.Dynamic.cs @@ -0,0 +1,13 @@ +using Cosmos.Optionals.DynamicOptionals; + +namespace Cosmos.Optionals { + /// + /// Optional utilities + /// + public static partial class Optional { + /// + /// Get an instance of builder, to build a dynamic Maybe. + /// + public static IDynamicOptionalBuilder Dynamic => DynamicOptionalBuilder.Create(); + } +} \ No newline at end of file From 4de6246820f2e4e0f9b62c6334bb18ed55577ece Mon Sep 17 00:00:00 2001 From: alexinea Date: Thu, 2 Jan 2020 16:07:06 +0800 Subject: [PATCH 06/15] Add Toml/Nett serialization extensions --- Cosmos.Standard.sln | 16 +- Publish.bat | 3 +- PublishToMyGet.bat | 3 +- extra/serialization/README.MD | 2 + extra/serialization/build/misc.props | 2 +- .../Cosmos.Serialization.Nett.csproj | 23 + .../Cosmos.Serialization.Nett.xml | 509 ++++++++++++++++++ .../Cosmos/Serialization/NettSerializer.cs | 29 + .../Toml/Extensions/Extensions.Nett.Bytes.cs | 59 ++ .../Toml/Extensions/Extensions.Nett.Object.cs | 26 + .../Toml/Extensions/Extensions.Nett.Pack.cs | 130 +++++ .../Toml/Extensions/Extensions.Nett.Stream.cs | 44 ++ .../Toml/Extensions/Extensions.Nett.String.cs | 43 ++ .../Toml/Nett/NettHelper.Async.Pack.cs | 94 ++++ .../Toml/Nett/NettHelper.Async.cs | 78 +++ .../Toml/Nett/NettHelper.Sync.Pack.cs | 94 ++++ .../Toml/Nett/NettHelper.Sync.cs | 78 +++ .../Serialization/Toml/Nett/NettManager.cs | 28 + .../Cosmos.Test.Serialization.NettTest.csproj | 20 + .../NiceModel.cs | 13 + .../NiceType.cs | 6 + .../UnitTest.cs | 117 ++++ .../UnitTestAsync.cs | 118 ++++ .../YamlTest.cs | 36 ++ .../YamlTestAsync.cs | 37 ++ .../Cosmos.Abstractions.xml | 6 + .../Cosmos/Serialization/ITomlSerializer.cs | 7 + 27 files changed, 1617 insertions(+), 4 deletions(-) create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos.Serialization.Nett.csproj create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos.Serialization.Nett.xml create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/NettSerializer.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Bytes.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Object.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Pack.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Stream.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.String.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Async.Pack.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Async.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Sync.Pack.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Sync.cs create mode 100644 extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettManager.cs create mode 100644 extra/serialization/tests/Cosmos.Test.Serialization.NettTest/Cosmos.Test.Serialization.NettTest.csproj create mode 100644 extra/serialization/tests/Cosmos.Test.Serialization.NettTest/NiceModel.cs create mode 100644 extra/serialization/tests/Cosmos.Test.Serialization.NettTest/NiceType.cs create mode 100644 extra/serialization/tests/Cosmos.Test.Serialization.NettTest/UnitTest.cs create mode 100644 extra/serialization/tests/Cosmos.Test.Serialization.NettTest/UnitTestAsync.cs create mode 100644 extra/serialization/tests/Cosmos.Test.Serialization.NettTest/YamlTest.cs create mode 100644 extra/serialization/tests/Cosmos.Test.Serialization.NettTest/YamlTestAsync.cs create mode 100644 src/Cosmos.Abstractions/Cosmos/Serialization/ITomlSerializer.cs diff --git a/Cosmos.Standard.sln b/Cosmos.Standard.sln index 4daef125..7ad082aa 100644 --- a/Cosmos.Standard.sln +++ b/Cosmos.Standard.sln @@ -10,8 +10,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution LICENSE = LICENSE NuGet.config = NuGet.config Publish.bat = Publish.bat - PublishToMyGet.bat = PublishToMyGet.bat README.md = README.md + PublishToMyGet.bat = PublishToMyGet.bat EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0F01E2EF-3398-47CB-B5CB-33AF122A1BC7}" @@ -165,6 +165,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Test.Serialization.Y EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Extensions.Optionals", "src\Cosmos.Extensions.Optionals\Cosmos.Extensions.Optionals.csproj", "{43F1A15E-04EA-405F-8115-B3DD3DDD6B3B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Serialization.Nett", "extra\serialization\src\Cosmos.Serialization.Nett\Cosmos.Serialization.Nett.csproj", "{B1A584BE-EE50-4EF3-AC49-1E3FB91545E2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Test.Serialization.NettTest", "extra\serialization\tests\Cosmos.Test.Serialization.NettTest\Cosmos.Test.Serialization.NettTest.csproj", "{57DA8994-BA86-4FB8-BA92-CFB09FDE0A55}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -379,6 +383,14 @@ Global {43F1A15E-04EA-405F-8115-B3DD3DDD6B3B}.Debug|Any CPU.Build.0 = Debug|Any CPU {43F1A15E-04EA-405F-8115-B3DD3DDD6B3B}.Release|Any CPU.ActiveCfg = Release|Any CPU {43F1A15E-04EA-405F-8115-B3DD3DDD6B3B}.Release|Any CPU.Build.0 = Release|Any CPU + {B1A584BE-EE50-4EF3-AC49-1E3FB91545E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1A584BE-EE50-4EF3-AC49-1E3FB91545E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1A584BE-EE50-4EF3-AC49-1E3FB91545E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1A584BE-EE50-4EF3-AC49-1E3FB91545E2}.Release|Any CPU.Build.0 = Release|Any CPU + {57DA8994-BA86-4FB8-BA92-CFB09FDE0A55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57DA8994-BA86-4FB8-BA92-CFB09FDE0A55}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57DA8994-BA86-4FB8-BA92-CFB09FDE0A55}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57DA8994-BA86-4FB8-BA92-CFB09FDE0A55}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -446,6 +458,8 @@ Global {60B1F9E9-300B-4944-8409-B434E6CF9AC2} = {66C97C79-C2AE-49DD-8622-CAC7DD71F21B} {FB8BD44F-F65D-4944-8F1B-CD72CF8EBBAE} = {66C97C79-C2AE-49DD-8622-CAC7DD71F21B} {43F1A15E-04EA-405F-8115-B3DD3DDD6B3B} = {BDBDE50C-D11B-4B8B-8349-0B6681CC98FF} + {B1A584BE-EE50-4EF3-AC49-1E3FB91545E2} = {87D7302C-14EA-46B4-9324-0E42E39C100D} + {57DA8994-BA86-4FB8-BA92-CFB09FDE0A55} = {66C97C79-C2AE-49DD-8622-CAC7DD71F21B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D68A6AF5-79FE-4679-AD20-67D6CFCF75B4} diff --git a/Publish.bat b/Publish.bat index d19fb759..5b402f8a 100644 --- a/Publish.bat +++ b/Publish.bat @@ -27,12 +27,13 @@ dotnet pack src/Cosmos.Standard -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.serialization.Xml -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Jil -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Lit -c Release -o nuget_pub +dotnet pack extra/serialization/src/Cosmos.Serialization.Nett -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.serialization.Binary -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Swifter -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Utf8Json -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Protobuf -c Release -o nuget_pub -dotnet pack extra/serialization/src/Cosmos.Serialization.KoobooJson -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.SharpYaml -c Release -o nuget_pub +dotnet pack extra/serialization/src/Cosmos.Serialization.KoobooJson -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.YamlDotNet -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.MsgPackCli -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.MessagePack -c Release -o nuget_pub diff --git a/PublishToMyGet.bat b/PublishToMyGet.bat index 45bc9335..b4e4118c 100644 --- a/PublishToMyGet.bat +++ b/PublishToMyGet.bat @@ -27,12 +27,13 @@ dotnet pack src/Cosmos.Standard -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.serialization.Xml -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Jil -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Lit -c Release -o nuget_pub +dotnet pack extra/serialization/src/Cosmos.Serialization.Nett -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.serialization.Binary -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Swifter -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Utf8Json -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.Protobuf -c Release -o nuget_pub -dotnet pack extra/serialization/src/Cosmos.Serialization.KoobooJson -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.SharpYaml -c Release -o nuget_pub +dotnet pack extra/serialization/src/Cosmos.Serialization.KoobooJson -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.YamlDotNet -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.MsgPackCli -c Release -o nuget_pub dotnet pack extra/serialization/src/Cosmos.Serialization.MessagePack -c Release -o nuget_pub diff --git a/extra/serialization/README.MD b/extra/serialization/README.MD index 04277722..991bf8d1 100644 --- a/extra/serialization/README.MD +++ b/extra/serialization/README.MD @@ -17,6 +17,8 @@ Cosmos.Serialization provides several serializers and extensions: - Yaml - Cosmos.Serialization.YamlDotNet - Cosmos.Serialization.SharpYaml +- Toml + - Cosmos.Serialization.Nett - Binary - Cosmos.Serialization.Binary - Protobuf diff --git a/extra/serialization/build/misc.props b/extra/serialization/build/misc.props index 57f024df..32bbe07e 100644 --- a/extra/serialization/build/misc.props +++ b/extra/serialization/build/misc.props @@ -9,6 +9,6 @@ - + \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos.Serialization.Nett.csproj b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos.Serialization.Nett.csproj new file mode 100644 index 00000000..197ea635 --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos.Serialization.Nett.csproj @@ -0,0 +1,23 @@ + + + + + + netcoreapp3.1;netstandard2.1;netstandard2.0;net461;net451 + + + + Cosmos.Serialization.Nett + Cosmos.Serialization.Nett + Nett TOML serializer extension for Cosmos base library + + + + + + + + + + + \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos.Serialization.Nett.xml b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos.Serialization.Nett.xml new file mode 100644 index 00000000..917d2ed6 --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos.Serialization.Nett.xml @@ -0,0 +1,509 @@ + + + + Cosmos.Serialization.Nett + + + + + Nett TOML Serializer + + + + + + + + + + + + + + + + + + + + + + + TomlDotNet extensions + + + TomlDotNet extensions + + + TomlDotNet extensions + + + Nett extensions + + + Nett extensions + + + + + To TomlDotNet bytes + + + + + + + + To TomlDotNet bytes async + + + + + + + + From TomlDotNet bytes + + + + + + + + From TomlDotNet bytes + + + + + + + + From TomlDotNet bytes async + + + + + + + + From TomlDotNet bytes async + + + + + + + + To Toml + + + + + + + + To Toml async + + + + + + + + Lit pack to + + + + + + + + Pack to + + + + + + + + Pack to + + + + + + + + Pack by + + + + + + + + Pack by + + + + + + + + Toml pack to + + + + + + + + Pack to async + + + + + + + + + Pack to async + + + + + + + + + Pack by + + + + + + + + Pack by + + + + + + + + Unpack + + + + + + + + Unpack + + + + + + + + Unpack async + + + + + + + + Unpack async + + + + + + + + To stream + + + + + + + + To stream + + + + + + + + To stream + + + + + + + + To stream + + + + + + + + From Toml + + + + + + + + From Toml + + + + + + + + From Toml async + + + + + + + + From Toml async + + + + + + + + Yaml Helper + + + Yaml Helper + + + Yaml Helper + + + Yaml Helper + + + + + Serialize async + + + + + + + + Serialize to bytes async + + + + + + + Deserialize async + + + + + + + + Deserialize async + + + + + + + + Deserialize + + + + + + + + Deserialize + + + + + + + + Pack async + + + + + + + + Pack + + + + + + + + Pack async + + + + + + + + Pack + + + + + + + + Unpack async + + + + + + + + Unpack async + + + + + + + + Serialize + + + + + + + + Serialize to bytes + + + + + + + Deserialize + + + + + + + + Deserialize + + + + + + + + Deserialize + + + + + + + + Deserialize + + + + + + + + Pack + + + + + + + + Pack + + + + + + + + Pack + + + + + + + + Pack + + + + + + + + Unpack + + + + + + + + Unpack + + + + + + + + Nett TOML manager + + + + + Gets or sets default TomlSettings + + + + + Gets or sets default encoding + + + + diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/NettSerializer.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/NettSerializer.cs new file mode 100644 index 00000000..97f61c2a --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/NettSerializer.cs @@ -0,0 +1,29 @@ +using System; +using System.Threading.Tasks; +using Cosmos.Serialization.Toml.Nett; + +namespace Cosmos.Serialization { + /// + /// Nett TOML Serializer + /// + public class NettSerializer : ITomlSerializer { + + /// + public string Serialize(T o) => NettHelper.Serialize(o); + + /// + public T Deserialize(string data) => NettHelper.Deserialize(data); + + /// + public object Deserialize(string data, Type type) => NettHelper.Deserialize(data, type); + + /// + public Task SerializeAsync(T o) => NettHelper.SerializeAsync(o); + + /// + public Task DeserializeAsync(string data) => NettHelper.DeserializeAsync(data); + + /// + public Task DeserializeAsync(string data, Type type) => NettHelper.DeserializeAsync(data, type); + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Bytes.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Bytes.cs new file mode 100644 index 00000000..ca1e908d --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Bytes.cs @@ -0,0 +1,59 @@ +using System; +using System.Threading.Tasks; +using Cosmos.Serialization.Toml.Nett; + +// ReSharper disable once CheckNamespace +namespace Cosmos.Serialization.Toml { + /// + /// TomlDotNet extensions + /// + public static partial class Extensions { + /// + /// To TomlDotNet bytes + /// + /// + /// + /// + public static byte[] ToTomlBytes(this T obj) => NettHelper.SerializeToBytes(obj); + + /// + /// To TomlDotNet bytes async + /// + /// + /// + /// + public static Task ToTomlBytesAsync(this T obj) => NettHelper.SerializeToBytesAsync(obj); + + /// + /// From TomlDotNet bytes + /// + /// + /// + /// + public static T FromTomlBytes(this byte[] data) => NettHelper.DeserializeFromBytes(data); + + /// + /// From TomlDotNet bytes + /// + /// + /// + /// + public static object FromTomlBytes(this byte[] data, Type type) => NettHelper.DeserializeFromBytes(data, type); + + /// + /// From TomlDotNet bytes async + /// + /// + /// + /// + public static Task FromTomlBytesAsync(this byte[] data) => NettHelper.DeserializeFromBytesAsync(data); + + /// + /// From TomlDotNet bytes async + /// + /// + /// + /// + public static Task FromTomlBytesAsync(this byte[] data, Type type) => NettHelper.DeserializeFromBytesAsync(data, type); + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Object.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Object.cs new file mode 100644 index 00000000..bcbf58fc --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Object.cs @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using Cosmos.Serialization.Toml.Nett; + +// ReSharper disable once CheckNamespace +namespace Cosmos.Serialization.Toml { + /// + /// TomlDotNet extensions + /// + public static partial class Extensions { + /// + /// To Toml + /// + /// + /// + /// + public static string ToToml(this T o) => NettHelper.Serialize(o); + + /// + /// To Toml async + /// + /// + /// + /// + public static Task ToTomlAsync(this T o) => NettHelper.SerializeAsync(o); + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Pack.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Pack.cs new file mode 100644 index 00000000..e271d0b5 --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Pack.cs @@ -0,0 +1,130 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using NettHelper = Cosmos.Serialization.Toml.Nett.NettHelper; + +// ReSharper disable once CheckNamespace +namespace Cosmos.Serialization.Toml { + /// + /// TomlDotNet extensions + /// + public static partial class Extensions { + /// + /// Lit pack to + /// + /// + /// + /// + public static Stream TomlPack(this T obj) => NettHelper.Pack(obj); + + /// + /// Pack to + /// + /// + /// + /// + public static void TomlPackTo(this T t, Stream stream) { + NettHelper.Pack(t, stream); + } + + /// + /// Pack to + /// + /// + /// + /// + public static void TomlPackTo(this object obj, Type type, Stream stream) { + NettHelper.Pack(obj, type, stream); + } + + /// + /// Pack by + /// + /// + /// + /// + public static void TomlPackBy(this Stream stream, T t) => NettHelper.Pack(t, stream); + + /// + /// Pack by + /// + /// + /// + /// + public static void TomlPackBy(this Stream stream, object obj, Type type) => NettHelper.Pack(obj, type, stream); + + /// + /// Toml pack to + /// + /// + /// + /// + public static Task TomlPackAsync(this T obj) => NettHelper.PackAsync(obj); + + /// + /// Pack to async + /// + /// + /// + /// + /// + public static async Task TomlPackToAsync(this T t, Stream stream) => await NettHelper.PackAsync(t, stream); + + /// + /// Pack to async + /// + /// + /// + /// + /// + public static async Task TomlPackToAsync(this object obj, Type type, Stream stream) => await NettHelper.PackAsync(obj, type, stream); + + /// + /// Pack by + /// + /// + /// + /// + public static async Task TomlPackByAsync(this Stream stream, T t) => await NettHelper.PackAsync(t, stream); + + /// + /// Pack by + /// + /// + /// + /// + public static async Task TomlPackByAsync(this Stream stream, object obj, Type type) => await NettHelper.PackAsync(obj, type, stream); + + /// + /// Unpack + /// + /// + /// + /// + public static T TomlUnpack(this Stream stream) => NettHelper.Unpack(stream); + + /// + /// Unpack + /// + /// + /// + /// + public static object TomlUnpack(this Stream stream, Type type) => NettHelper.Unpack(stream, type); + + /// + /// Unpack async + /// + /// + /// + /// + public static Task TomlUnpackAsync(this Stream stream) => NettHelper.UnpackAsync(stream); + + /// + /// Unpack async + /// + /// + /// + /// + public static Task TomlUnpackAsync(this Stream stream, Type type) => NettHelper.UnpackAsync(stream, type); + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Stream.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Stream.cs new file mode 100644 index 00000000..f7349d30 --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.Stream.cs @@ -0,0 +1,44 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Cosmos.Serialization.Toml.Nett; + +// ReSharper disable once CheckNamespace +namespace Cosmos.Serialization.Toml { + /// + /// Nett extensions + /// + public static partial class Extensions { + /// + /// To stream + /// + /// + /// + /// + public static Stream ToTomlStream(this T t) => NettHelper.Pack(t); + + /// + /// To stream + /// + /// + /// + /// + public static Stream ToTomlStream(this object obj, Type type) => NettHelper.Pack(obj, type); + + /// + /// To stream + /// + /// + /// + /// + public static async Task ToTomlStreamAsync(this T t) => await NettHelper.PackAsync(t); + + /// + /// To stream + /// + /// + /// + /// + public static async Task ToTomlStreamAsync(this object obj, Type type) => await NettHelper.PackAsync(obj, type); + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.String.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.String.cs new file mode 100644 index 00000000..1cf64f68 --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Extensions/Extensions.Nett.String.cs @@ -0,0 +1,43 @@ +using System; +using System.Threading.Tasks; +using Cosmos.Serialization.Toml.Nett; + +// ReSharper disable once CheckNamespace +namespace Cosmos.Serialization.Toml { + /// + /// Nett extensions + /// + public static partial class Extensions { + /// + /// From Toml + /// + /// + /// + /// + public static T FromToml(this string str) => NettHelper.Deserialize(str); + + /// + /// From Toml + /// + /// + /// + /// + public static object FromToml(this string str, Type type) => NettHelper.Deserialize(str, type); + + /// + /// From Toml async + /// + /// + /// + /// + public static Task FromTomlAsync(this string str) => NettHelper.DeserializeAsync(str); + + /// + /// From Toml async + /// + /// + /// + /// + public static Task FromTomlAsync(this string str, Type type) => NettHelper.DeserializeAsync(str, type); + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Async.Pack.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Async.Pack.cs new file mode 100644 index 00000000..778cb3d4 --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Async.Pack.cs @@ -0,0 +1,94 @@ +using System; +using System.IO; +using System.Threading.Tasks; + +namespace Cosmos.Serialization.Toml.Nett { + /// + /// Yaml Helper + /// + public static partial class NettHelper { + /// + /// Pack async + /// + /// + /// + /// + public static async Task PackAsync(T o) { + var ms = new MemoryStream(); + + if (o is null) + return ms; + + await PackAsync(o, ms); + + return ms; + } + + /// + /// Pack + /// + /// + /// + /// + public static async Task PackAsync(object o, Type type) { + var ms = new MemoryStream(); + + if (o is null) + return ms; + + await PackAsync(o, type, ms); + + return ms; + } + + /// + /// Pack async + /// + /// + /// + /// + public static async Task PackAsync(T o, Stream stream) { + if (o == null || !stream.CanWrite) + return; + + await Task.Run(() => Pack(o, stream)); + } + + /// + /// Pack + /// + /// + /// + /// + public static async Task PackAsync(object o, Type type, Stream stream) { + if (o == null || !stream.CanWrite) + return; + + await Task.Run(() => Pack(o, type, stream)); + } + + /// + /// Unpack async + /// + /// + /// + /// + public static async Task UnpackAsync(Stream stream) { + return stream == null + ? default + : await Task.Run(() => Unpack(stream)); + } + + /// + /// Unpack async + /// + /// + /// + /// + public static async Task UnpackAsync(Stream stream, Type type) { + return stream == null + ? null + : await Task.Run(() => Unpack(stream, type)); + } + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Async.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Async.cs new file mode 100644 index 00000000..a316574f --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Async.cs @@ -0,0 +1,78 @@ +using System; +using System.Threading.Tasks; + +namespace Cosmos.Serialization.Toml.Nett { + /// + /// Yaml Helper + /// + public static partial class NettHelper { + /// + /// Serialize async + /// + /// + /// + /// + public static Task SerializeAsync(T o) { + return Task.Run(() => Serialize(o)); + } + + /// + /// Serialize to bytes async + /// + /// + /// + public static async Task SerializeToBytesAsync(T o) { + return o is null + ? new byte[0] + : NettManager.DefaultEncoding.GetBytes(await SerializeAsync(o)); + } + + /// + /// Deserialize async + /// + /// + /// + /// + public static async Task DeserializeAsync(string data) { + return string.IsNullOrWhiteSpace(data) + ? default + : await Task.Run(() => Deserialize(data)); + } + + /// + /// Deserialize async + /// + /// + /// + /// + public static async Task DeserializeAsync(string data, Type type) { + return string.IsNullOrWhiteSpace(data) + ? null + : await Task.Run(() => Deserialize(data, type)); + } + + /// + /// Deserialize + /// + /// + /// + /// + public static async Task DeserializeFromBytesAsync(byte[] data) { + return data is null || data.Length is 0 + ? default + : await DeserializeAsync(NettManager.DefaultEncoding.GetString(data)); + } + + /// + /// Deserialize + /// + /// + /// + /// + public static async Task DeserializeFromBytesAsync(byte[] data, Type type) { + return data is null || data.Length is 0 + ? null + : await DeserializeAsync(NettManager.DefaultEncoding.GetString(data), type); + } + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Sync.Pack.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Sync.Pack.cs new file mode 100644 index 00000000..e081c085 --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Sync.Pack.cs @@ -0,0 +1,94 @@ +using System; +using System.IO; +using Tommy = Nett.Toml; + +namespace Cosmos.Serialization.Toml.Nett { + /// + /// Yaml Helper + /// + public static partial class NettHelper { + /// + /// Pack + /// + /// + /// + /// + public static Stream Pack(T o) { + var ms = new MemoryStream(); + + if (o is null) + return ms; + + Pack(o, ms); + + return ms; + } + + /// + /// Pack + /// + /// + /// + /// + public static Stream Pack(object o, Type type) { + var ms = new MemoryStream(); + + if (o is null) + return ms; + + Pack(o, type, ms); + + return ms; + } + + /// + /// Pack + /// + /// + /// + /// + public static void Pack(T o, Stream stream) { + if (o is null || !stream.CanWrite) + return; + + Tommy.WriteStream(o, stream, NettManager.DefaultSettings); + } + + /// + /// Pack + /// + /// + /// + /// + public static void Pack(object o, Type type, Stream stream) { + if (o is null || !stream.CanWrite) + return; + + Tommy.WriteStream(o, stream, NettManager.DefaultSettings); + } + + /// + /// Unpack + /// + /// + /// + /// + public static T Unpack(Stream stream) { + return stream == null + ? default + : Tommy.ReadStream(stream, NettManager.DefaultSettings); + } + + /// + /// Unpack + /// + /// + /// + /// + public static object Unpack(Stream stream, Type type) { + return stream is null + ? null + : Tommy.ReadStream(stream, NettManager.DefaultSettings).Get(type); + } + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Sync.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Sync.cs new file mode 100644 index 00000000..642f5612 --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettHelper.Sync.cs @@ -0,0 +1,78 @@ +using System; +using Tommy = Nett.Toml; + +namespace Cosmos.Serialization.Toml.Nett { + /// + /// Yaml Helper + /// + public static partial class NettHelper { + /// + /// Serialize + /// + /// + /// + /// + public static string Serialize(T o) { + return Tommy.WriteString(o, NettManager.DefaultSettings); + } + + /// + /// Serialize to bytes + /// + /// + /// + public static byte[] SerializeToBytes(T o) { + return o is null + ? new byte[0] + : NettManager.DefaultEncoding.GetBytes(Serialize(o)); + } + + /// + /// Deserialize + /// + /// + /// + /// + public static T Deserialize(string data) { + return string.IsNullOrWhiteSpace(data) + ? default + : Tommy.ReadString(data, NettManager.DefaultSettings); + } + + /// + /// Deserialize + /// + /// + /// + /// + public static object Deserialize(string data, Type type) { + return string.IsNullOrWhiteSpace(data) + ? null + : Tommy.ReadString(data, NettManager.DefaultSettings).Get(type); + } + + /// + /// Deserialize + /// + /// + /// + /// + public static T DeserializeFromBytes(byte[] data) { + return data is null || data.Length is 0 + ? default + : Deserialize(NettManager.DefaultEncoding.GetString(data)); + } + + /// + /// Deserialize + /// + /// + /// + /// + public static object DeserializeFromBytes(byte[] data, Type type) { + return data is null || data.Length is 0 + ? null + : Deserialize(NettManager.DefaultEncoding.GetString(data), type); + } + } +} \ No newline at end of file diff --git a/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettManager.cs b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettManager.cs new file mode 100644 index 00000000..16099acb --- /dev/null +++ b/extra/serialization/src/Cosmos.Serialization.Nett/Cosmos/Serialization/Toml/Nett/NettManager.cs @@ -0,0 +1,28 @@ +using System.Text; +using Nett; + +namespace Cosmos.Serialization.Toml.Nett { + /// + /// Nett TOML manager + /// + public static class NettManager { + private static Encoding _encoding = Encoding.UTF8; + private static TomlSettings _settings = TomlSettings.Create(); + + /// + /// Gets or sets default TomlSettings + /// + public static TomlSettings DefaultSettings { + get => _settings; + set => _settings = value ?? _settings; + } + + /// + /// Gets or sets default encoding + /// + public static Encoding DefaultEncoding { + get => _encoding; + set => _encoding = value ?? _encoding; + } + } +} \ No newline at end of file diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/Cosmos.Test.Serialization.NettTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/Cosmos.Test.Serialization.NettTest.csproj new file mode 100644 index 00000000..da91b095 --- /dev/null +++ b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/Cosmos.Test.Serialization.NettTest.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/NiceModel.cs b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/NiceModel.cs new file mode 100644 index 00000000..4f091e77 --- /dev/null +++ b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/NiceModel.cs @@ -0,0 +1,13 @@ +using System; + +namespace Cosmos.Test.Serialization.NettTest { + [Serializable] + public class NiceModel { + public string Id { get; set; } + public string Name { get; set; } + public NiceType NiceType { get; set; } + public int Count { get; set; } + public DateTime CreatedTime { get; set; } + public bool IsValid { get; set; } + } +} \ No newline at end of file diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/NiceType.cs b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/NiceType.cs new file mode 100644 index 00000000..ce24704d --- /dev/null +++ b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/NiceType.cs @@ -0,0 +1,6 @@ +namespace Cosmos.Test.Serialization.NettTest { + public enum NiceType { + Yes, + No + } +} \ No newline at end of file diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/UnitTest.cs b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/UnitTest.cs new file mode 100644 index 00000000..6af6eb54 --- /dev/null +++ b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/UnitTest.cs @@ -0,0 +1,117 @@ +using System; +using System.IO; +using Cosmos.Serialization.Toml; +using Xunit; + +namespace Cosmos.Test.Serialization.NettTest { + public class UnitTest { + [Fact] + public void BytesTest() { + var model = CreateNiceModel(); + var bytes = model.ToTomlBytes(); + var backs = bytes.FromTomlBytes(); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(backs.Id, backs.Name, backs.NiceType, backs.Count, backs.CreatedTime, backs.IsValid)); + } + + [Fact] + public void NonGenericBytesTest() { + var model = CreateNiceModel(); + var bytes = model.ToTomlBytes(); + var backs = (NiceModel) bytes.FromTomlBytes(typeof(NiceModel)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(backs.Id, backs.Name, backs.NiceType, backs.Count, backs.CreatedTime, backs.IsValid)); + } + + [Fact] + public void StreamTest() { + var model = CreateNiceModel(); + var stream1 = model.TomlPack(); + var stream2 = new MemoryStream(); + model.TomlPackTo(stream2); + var stream3 = new MemoryStream(); + stream3.TomlPackBy(model); + + var back1 = stream1.TomlUnpack(); + var back2 = stream2.TomlUnpack(); + var back3 = stream3.TomlUnpack(); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back2.Id, back2.Name, back2.NiceType, back2.Count, back2.CreatedTime, back2.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back3.Id, back3.Name, back3.NiceType, back3.Count, back3.CreatedTime, back3.IsValid)); + } + + [Fact] + public void NonGenericStreamTest() { + var model = CreateNiceModel(); + var stream1 = model.TomlPack(); + var stream2 = new MemoryStream(); + model.TomlPackTo(stream2); + var stream3 = new MemoryStream(); + stream3.TomlPackBy(model); + + var back1 = (NiceModel) stream1.TomlUnpack(typeof(NiceModel)); + var back2 = (NiceModel) stream2.TomlUnpack(typeof(NiceModel)); + var back3 = (NiceModel) stream3.TomlUnpack(typeof(NiceModel)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back2.Id, back2.Name, back2.NiceType, back2.Count, back2.CreatedTime, back2.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back3.Id, back3.Name, back3.NiceType, back3.Count, back3.CreatedTime, back3.IsValid)); + } + + [Fact] + public void StringTest() { + var model = CreateNiceModel(); + var json1 = model.ToToml(); + var back1 = json1.FromToml(); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + } + + [Fact] + public void NonGenericStringTest() { + var model = CreateNiceModel(); + var json1 = model.ToToml(); + var back1 = (NiceModel) json1.FromToml(typeof(NiceModel)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + } + + private static NiceModel CreateNiceModel() { + return new NiceModel { + Id = "123", + Name = "nice", + NiceType = NiceType.Yes, + Count = new Random().Next(0, 100), + // Why use ToUniversalTime? + // Please view: http://paiden.github.io/Nett/articles/pitfalls.html + CreatedTime = new DateTime(2019, 10, 1).ToUniversalTime(), + IsValid = true + }; + } + } +} \ No newline at end of file diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/UnitTestAsync.cs b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/UnitTestAsync.cs new file mode 100644 index 00000000..f6dff5e8 --- /dev/null +++ b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/UnitTestAsync.cs @@ -0,0 +1,118 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Cosmos.Serialization.Toml; +using Xunit; + +namespace Cosmos.Test.Serialization.NettTest { + public class UnitTestAsync { + [Fact] + public async Task BytesTest() { + var model = CreateNiceModel(); + var bytes = await model.ToTomlBytesAsync(); + var backs = await bytes.FromTomlBytesAsync(); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(backs.Id, backs.Name, backs.NiceType, backs.Count, backs.CreatedTime, backs.IsValid)); + } + + [Fact] + public async Task NonGenericBytesTest() { + var model = CreateNiceModel(); + var bytes = await model.ToTomlBytesAsync(); + var backs = (NiceModel) await bytes.FromTomlBytesAsync(typeof(NiceModel)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(backs.Id, backs.Name, backs.NiceType, backs.Count, backs.CreatedTime, backs.IsValid)); + } + + [Fact] + public async Task StreamTest() { + var model = CreateNiceModel(); + var stream1 = await model.TomlPackAsync(); + var stream2 = new MemoryStream(); + await model.TomlPackToAsync(stream2); + var stream3 = new MemoryStream(); + await stream3.TomlPackByAsync(model); + + var back1 = await stream1.TomlUnpackAsync(); + var back2 = await stream2.TomlUnpackAsync(); + var back3 = await stream3.TomlUnpackAsync(); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back2.Id, back2.Name, back2.NiceType, back2.Count, back2.CreatedTime, back2.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back3.Id, back3.Name, back3.NiceType, back3.Count, back3.CreatedTime, back3.IsValid)); + } + + [Fact] + public async Task NonGenericStreamTest() { + var model = CreateNiceModel(); + var stream1 = await model.TomlPackAsync(); + var stream2 = new MemoryStream(); + await model.TomlPackToAsync(stream2); + var stream3 = new MemoryStream(); + await stream3.TomlPackByAsync(model); + + var back1 = (NiceModel) await stream1.TomlUnpackAsync(typeof(NiceModel)); + var back2 = (NiceModel) await stream2.TomlUnpackAsync(typeof(NiceModel)); + var back3 = (NiceModel) await stream3.TomlUnpackAsync(typeof(NiceModel)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back2.Id, back2.Name, back2.NiceType, back2.Count, back2.CreatedTime, back2.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back3.Id, back3.Name, back3.NiceType, back3.Count, back3.CreatedTime, back3.IsValid)); + } + + [Fact] + public async Task StringTest() { + var model = CreateNiceModel(); + var json1 = await model.ToTomlAsync(); + var back1 = await json1.FromTomlAsync(); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + } + + [Fact] + public async Task NonGenericStringTest() { + var model = CreateNiceModel(); + var json1 = await model.ToTomlAsync(); + var back1 = (NiceModel) await json1.FromTomlAsync(typeof(NiceModel)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + } + + private static NiceModel CreateNiceModel() { + return new NiceModel { + Id = "123", + Name = "nice", + NiceType = NiceType.Yes, + Count = new Random().Next(0, 100), + // Why use ToUniversalTime? + // Please view: http://paiden.github.io/Nett/articles/pitfalls.html + CreatedTime = new DateTime(2019, 10, 1).ToUniversalTime(), + IsValid = true + }; + } + } +} \ No newline at end of file diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/YamlTest.cs b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/YamlTest.cs new file mode 100644 index 00000000..cbf70705 --- /dev/null +++ b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/YamlTest.cs @@ -0,0 +1,36 @@ +using System; +using Cosmos.Serialization.Toml; +using Xunit; + +namespace Cosmos.Test.Serialization.NettTest { + public class YamlTest { + [Fact] + public void BasicJsonTest() { + var model = CreateNiceModel(); + var json1 = model.ToToml(); + var back1 = json1.FromToml(); + var back2 = (NiceModel) json1.FromToml(typeof(NiceModel)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back2.Id, back2.Name, back2.NiceType, back2.Count, back2.CreatedTime, back2.IsValid)); + } + + private static NiceModel CreateNiceModel() { + return new NiceModel { + Id = "123", + Name = "nice", + NiceType = NiceType.Yes, + Count = new Random().Next(0, 100), + // Why use ToUniversalTime? + // Please view: http://paiden.github.io/Nett/articles/pitfalls.html + CreatedTime = new DateTime(2019, 10, 1).ToUniversalTime(), + IsValid = true + }; + } + } +} \ No newline at end of file diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/YamlTestAsync.cs b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/YamlTestAsync.cs new file mode 100644 index 00000000..56ef5654 --- /dev/null +++ b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/YamlTestAsync.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Cosmos.Serialization.Toml; +using Xunit; + +namespace Cosmos.Test.Serialization.NettTest { + public class YamlTestAsync { + [Fact] + public async Task BasicJsonTest() { + var model = CreateNiceModel(); + var json1 = await model.ToTomlAsync(); + var back1 = await json1.FromTomlAsync(); + var back2 = (NiceModel) await json1.FromTomlAsync(typeof(NiceModel)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back1.Id, back1.Name, back1.NiceType, back1.Count, back1.CreatedTime, back1.IsValid)); + + Assert.Equal( + Tuple.Create(model.Id, model.Name, model.NiceType, model.Count, model.CreatedTime, model.IsValid), + Tuple.Create(back2.Id, back2.Name, back2.NiceType, back2.Count, back2.CreatedTime, back2.IsValid)); + } + + private static NiceModel CreateNiceModel() { + return new NiceModel { + Id = "123", + Name = "nice", + NiceType = NiceType.Yes, + Count = new Random().Next(0, 100), + // Why use ToUniversalTime? + // Please view: http://paiden.github.io/Nett/articles/pitfalls.html + CreatedTime = new DateTime(2019, 10, 1).ToUniversalTime(), + IsValid = true + }; + } + } +} \ No newline at end of file diff --git a/src/Cosmos.Abstractions/Cosmos.Abstractions.xml b/src/Cosmos.Abstractions/Cosmos.Abstractions.xml index d467b2a7..13a6d835 100644 --- a/src/Cosmos.Abstractions/Cosmos.Abstractions.xml +++ b/src/Cosmos.Abstractions/Cosmos.Abstractions.xml @@ -182,6 +182,12 @@ Google ProtoBuf 序列化器接口 + + + Interface of Toml serializer
+ Toml 序列化器接口 +
+
Interface of XML serializer
diff --git a/src/Cosmos.Abstractions/Cosmos/Serialization/ITomlSerializer.cs b/src/Cosmos.Abstractions/Cosmos/Serialization/ITomlSerializer.cs new file mode 100644 index 00000000..10c1803b --- /dev/null +++ b/src/Cosmos.Abstractions/Cosmos/Serialization/ITomlSerializer.cs @@ -0,0 +1,7 @@ +namespace Cosmos.Serialization { + /// + /// Interface of Toml serializer
+ /// Toml 序列化器接口 + ///
+ public interface ITomlSerializer : IObjectSerializer { } +} \ No newline at end of file From 295ae7fa8a477c2494c1b76e65216def9e430439 Mon Sep 17 00:00:00 2001 From: alexinea Date: Thu, 2 Jan 2020 16:07:25 +0800 Subject: [PATCH 07/15] Update misc things. --- build/misc.props | 2 +- build/version.props | 2 +- extra/dependency/build/misc.props | 2 +- extra/http/build/misc.props | 2 +- {msic => misc}/images/icon.png | Bin 5 files changed, 4 insertions(+), 4 deletions(-) rename {msic => misc}/images/icon.png (100%) diff --git a/build/misc.props b/build/misc.props index 1fb0f011..07f959c7 100644 --- a/build/misc.props +++ b/build/misc.props @@ -9,6 +9,6 @@ - + \ No newline at end of file diff --git a/build/version.props b/build/version.props index 96d92cb6..9fb5d78a 100644 --- a/build/version.props +++ b/build/version.props @@ -2,7 +2,7 @@ 0 1 - 2-alpha2-100015 + 2-beta1-101120 $(VersionMajor).$(VersionMinor).$(VersionPatch) diff --git a/extra/dependency/build/misc.props b/extra/dependency/build/misc.props index 18daca01..d16d0258 100644 --- a/extra/dependency/build/misc.props +++ b/extra/dependency/build/misc.props @@ -9,6 +9,6 @@ - + \ No newline at end of file diff --git a/extra/http/build/misc.props b/extra/http/build/misc.props index 57f024df..32bbe07e 100644 --- a/extra/http/build/misc.props +++ b/extra/http/build/misc.props @@ -9,6 +9,6 @@ - + \ No newline at end of file diff --git a/msic/images/icon.png b/misc/images/icon.png similarity index 100% rename from msic/images/icon.png rename to misc/images/icon.png From e2ba2f393509623c1fdb458288488d3767825ba9 Mon Sep 17 00:00:00 2001 From: alexinea Date: Sat, 4 Jan 2020 23:17:11 +0800 Subject: [PATCH 08/15] Code cleanup. --- src/Cosmos.Extensions.Reflection/Cosmos/InstanceScanner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/InstanceScanner.cs b/src/Cosmos.Extensions.Reflection/Cosmos/InstanceScanner.cs index 30534376..da09da3a 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/InstanceScanner.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/InstanceScanner.cs @@ -10,7 +10,7 @@ public abstract class InstanceScanner : TypeScanner { /// /// Create a new instance. /// - protected InstanceScanner() : base() { } + protected InstanceScanner() { } /// /// Create a new instance. From 746bcc943d1b8758cf8374fcfab832a952d6e07a Mon Sep 17 00:00:00 2001 From: alexinea Date: Sat, 4 Jan 2020 23:23:53 +0800 Subject: [PATCH 09/15] Add Fluent exception builder apis #28 --- .../Cosmos.Extensions.Reflection.csproj | 4 + .../Cosmos.Extensions.Reflection.xml | 207 ++++++++++++++++++ .../ExceptionArgConstants.cs | 40 ++++ .../ExceptionBuildingOptions.cs | 61 ++++++ .../Cosmos/Exceptions/ExceptionBuilder.cs | 21 ++ .../Cosmos/Exceptions/ExceptionBuilder`1.cs | 91 ++++++++ .../Exceptions/IFluentExceptionBuilder.cs | 59 +++++ .../Cosmos/NTypes.CtorArgDescriptor.cs | 50 +++++ .../Cosmos/NTypes.CtorMatchedResult.cs | 22 ++ .../Cosmos/NTypes.CtorTemplate.cs | 129 +++++++++++ .../Cosmos/NTypes.cs | 76 +++++++ .../Cosmos.Extensions.csproj | 4 - src/Cosmos.Extensions/Cosmos.Extensions.xml | 32 ++- src/Cosmos/Cosmos.csproj | 1 + src/Cosmos/Cosmos.xml | 15 ++ .../Cosmos/Exceptions/ExceptionHelper.cs | 0 .../Cosmos/Judgments/AssertionJudgment.cs | 31 ++- src/Cosmos/Cosmos/Types.InstanceCreator.cs | 62 ++++++ src/Cosmos/Cosmos/Types.cs | 54 +---- 19 files changed, 880 insertions(+), 79 deletions(-) create mode 100644 src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionArgConstants.cs create mode 100644 src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionBuildingOptions.cs create mode 100644 src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder.cs create mode 100644 src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs create mode 100644 src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs create mode 100644 src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorArgDescriptor.cs create mode 100644 src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorMatchedResult.cs create mode 100644 src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorTemplate.cs create mode 100644 src/Cosmos.Extensions.Reflection/Cosmos/NTypes.cs rename src/{Cosmos.Extensions => Cosmos}/Cosmos/Exceptions/ExceptionHelper.cs (100%) create mode 100644 src/Cosmos/Cosmos/Types.InstanceCreator.cs diff --git a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.csproj b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.csproj index 97975010..3bb2afe1 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.csproj +++ b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.csproj @@ -20,4 +20,8 @@ + + + + \ No newline at end of file diff --git a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml index 77f5dfbc..58db44c4 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml +++ b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml @@ -4,6 +4,150 @@ Cosmos.Extensions.Reflection + + + Exception arg constants + + + + + Message + + + + + Param Name + + + + + Inner exception + + + + + Inner exception, usage for InvalidProgramException + + + + + Actual value + + + + + Error code + + + + + Exception building options + + + + + Create a new instance of . + + + + + + Gets exception type + + + + + Add args + + + + + + + + + Add args + + + + + + + + + + Exception builder + + + + + Create a new instance of . + + + + + + + Exception builder + + + + + + Interface for fluent exception builder + + + + + Gets target exception's type + + + + + With inner exception + + + + + + + With parameter's name + + + + + + + With message + + + + + + + Actual value + + + + + + + Error code + + + + + + + Build and return exception instance + + + + + + Build and throw exception + + Type extensions @@ -412,6 +556,69 @@ + + + Advanced Types utilities + + + + + Create instance + + + + + + + + Create instance + + + + + + + + + Create instance + + + + + + + + Descriptor of argument + + + + + Create a new instance of . + + + + + Create a new instance of . + + + + + + + + Argument name + + + + + Argument value + + + + + Argument type + + Property access type diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionArgConstants.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionArgConstants.cs new file mode 100644 index 00000000..270ace39 --- /dev/null +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionArgConstants.cs @@ -0,0 +1,40 @@ +#if !NET451 + +namespace Cosmos.Exceptions.BuildingDescriptors { + /// + /// Exception arg constants + /// + public class ExceptionArgConstants { + /// + /// Message + /// + public const string MESSAGE = "message"; + + /// + /// Param Name + /// + public const string PARAM_NAME = "paramName"; + + /// + /// Inner exception + /// + public const string INNER_EXCEPTION = "innerException"; + + /// + /// Inner exception, usage for InvalidProgramException + /// + public const string INNER = "inner"; + + /// + /// Actual value + /// + public const string ACTUAL_VALUE = "actualValue"; + + /// + /// Error code + /// + public const string ERROR_CODE = "errorCode"; + } +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionBuildingOptions.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionBuildingOptions.cs new file mode 100644 index 00000000..15bde308 --- /dev/null +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionBuildingOptions.cs @@ -0,0 +1,61 @@ +#if !NET451 + +using System; +using System.Collections.Generic; + +namespace Cosmos.Exceptions.BuildingDescriptors { + /// + /// Exception building options + /// + public class ExceptionBuildingOptions { + private Dictionary _items = new Dictionary(); + + /// + /// Create a new instance of . + /// + /// + public ExceptionBuildingOptions(Type type) { + ExceptionType = type; + } + + /// + /// Gets exception type + /// + public Type ExceptionType { get; } + + internal IEnumerable ArgumentDescriptors => _items.Values; + + /// + /// Add args + /// + /// + /// + /// + /// + public ExceptionBuildingOptions AddArg(string argumentName, TArgVal argumentValue) { + if (_items.ContainsKey(argumentName)) + return this; + + _items.Add(argumentName, new CtorArgDescriptor(argumentName, argumentValue, typeof(TArgVal))); + return this; + } + + /// + /// Add args + /// + /// + /// + /// + /// + /// + public ExceptionBuildingOptions AddArg(string argumentName, TArgVal argumentValue, Func predicate) { + if (predicate(argumentValue)) { + AddArg(argumentName, argumentValue); + } + + return this; + } + } +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder.cs new file mode 100644 index 00000000..7b1814eb --- /dev/null +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder.cs @@ -0,0 +1,21 @@ +#if !NET451 + +using System; + +namespace Cosmos.Exceptions { + /// + /// Exception builder + /// + public static class ExceptionBuilder { + /// + /// Create a new instance of . + /// + /// + /// + public static IFluentExceptionBuilder Create() where TException : Exception { + return new ExceptionBuilder(); + } + } +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs new file mode 100644 index 00000000..f7eecf5b --- /dev/null +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs @@ -0,0 +1,91 @@ +#if !NET451 + +using System; +using Cosmos.Exceptions.BuildingDescriptors; + +namespace Cosmos.Exceptions { + /// + /// Exception builder + /// + /// + internal class ExceptionBuilder : IFluentExceptionBuilder where TException : Exception { + private readonly Type _typeOfException; + + public ExceptionBuilder() { + _typeOfException = Types.Of(); + } + + public Type TargetType => _typeOfException; + + private Exception _innerException; + + public IFluentExceptionBuilder InnerException(Exception innerException) { + if (innerException is null) + return this; + + _innerException = innerException; + return this; + } + + private string _paramName; + + public IFluentExceptionBuilder ParamName(string paramName) { + if (string.IsNullOrWhiteSpace(paramName)) + return this; + + _paramName = paramName; + return this; + } + + private string _message; + + public IFluentExceptionBuilder Message(string message) { + if (string.IsNullOrWhiteSpace(message)) + return this; + + _message = message; + return this; + } + + private object _actualValue; + + public IFluentExceptionBuilder ActualValue(object actualValue) { + _actualValue = actualValue; + return this; + } + + private int _errorCode; + + public IFluentExceptionBuilder ErrorCode(int errorCode) { + _errorCode = errorCode; + return this; + } + + private TException CachedException { get; set; } + + private void CreateAndCacheExceptionInstance() { + if (CachedException is null) { + var options = new ExceptionBuildingOptions(TargetType) + .AddArg(ExceptionArgConstants.INNER, _innerException, x => x != null) + .AddArg(ExceptionArgConstants.INNER_EXCEPTION, _innerException, x => x != null) + .AddArg(ExceptionArgConstants.MESSAGE, _message) + .AddArg(ExceptionArgConstants.PARAM_NAME, _paramName, x => !string.IsNullOrWhiteSpace(x)) + .AddArg(ExceptionArgConstants.ACTUAL_VALUE, _actualValue) + .AddArg(ExceptionArgConstants.ERROR_CODE, _errorCode); + CachedException = NTypes.CreateInstance(options.ExceptionType, options.ArgumentDescriptors); + } + } + + public TException Build() { + CreateAndCacheExceptionInstance(); + return CachedException; + } + + public void BuildAndThrow() { + CreateAndCacheExceptionInstance(); + ExceptionHelper.PrepareForRethrow(CachedException); + } + } +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs new file mode 100644 index 00000000..9db2aa54 --- /dev/null +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs @@ -0,0 +1,59 @@ +using System; + +namespace Cosmos.Exceptions { + /// + /// Interface for fluent exception builder + /// + public interface IFluentExceptionBuilder where TException : Exception { + /// + /// Gets target exception's type + /// + Type TargetType { get; } + + /// + /// With inner exception + /// + /// + /// + IFluentExceptionBuilder InnerException(Exception innerException); + + /// + /// With parameter's name + /// + /// + /// + IFluentExceptionBuilder ParamName(string paramName); + + /// + /// With message + /// + /// + /// + IFluentExceptionBuilder Message(string message); + + /// + /// Actual value + /// + /// + /// + IFluentExceptionBuilder ActualValue(object actualValue); + + /// + /// Error code + /// + /// + /// + IFluentExceptionBuilder ErrorCode(int errorCode); + + /// + /// Build and return exception instance + /// + /// + TException Build(); + + /// + /// Build and throw exception + /// + void BuildAndThrow(); + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorArgDescriptor.cs b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorArgDescriptor.cs new file mode 100644 index 00000000..d514ae14 --- /dev/null +++ b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorArgDescriptor.cs @@ -0,0 +1,50 @@ +#if !NET451 + +using System; + +/* + * Author: LanX + * 2020.01.03 + */ + +namespace Cosmos { + /// + /// Descriptor of argument + /// + public class CtorArgDescriptor { + + /// + /// Create a new instance of . + /// + public CtorArgDescriptor() { } + + /// + /// Create a new instance of . + /// + /// + /// + /// + public CtorArgDescriptor(string name, object value, Type type) { + Name = name; + Value = value; + Type = type; + } + + /// + /// Argument name + /// + public string Name { get; set; } + + /// + /// Argument value + /// + public object Value { get; set; } + + /// + /// Argument type + /// + public Type Type { get; set; } + } +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorMatchedResult.cs b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorMatchedResult.cs new file mode 100644 index 00000000..a92f8af9 --- /dev/null +++ b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorMatchedResult.cs @@ -0,0 +1,22 @@ +#if !NET451 + +/* + * Author: LanX + * 2020.01.03 + */ + +namespace Cosmos { + internal readonly struct CtorMatchedResult { + + public CtorMatchedResult(object[] values, int index) { + Values = values; + Index = index; + } + + public readonly object[] Values; + + public readonly int Index; + } +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorTemplate.cs b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorTemplate.cs new file mode 100644 index 00000000..2f0f688f --- /dev/null +++ b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorTemplate.cs @@ -0,0 +1,129 @@ +#if !NET451 + +using BTFindTree; +using Natasha; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +/* + * Author: LanX + * 2020.01.03 + */ + +namespace Cosmos { + internal class CtorTemplate { + public readonly Dictionary> Cache; + + // public readonly Dictionary RealNameMapping; + public readonly ConstructorInfo[] Ctors; + public readonly Dictionary CtorsMappings; + public readonly Func, CtorMatchedResult> GetIndex; + private readonly int _defaultCtorIndex; + public readonly Func[] Initor; + + private CtorTemplate(Type type) { + CtorsMappings = new Dictionary(); + Cache = new Dictionary>(); + Ctors = type.GetConstructors(); + Initor = new Func[Ctors.Length]; + + var maxParametersCount = 0; + + for (var i = 0; i < Ctors.Length; i++) { + + CtorsMappings[Ctors[i]] = i; + var parameters = Ctors[i].GetParameters(); + if (parameters.Length > maxParametersCount) { + maxParametersCount = parameters.Length; + } + + if (parameters.Length == 0) { + _defaultCtorIndex = i; + } + + var pairs = new ParameterInfo[parameters.Length]; + + for (var j = 0; j < parameters.Length; j++) { + pairs[parameters[j].Position] = parameters[j]; + var key = parameters[j].ParameterType.Name + parameters[j].Name; + if (!Cache.ContainsKey(key)) { + Cache[key] = new List<(ConstructorInfo, ParameterInfo)>(); + } + + Cache[key].Add((Ctors[i], parameters[j])); + } + + var parameterScript = new StringBuilder(); + for (int j = 0; j < pairs.Length; j += 1) { + parameterScript.AppendLine(@$"{pairs[j].Name}:arg[{j}]==null?default:({pairs[j].ParameterType.GetDevelopName()})arg[{j}]"); + if (j != pairs.Length - 1) { + parameterScript.Append(","); + } + } + + Initor[i] = NDomain.Random().Func($"return new {type.GetDevelopName()}({parameterScript});"); + + } + + var tempCache = new Dictionary(); + var script = new StringBuilder(); + script.Append($@" + if(arg == default || arg.Count() == 0) + {{ + return new CtorMatchedResult(null,{_defaultCtorIndex}); + }} + int[] index = new int[{Ctors.Length}]; + object[][] values = new object[{Ctors.Length}][]; + for(int i=0;i<{Ctors.Length};i+=1) + {{ + values[i] = new object[{maxParametersCount}]; + }} + foreach(var item in arg){{ + string temp = item.Type.Name + item.Name; +"); + foreach (var item in Cache) { + + var builder = new StringBuilder(); + foreach (var ctor in item.Value) { + builder.AppendLine($"index[{CtorsMappings[ctor.Item1]}]+=1;"); + builder.AppendLine($"values[{CtorsMappings[ctor.Item1]}][{ctor.Item2.Position}]=item.Value;"); + } + + tempCache[item.Key] = builder.ToString(); + + } + + script.AppendLine(BTFTemplate.GetPrecisionPointBTFScript(tempCache, "temp")); + script.AppendLine("}"); + script.AppendLine(@" + int maxValue = 0; + int maxIndex = 0; + for(int i=0;i, CtorMatchedResult>(script.ToString()); + + } + + public object GetCtor(IEnumerable test) { + var result = GetIndex(test); + return Initor[result.Index](result.Values); + } + + public static CtorTemplate Create() => new CtorTemplate(typeof(T)); + + public static CtorTemplate Create(Type type) => new CtorTemplate(type); + } +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.cs b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.cs new file mode 100644 index 00000000..8e207770 --- /dev/null +++ b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.cs @@ -0,0 +1,76 @@ +#if !NET451 + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Cosmos { + /// + /// Advanced Types utilities + /// + public static class NTypes { + /// + /// Create instance + /// + /// + /// + /// + public static TInstance CreateInstance(IEnumerable ctorArgDescriptors) { + if (ctorArgDescriptors is null) + return Types.CreateInstance(); + var descriptors = ctorArgDescriptors.ToList(); + return !descriptors.Any() + ? Types.CreateInstance() + : CreateInstanceCore(descriptors); + } + + /// + /// Create instance + /// + /// + /// + /// + /// + public static TInstance CreateInstance(Type type, IEnumerable ctorArgDescriptors) { + if (ctorArgDescriptors is null) + return Types.CreateInstance(); + var descriptors = ctorArgDescriptors.ToList(); + var instance = !descriptors.Any() + ? Types.CreateInstance(type) + : CreateInstanceCore(type, descriptors); + + return instance is TInstance ret ? ret : default; + } + + /// + /// Create instance + /// + /// + /// + /// + public static object CreateInstance(Type type, IEnumerable ctorArgDescriptors) { + if (ctorArgDescriptors is null) + return Types.CreateInstance(type); + var descriptors = ctorArgDescriptors.ToList(); + if (!descriptors.Any()) + return Types.CreateInstance(type); + return CreateInstanceCore(type, descriptors); + } + + private static TInstance CreateInstanceCore(IEnumerable ctorArgDescriptors) + => CreateInstanceCore(typeof(TInstance), ctorArgDescriptors) is TInstance ret ? ret : default; + + private static object CreateInstanceCore(Type type, IEnumerable ctorArgDescriptors) { + + /* + * Author: LanX + * 2020.01.03 + */ + + var template = CtorTemplate.Create(type); + return template.GetCtor(ctorArgDescriptors); + } + } +} + +#endif \ No newline at end of file diff --git a/src/Cosmos.Extensions/Cosmos.Extensions.csproj b/src/Cosmos.Extensions/Cosmos.Extensions.csproj index 78da8e5d..7b32deb5 100644 --- a/src/Cosmos.Extensions/Cosmos.Extensions.csproj +++ b/src/Cosmos.Extensions/Cosmos.Extensions.csproj @@ -16,10 +16,6 @@ - - - - diff --git a/src/Cosmos.Extensions/Cosmos.Extensions.xml b/src/Cosmos.Extensions/Cosmos.Extensions.xml index 505bc976..3abca560 100644 --- a/src/Cosmos.Extensions/Cosmos.Extensions.xml +++ b/src/Cosmos.Extensions/Cosmos.Extensions.xml @@ -970,18 +970,6 @@ - - - Exception helper - - - - - Prepare for rethrow - - - - 参数重绑定操作 @@ -4488,6 +4476,26 @@ + + + Interlocked util + + + + + Read + + + + + + + Read + + + + + Common join utils diff --git a/src/Cosmos/Cosmos.csproj b/src/Cosmos/Cosmos.csproj index b76ba25d..880cd5d7 100644 --- a/src/Cosmos/Cosmos.csproj +++ b/src/Cosmos/Cosmos.csproj @@ -30,6 +30,7 @@ + diff --git a/src/Cosmos/Cosmos.xml b/src/Cosmos/Cosmos.xml index 98f11152..00a36d0f 100644 --- a/src/Cosmos/Cosmos.xml +++ b/src/Cosmos/Cosmos.xml @@ -987,6 +987,18 @@ 枚举类型 成员名、值、实例均可 + + + Exception helper + + + + + Prepare for rethrow + + + + Assertion Judgment @@ -2088,6 +2100,9 @@ Type Utilities + + Type Utilities + diff --git a/src/Cosmos.Extensions/Cosmos/Exceptions/ExceptionHelper.cs b/src/Cosmos/Cosmos/Exceptions/ExceptionHelper.cs similarity index 100% rename from src/Cosmos.Extensions/Cosmos/Exceptions/ExceptionHelper.cs rename to src/Cosmos/Cosmos/Exceptions/ExceptionHelper.cs diff --git a/src/Cosmos/Cosmos/Judgments/AssertionJudgment.cs b/src/Cosmos/Cosmos/Judgments/AssertionJudgment.cs index 1ccb2aab..99c59d99 100644 --- a/src/Cosmos/Cosmos/Judgments/AssertionJudgment.cs +++ b/src/Cosmos/Cosmos/Judgments/AssertionJudgment.cs @@ -17,11 +17,15 @@ public static void Require(bool assertion, string message) where TEx if (assertion) return; - if (string.IsNullOrEmpty(message)) - throw new ArgumentNullException(nameof(message)); + Exception exception; - var exception = Types.CreateInstance(message); - throw exception; + if (string.IsNullOrEmpty(message)) { + exception = new ArgumentNullException(nameof(message)); + } else { + exception = Types.CreateInstance(message); + } + + Exceptions.ExceptionHelper.PrepareForRethrow(exception); } /// @@ -35,7 +39,8 @@ public static void Require2(bool assertion, params object[] exceptio return; var exception = Types.CreateInstance(exceptionParams); - throw exception; + + Exceptions.ExceptionHelper.PrepareForRethrow(exception); } /// @@ -51,12 +56,14 @@ public static void Require2Validation(bool assertion, params object[ var exception = Types.CreateInstance(exceptionParams); - throw exception switch { + var wrappedException = exception switch { ArgumentNullException __exception_01 => (Exception) ValidationErrors.Null(__exception_01), ArgumentOutOfRangeException __exception_02 => ValidationErrors.OutOfRange(__exception_02), ArgumentInvalidException __exception_03 => ValidationErrors.Invalid(__exception_03), _ => exception }; + + Exceptions.ExceptionHelper.PrepareForRethrow(wrappedException); } /// @@ -69,11 +76,15 @@ public static void Require3(bool assertion, CosmosExceptionOptions o if (assertion) return; - if (options == null) - throw new ArgumentNullException(nameof(options)); + Exception exception; + + if (options == null) { + exception = new ArgumentNullException(nameof(options)); + } else { + exception = Types.CreateInstance(options); + } - var exception = Types.CreateInstance(options); - throw exception; + Exceptions.ExceptionHelper.PrepareForRethrow(exception); } } } \ No newline at end of file diff --git a/src/Cosmos/Cosmos/Types.InstanceCreator.cs b/src/Cosmos/Cosmos/Types.InstanceCreator.cs new file mode 100644 index 00000000..e5f3b341 --- /dev/null +++ b/src/Cosmos/Cosmos/Types.InstanceCreator.cs @@ -0,0 +1,62 @@ +using System; +using System.Linq; +using AspectCore.Extensions.Reflection; + +namespace Cosmos { + /// + /// Type Utilities + /// + public static partial class Types { + + #region CreateInstance + + /// + /// Create instance + /// + /// Special type you need to return. + /// Arguments for such type's constructor + /// Instance of special type + public static TInstance CreateInstance(params object[] args) { + if (args is null || args.Length == 0) + return CreateInstanceCore(); + return CreateInstanceCore(args); + } + + /// + /// Create instance + /// + /// Special type you need to return. + /// Special type + /// Arguments for such type's constructor + /// Instance of special type + public static TInstance CreateInstance(Type type, params object[] args) + => CreateInstance(type, args) is TInstance ret ? ret : default; + + /// + /// Create instance + /// + /// Special type + /// Arguments for such type's constructor + /// Instance of special type + public static object CreateInstance(Type type, params object[] args) { + if (args is null || args.Length == 0) + return CreateInstanceCore(type); + return CreateInstanceCore(type, args); + } + + private static TInstance CreateInstanceCore() + => CreateInstanceCore(typeof(TInstance)) is TInstance ret ? ret : default; + + private static TInstance CreateInstanceCore(object[] args) + => CreateInstanceCore(typeof(TInstance), args) is TInstance ret ? ret : default; + + private static object CreateInstanceCore(Type type) + => type.GetConstructors().FirstOrDefault(x => !x.GetParameters().Any())?.GetReflector().Invoke(); + + private static object CreateInstanceCore(Type type, object[] args) + => type.GetConstructor(Of(args))?.GetReflector().Invoke(args); + + #endregion + + } +} \ No newline at end of file diff --git a/src/Cosmos/Cosmos/Types.cs b/src/Cosmos/Cosmos/Types.cs index 99e71e73..0e04b9b2 100644 --- a/src/Cosmos/Cosmos/Types.cs +++ b/src/Cosmos/Cosmos/Types.cs @@ -1,12 +1,11 @@ using System; using System.Linq; -using AspectCore.Extensions.Reflection; namespace Cosmos { /// /// Type Utilities /// - public static class Types { + public static partial class Types { #region Of @@ -139,56 +138,5 @@ bool _checkRawGenericType(Type test) public static Type GetRawTypeFromGenericClass() => GetRawTypeFromGenericClass(typeof(TGot), typeof(TGeneric)); #endregion - - #region CreateInstance - - /// - /// Create instance - /// - /// Special type you need to return. - /// Arguments for such type's constructor - /// Instance of special type - public static TInstance CreateInstance(params object[] args) { - if (args == null || args.Length == 0) - return CreateInstanceCore(); - return CreateInstanceCore(args); - } - - /// - /// Create instance - /// - /// Special type you need to return. - /// Special type - /// Arguments for such type's constructor - /// Instance of special type - public static TInstance CreateInstance(Type type, params object[] args) - => CreateInstance(type, args) is TInstance ret ? ret : default; - - /// - /// Create instance - /// - /// Special type - /// Arguments for such type's constructor - /// Instance of special type - public static object CreateInstance(Type type, params object[] args) { - if (args == null || args.Length == 0) - return CreateInstanceCore(type); - return CreateInstanceCore(type, args); - } - - private static TInstance CreateInstanceCore() - => CreateInstanceCore(typeof(TInstance)) is TInstance ret ? ret : default; - - private static TInstance CreateInstanceCore(object[] args) - => CreateInstanceCore(typeof(TInstance), args) is TInstance ret ? ret : default; - - private static object CreateInstanceCore(Type type) - => type.GetConstructors().FirstOrDefault(x => !x.GetParameters().Any())?.GetReflector().Invoke(); - - private static object CreateInstanceCore(Type type, object[] args) - => type.GetConstructor(Of(args))?.GetReflector().Invoke(args); - - #endregion - } } \ No newline at end of file From 3c3609f2130781bafc89cb4e7438c1ccb5ba8387 Mon Sep 17 00:00:00 2001 From: alexinea Date: Sun, 5 Jan 2020 16:27:42 +0800 Subject: [PATCH 10/15] Update dependency info. --- .../Cosmos.Test.Serialization.BinaryTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.JilTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.KoobooTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.LitTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.MessagePackageTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.MicrosoftJsonTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.MsgPackCliTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.NettTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.NewtonsoftTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.ProtobufTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.SharpYaml.csproj | 4 ++-- .../Cosmos.Test.Serialization.SwifterTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.Utf8JsonTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.XmlTest.csproj | 4 ++-- .../Cosmos.Test.Serialization.YamlDotNet.csproj | 4 ++-- .../Cosmos.Test.Serialization.ZeroFormatterTest.csproj | 4 ++-- .../Cosmos.Test.ScannerTestEntry.csproj | 2 +- test/Cosmos.Test/Cosmos.Test.csproj | 2 +- .../Cosmos.Tests.DateTimeTests.csproj | 2 +- test/Cosmos.Tests.GuavaTests/Cosmos.Tests.GuavaTests.csproj | 2 +- 20 files changed, 36 insertions(+), 36 deletions(-) diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.BinaryTest/Cosmos.Test.Serialization.BinaryTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.BinaryTest/Cosmos.Test.Serialization.BinaryTest.csproj index 9f49d535..ebc701bb 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.BinaryTest/Cosmos.Test.Serialization.BinaryTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.BinaryTest/Cosmos.Test.Serialization.BinaryTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.JilTest/Cosmos.Test.Serialization.JilTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.JilTest/Cosmos.Test.Serialization.JilTest.csproj index 941393a2..1bf753e4 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.JilTest/Cosmos.Test.Serialization.JilTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.JilTest/Cosmos.Test.Serialization.JilTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.KoobooTest/Cosmos.Test.Serialization.KoobooTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.KoobooTest/Cosmos.Test.Serialization.KoobooTest.csproj index c2d8c7ca..3d8dc6fd 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.KoobooTest/Cosmos.Test.Serialization.KoobooTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.KoobooTest/Cosmos.Test.Serialization.KoobooTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.LitTest/Cosmos.Test.Serialization.LitTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.LitTest/Cosmos.Test.Serialization.LitTest.csproj index c4f9af05..d715c3e4 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.LitTest/Cosmos.Test.Serialization.LitTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.LitTest/Cosmos.Test.Serialization.LitTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.MessagePackageTest/Cosmos.Test.Serialization.MessagePackageTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.MessagePackageTest/Cosmos.Test.Serialization.MessagePackageTest.csproj index 68bed5e0..68893f1c 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.MessagePackageTest/Cosmos.Test.Serialization.MessagePackageTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.MessagePackageTest/Cosmos.Test.Serialization.MessagePackageTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.MicrosoftJsonTest/Cosmos.Test.Serialization.MicrosoftJsonTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.MicrosoftJsonTest/Cosmos.Test.Serialization.MicrosoftJsonTest.csproj index f27fe924..654b387a 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.MicrosoftJsonTest/Cosmos.Test.Serialization.MicrosoftJsonTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.MicrosoftJsonTest/Cosmos.Test.Serialization.MicrosoftJsonTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.MsgPackCliTest/Cosmos.Test.Serialization.MsgPackCliTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.MsgPackCliTest/Cosmos.Test.Serialization.MsgPackCliTest.csproj index 9426f5f2..35336aa1 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.MsgPackCliTest/Cosmos.Test.Serialization.MsgPackCliTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.MsgPackCliTest/Cosmos.Test.Serialization.MsgPackCliTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/Cosmos.Test.Serialization.NettTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/Cosmos.Test.Serialization.NettTest.csproj index da91b095..cd0f953d 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/Cosmos.Test.Serialization.NettTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.NettTest/Cosmos.Test.Serialization.NettTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.NewtonsoftTest/Cosmos.Test.Serialization.NewtonsoftTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.NewtonsoftTest/Cosmos.Test.Serialization.NewtonsoftTest.csproj index ebf8065c..433f0e9c 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.NewtonsoftTest/Cosmos.Test.Serialization.NewtonsoftTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.NewtonsoftTest/Cosmos.Test.Serialization.NewtonsoftTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.ProtobufTest/Cosmos.Test.Serialization.ProtobufTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.ProtobufTest/Cosmos.Test.Serialization.ProtobufTest.csproj index 2f28e362..3ffe9d10 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.ProtobufTest/Cosmos.Test.Serialization.ProtobufTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.ProtobufTest/Cosmos.Test.Serialization.ProtobufTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.SharpYaml/Cosmos.Test.Serialization.SharpYaml.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.SharpYaml/Cosmos.Test.Serialization.SharpYaml.csproj index 510463f1..44da8dec 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.SharpYaml/Cosmos.Test.Serialization.SharpYaml.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.SharpYaml/Cosmos.Test.Serialization.SharpYaml.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.SwifterTest/Cosmos.Test.Serialization.SwifterTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.SwifterTest/Cosmos.Test.Serialization.SwifterTest.csproj index f15f1988..5b5514f2 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.SwifterTest/Cosmos.Test.Serialization.SwifterTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.SwifterTest/Cosmos.Test.Serialization.SwifterTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.Utf8JsonTest/Cosmos.Test.Serialization.Utf8JsonTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.Utf8JsonTest/Cosmos.Test.Serialization.Utf8JsonTest.csproj index 4a357cd0..619cf4b7 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.Utf8JsonTest/Cosmos.Test.Serialization.Utf8JsonTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.Utf8JsonTest/Cosmos.Test.Serialization.Utf8JsonTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.XmlTest/Cosmos.Test.Serialization.XmlTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.XmlTest/Cosmos.Test.Serialization.XmlTest.csproj index 4aa3aae8..d5dc1981 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.XmlTest/Cosmos.Test.Serialization.XmlTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.XmlTest/Cosmos.Test.Serialization.XmlTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.YamlDotNet/Cosmos.Test.Serialization.YamlDotNet.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.YamlDotNet/Cosmos.Test.Serialization.YamlDotNet.csproj index 8c7132ff..0a557192 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.YamlDotNet/Cosmos.Test.Serialization.YamlDotNet.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.YamlDotNet/Cosmos.Test.Serialization.YamlDotNet.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/extra/serialization/tests/Cosmos.Test.Serialization.ZeroFormatterTest/Cosmos.Test.Serialization.ZeroFormatterTest.csproj b/extra/serialization/tests/Cosmos.Test.Serialization.ZeroFormatterTest/Cosmos.Test.Serialization.ZeroFormatterTest.csproj index 42ac96db..2a4f34d1 100644 --- a/extra/serialization/tests/Cosmos.Test.Serialization.ZeroFormatterTest/Cosmos.Test.Serialization.ZeroFormatterTest.csproj +++ b/extra/serialization/tests/Cosmos.Test.Serialization.ZeroFormatterTest/Cosmos.Test.Serialization.ZeroFormatterTest.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/test/Cosmos.Test.ScannerTestEntry/Cosmos.Test.ScannerTestEntry.csproj b/test/Cosmos.Test.ScannerTestEntry/Cosmos.Test.ScannerTestEntry.csproj index af47b628..5a302b77 100644 --- a/test/Cosmos.Test.ScannerTestEntry/Cosmos.Test.ScannerTestEntry.csproj +++ b/test/Cosmos.Test.ScannerTestEntry/Cosmos.Test.ScannerTestEntry.csproj @@ -9,7 +9,7 @@ - + all diff --git a/test/Cosmos.Test/Cosmos.Test.csproj b/test/Cosmos.Test/Cosmos.Test.csproj index 0d36c403..ec026554 100644 --- a/test/Cosmos.Test/Cosmos.Test.csproj +++ b/test/Cosmos.Test/Cosmos.Test.csproj @@ -4,7 +4,7 @@ 7.2 - + diff --git a/test/Cosmos.Tests.DateTimeTests/Cosmos.Tests.DateTimeTests.csproj b/test/Cosmos.Tests.DateTimeTests/Cosmos.Tests.DateTimeTests.csproj index a4b5e7fb..b8d440c3 100644 --- a/test/Cosmos.Tests.DateTimeTests/Cosmos.Tests.DateTimeTests.csproj +++ b/test/Cosmos.Tests.DateTimeTests/Cosmos.Tests.DateTimeTests.csproj @@ -7,7 +7,7 @@ - + diff --git a/test/Cosmos.Tests.GuavaTests/Cosmos.Tests.GuavaTests.csproj b/test/Cosmos.Tests.GuavaTests/Cosmos.Tests.GuavaTests.csproj index 32a14414..c7ad39c1 100644 --- a/test/Cosmos.Tests.GuavaTests/Cosmos.Tests.GuavaTests.csproj +++ b/test/Cosmos.Tests.GuavaTests/Cosmos.Tests.GuavaTests.csproj @@ -7,7 +7,7 @@ - + From a3a66a48c2c72b3b46df72d89f69241e95b8ab1d Mon Sep 17 00:00:00 2001 From: alexinea Date: Sun, 5 Jan 2020 16:30:55 +0800 Subject: [PATCH 11/15] Add Base32Util, InterlockedUtil and Concurrent collections.. --- .../Concurrent/BoundedConcurrentQueue.cs | 91 +++++++++++ .../Collections/Concurrent/ConcurrentSet`1.cs | 74 +++++++++ .../Cosmos/InterlockedUtil.cs | 27 ++++ .../Cosmos/Conversions/Base32Conversion.cs | 145 ++++++++++++++++++ 4 files changed, 337 insertions(+) create mode 100644 src/Cosmos.Extensions.Asyncs/Cosmos/Collections/Concurrent/BoundedConcurrentQueue.cs create mode 100644 src/Cosmos.Extensions.Asyncs/Cosmos/Collections/Concurrent/ConcurrentSet`1.cs create mode 100644 src/Cosmos.Extensions/Cosmos/InterlockedUtil.cs create mode 100644 src/Cosmos/Cosmos/Conversions/Base32Conversion.cs diff --git a/src/Cosmos.Extensions.Asyncs/Cosmos/Collections/Concurrent/BoundedConcurrentQueue.cs b/src/Cosmos.Extensions.Asyncs/Cosmos/Collections/Concurrent/BoundedConcurrentQueue.cs new file mode 100644 index 00000000..ecb4cc71 --- /dev/null +++ b/src/Cosmos.Extensions.Asyncs/Cosmos/Collections/Concurrent/BoundedConcurrentQueue.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Concurrent; +using System.Threading; + +namespace Cosmos.Collections.Concurrent { + /// + /// Bounded concurrent queue + /// + /// + public class BoundedConcurrentQueue { + // ReSharper disable once InconsistentNaming + private const int NON_BOUNDED = -1; + private readonly ConcurrentQueue _queue = new ConcurrentQueue(); + private readonly int _queueLimit; + private int _counter; + + /// + /// Create a new instance of . + /// + public BoundedConcurrentQueue() { + _queueLimit = NON_BOUNDED; + } + + /// + /// Create a new instance of . + /// + /// + /// + public BoundedConcurrentQueue(int queueLimit) { + if (queueLimit <= 0) + throw new ArgumentOutOfRangeException(nameof(queueLimit), "queue limit must be positive"); + + _queueLimit = queueLimit; + } + + /// + /// Gets queue count + /// + public int Count => _queue.Count; + + /// + /// Try dequeue + /// + /// + /// + public bool TryDequeue(out T item) { + if (_queueLimit == NON_BOUNDED) + return _queue.TryDequeue(out item); + + var result = false; + try { + //... + } finally // prevent state corrupt while aborting + { + if (_queue.TryDequeue(out item)) { + Interlocked.Decrement(ref _counter); + result = true; + } + } + + return result; + } + + /// + /// Try enqueue + /// + /// + /// + public bool TryEnqueue(T item) { + if (_queueLimit == NON_BOUNDED) { + _queue.Enqueue(item); + return true; + } + + var result = true; + + try { + //... + } finally { + if (Interlocked.Increment(ref _counter) <= _queueLimit) { + _queue.Enqueue(item); + } else { + Interlocked.Decrement(ref _counter); + result = false; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions.Asyncs/Cosmos/Collections/Concurrent/ConcurrentSet`1.cs b/src/Cosmos.Extensions.Asyncs/Cosmos/Collections/Concurrent/ConcurrentSet`1.cs new file mode 100644 index 00000000..216a6b1f --- /dev/null +++ b/src/Cosmos.Extensions.Asyncs/Cosmos/Collections/Concurrent/ConcurrentSet`1.cs @@ -0,0 +1,74 @@ +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; + +namespace Cosmos.Collections.Concurrent { + /// + /// Concurrent Set + /// + /// + public class ConcurrentSet : IReadOnlyCollection, ICollection { + private readonly ConcurrentDictionary _dictionary = new ConcurrentDictionary(); + + /// + /// Is empty + /// + public bool IsEmpty => _dictionary.IsEmpty; + + /// + public int Count => _dictionary.Count; + + /// + public bool IsReadOnly => false; + + /// + public bool Contains(T t) => _dictionary.ContainsKey(t); + + /// + /// Try add + /// + /// + /// + public bool TryAdd(T t) => _dictionary.TryAdd(t, false); + + /// + /// Try remove + /// + /// + /// + public bool TryRemove(T t) => _dictionary.TryRemove(t, out _); + + /// + /// Values + /// + /// + public ICollection Values() => _dictionary.Keys; + + /// + public void Clear() => _dictionary.Clear(); + + /// + public IEnumerator GetEnumerator() { + return _dictionary.Keys.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + /// + public void Add(T item) { + TryAdd(item); + } + + /// + public void CopyTo(T[] array, int arrayIndex) { + _dictionary.Keys.CopyTo(array, arrayIndex); + } + + /// + public bool Remove(T item) { + return TryRemove(item); + } + } +} \ No newline at end of file diff --git a/src/Cosmos.Extensions/Cosmos/InterlockedUtil.cs b/src/Cosmos.Extensions/Cosmos/InterlockedUtil.cs new file mode 100644 index 00000000..82be8e46 --- /dev/null +++ b/src/Cosmos.Extensions/Cosmos/InterlockedUtil.cs @@ -0,0 +1,27 @@ +using System.Threading; + +namespace Cosmos { + /// + /// Interlocked util + /// + public static class InterlockedUtil { + /// + /// Read + /// + /// + /// + public static int Read(ref int value) { + return Interlocked.CompareExchange(ref value, 0, 0); + } + + /// + /// Read + /// + /// + /// + /// + public static T Read(ref T value) where T : class { + return Interlocked.CompareExchange(ref value, null, null); + } + } +} \ No newline at end of file diff --git a/src/Cosmos/Cosmos/Conversions/Base32Conversion.cs b/src/Cosmos/Cosmos/Conversions/Base32Conversion.cs new file mode 100644 index 00000000..a88c6a2e --- /dev/null +++ b/src/Cosmos/Cosmos/Conversions/Base32Conversion.cs @@ -0,0 +1,145 @@ +using System; +using System.Text; + +namespace Cosmos.Conversions { + /// + /// Base32 Conversion Utilities + /// + public static class Base32Conversion { + /// + /// Base32 encode + /// + /// + /// + /// + public static string ToBase32String(byte[] bytes) { + if (bytes is null || bytes.Length == 0) { + throw new ArgumentNullException(nameof(bytes)); + } + + var charCount = (int) Math.Ceiling(bytes.Length / 5d) * 8; + var returnArray = new char[charCount]; + + byte nextChar = 0, bitsRemaining = 5; + var arrayIndex = 0; + + foreach (var b in bytes) { + nextChar = (byte) (nextChar | (b >> (8 - bitsRemaining))); + returnArray[arrayIndex++] = ValueToChar(nextChar); + + if (bitsRemaining < 4) { + nextChar = (byte) ((b >> (3 - bitsRemaining)) & 31); + returnArray[arrayIndex++] = ValueToChar(nextChar); + bitsRemaining += 5; + } + + bitsRemaining -= 3; + nextChar = (byte) ((b << bitsRemaining) & 31); + } + + //if we didn't end with a full char + if (arrayIndex != charCount) { + returnArray[arrayIndex++] = ValueToChar(nextChar); + while (arrayIndex != charCount) returnArray[arrayIndex++] = '='; //padding + } + + return new string(returnArray); + } + + /// + /// Base32 encode + /// + /// + /// + /// + /// + public static string ToBase32String(byte[] bytes, string data, Encoding encoding) { + return ToBase32String(encoding.GetBytes(data)); + } + + /// + /// Base32 decode + /// + /// + /// + /// + public static string FromBase32String(string data, Encoding encoding) { + return encoding.GetString(FromBase32StringToBytes(data)); + } + + /// + /// Base32 decode + /// + /// + /// + /// + public static byte[] FromBase32StringToBytes(string data) { + if (data is null) { + throw new ArgumentNullException(nameof(data)); + } + + data = data.TrimEnd('='); //remove padding characters + var byteCount = data.Length * 5 / 8; //this must be TRUNCATED + var returnArray = new byte[byteCount]; + + byte curByte = 0, bitsRemaining = 8; + var arrayIndex = 0; + foreach (var c in data) { + var cValue = CharToValue(c); + + int mask; + if (bitsRemaining > 5) { + mask = cValue << (bitsRemaining - 5); + curByte = (byte) (curByte | mask); + bitsRemaining -= 5; + } else { + mask = cValue >> (5 - bitsRemaining); + curByte = (byte) (curByte | mask); + returnArray[arrayIndex++] = curByte; + curByte = (byte) (cValue << (3 + bitsRemaining)); + bitsRemaining += 3; + } + } + + //if we didn't end with a full byte + if (arrayIndex != byteCount) { + returnArray[arrayIndex] = curByte; + } + + return returnArray; + } + + private static int CharToValue(char c) { + var value = (int) c; + + //65-90 == uppercase letters + if (value < 91 && value > 64) { + return value - 65; + } + + //50-55 == numbers 2-7 + if (value < 56 && value > 49) { + return value - 24; + } + + //97-122 == lowercase letters + if (value < 123 && value > 96) { + return value - 97; + } + + throw new ArgumentException("Character is not a Base32 character.", nameof(c)); + } + + private static char ValueToChar(byte b) { + if (b < 26) { + return (char) (b + 65); + } + + if (b < 32) { + return (char) (b + 24); + } + + throw new ArgumentException("Byte is not a Base32 value.", nameof(b)); + } + } +} \ No newline at end of file From 97bc8395221f5ee4e5b1eb4bc8701d93454e6a83 Mon Sep 17 00:00:00 2001 From: alexinea Date: Sun, 5 Jan 2020 16:31:33 +0800 Subject: [PATCH 12/15] Update Fluent exception apis. --- .../Cosmos.Extensions.Reflection.csproj | 6 +- .../Cosmos.Extensions.Reflection.xml | 166 ++---------------- .../ExceptionArgConstants.cs | 2 +- .../ExceptionBuildingOptions.cs | 2 +- .../Cosmos/Exceptions/ExceptionBuilder.cs | 7 +- .../Cosmos/Exceptions/ExceptionBuilder`1.cs | 2 +- .../Exceptions/IFluentExceptionBuilder.cs | 15 +- .../Cosmos/NTypes.CtorArgDescriptor.cs | 10 +- .../Cosmos/NTypes.CtorMatchedResult.cs | 18 +- .../Cosmos/NTypes.CtorTemplate.cs | 2 +- .../Cosmos/NTypes.cs | 2 +- .../Cosmos.Test.ReflectionTests.csproj | 24 +++ .../ExceptionCtorTest.cs | 20 +++ 13 files changed, 100 insertions(+), 176 deletions(-) create mode 100644 test/Cosmos.Test.ReflectionTests/Cosmos.Test.ReflectionTests.csproj create mode 100644 test/Cosmos.Test.ReflectionTests/ExceptionCtorTest.cs diff --git a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.csproj b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.csproj index 3bb2afe1..ab17e27c 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.csproj +++ b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.csproj @@ -12,6 +12,10 @@ Cosmos reflection extension library + + true + + @@ -20,7 +24,7 @@ - + diff --git a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml index 58db44c4..3f006ea7 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml +++ b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml @@ -4,94 +4,6 @@ Cosmos.Extensions.Reflection - - - Exception arg constants - - - - - Message - - - - - Param Name - - - - - Inner exception - - - - - Inner exception, usage for InvalidProgramException - - - - - Actual value - - - - - Error code - - - - - Exception building options - - - - - Create a new instance of . - - - - - - Gets exception type - - - - - Add args - - - - - - - - - Add args - - - - - - - - - - Exception builder - - - - - Create a new instance of . - - - - - - - Exception builder - - - Interface for fluent exception builder @@ -104,35 +16,40 @@ - With inner exception + With inner exception.
+ This value will be used for constructor with param-name 'innerException' and 'inner' (just for ).
- With parameter's name + With parameter's name.
+ This value will be used for constructor with param-name 'paramName'.
- With message + With message.
+ This value will be used for constructor with param-name 'message'.
- Actual value + Actual value.
+ This value will be used for constructor with param-name 'actualValue'.
- Error code + Error code.
+ This value will be used for constructor with param-name 'errorCode'.
@@ -556,69 +473,6 @@
- - - Advanced Types utilities - - - - - Create instance - - - - - - - - Create instance - - - - - - - - - Create instance - - - - - - - - Descriptor of argument - - - - - Create a new instance of . - - - - - Create a new instance of . - - - - - - - - Argument name - - - - - Argument value - - - - - Argument type - - Property access type diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionArgConstants.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionArgConstants.cs index 270ace39..f6f7b19f 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionArgConstants.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionArgConstants.cs @@ -1,4 +1,4 @@ -#if !NET451 +#if !NET451 && !NET461 namespace Cosmos.Exceptions.BuildingDescriptors { /// diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionBuildingOptions.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionBuildingOptions.cs index 15bde308..995e045d 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionBuildingOptions.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/BuildingDescriptors/ExceptionBuildingOptions.cs @@ -1,4 +1,4 @@ -#if !NET451 +#if !NET451 && !NET461 using System; using System.Collections.Generic; diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder.cs index 7b1814eb..bd2eef89 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder.cs @@ -1,4 +1,4 @@ -#if !NET451 +#if !NET451 && !NET461 using System; @@ -8,7 +8,10 @@ namespace Cosmos.Exceptions { /// public static class ExceptionBuilder { /// - /// Create a new instance of . + /// Create a new builder for of .
+ /// If you want to use this feature, please add following xml-node in your csproj file:
+ /// <PreserveCompilationContext>true</PreserveCompilationContext>
+ /// This feature is supported by LanX, the author of NCC Natasha. ///
/// /// diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs index f7eecf5b..8818a2cf 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs @@ -1,4 +1,4 @@ -#if !NET451 +#if !NET451 && !NET461 using System; using Cosmos.Exceptions.BuildingDescriptors; diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs index 9db2aa54..d764381a 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs @@ -11,35 +11,40 @@ public interface IFluentExceptionBuilder where TException : Exceptio Type TargetType { get; } /// - /// With inner exception + /// With inner exception.
+ /// This value will be used for constructor with param-name 'innerException' and 'inner' (just for ). ///
/// /// IFluentExceptionBuilder InnerException(Exception innerException); /// - /// With parameter's name + /// With parameter's name.
+ /// This value will be used for constructor with param-name 'paramName'. ///
/// /// IFluentExceptionBuilder ParamName(string paramName); /// - /// With message + /// With message.
+ /// This value will be used for constructor with param-name 'message'. ///
/// /// IFluentExceptionBuilder Message(string message); /// - /// Actual value + /// Actual value.
+ /// This value will be used for constructor with param-name 'actualValue'. ///
/// /// IFluentExceptionBuilder ActualValue(object actualValue); /// - /// Error code + /// Error code.
+ /// This value will be used for constructor with param-name 'errorCode'. ///
/// /// diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorArgDescriptor.cs b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorArgDescriptor.cs index d514ae14..750a0f1e 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorArgDescriptor.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorArgDescriptor.cs @@ -1,4 +1,4 @@ -#if !NET451 +#if !NET451 && !NET461 using System; @@ -13,10 +13,10 @@ namespace Cosmos { ///
public class CtorArgDescriptor { - /// - /// Create a new instance of . - /// - public CtorArgDescriptor() { } + // /// + // /// Create a new instance of . + // /// + // public CtorArgDescriptor() { } /// /// Create a new instance of . diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorMatchedResult.cs b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorMatchedResult.cs index a92f8af9..65d95d9d 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorMatchedResult.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorMatchedResult.cs @@ -1,4 +1,4 @@ -#if !NET451 +#if !NET451 && !NET461 /* * Author: LanX @@ -6,15 +6,29 @@ */ namespace Cosmos { - internal readonly struct CtorMatchedResult { + /// + /// Ctor matched result + /// + public readonly struct CtorMatchedResult { + /// + /// Ctor matched result + /// + /// + /// public CtorMatchedResult(object[] values, int index) { Values = values; Index = index; } + /// + /// Values + /// public readonly object[] Values; + /// + /// Index + /// public readonly int Index; } } diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorTemplate.cs b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorTemplate.cs index 2f0f688f..6be0eda5 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorTemplate.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.CtorTemplate.cs @@ -1,4 +1,4 @@ -#if !NET451 +#if !NET451 && !NET461 using BTFindTree; using Natasha; diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.cs b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.cs index 8e207770..5be3a14a 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/NTypes.cs @@ -1,4 +1,4 @@ -#if !NET451 +#if !NET451 && !NET461 using System; using System.Collections.Generic; diff --git a/test/Cosmos.Test.ReflectionTests/Cosmos.Test.ReflectionTests.csproj b/test/Cosmos.Test.ReflectionTests/Cosmos.Test.ReflectionTests.csproj new file mode 100644 index 00000000..ad85b859 --- /dev/null +++ b/test/Cosmos.Test.ReflectionTests/Cosmos.Test.ReflectionTests.csproj @@ -0,0 +1,24 @@ + + + + netcoreapp3.1;netcoreapp3.0;netcoreapp2.2 + false + true + + + + true + + + + + + + + + + + + + + diff --git a/test/Cosmos.Test.ReflectionTests/ExceptionCtorTest.cs b/test/Cosmos.Test.ReflectionTests/ExceptionCtorTest.cs new file mode 100644 index 00000000..59276243 --- /dev/null +++ b/test/Cosmos.Test.ReflectionTests/ExceptionCtorTest.cs @@ -0,0 +1,20 @@ +using System; +using Cosmos.Exceptions; +using Xunit; + +namespace Cosmos.Test.ReflectionTests { + public class ExceptionCtorTest { + [Fact] + public void CreateTest() { + var fluent = ExceptionBuilder.Create() + .ParamName(nameof(CreateTest)) + .Message("Create test"); + + var fluException = fluent.Build(); + var refException = new ArgumentNullException(nameof(CreateTest), "Create test"); + + Assert.Equal(fluException.Message, refException.Message); + Assert.Equal(fluException.ParamName, refException.ParamName); + } + } +} \ No newline at end of file From da4b72e88b591a23cf9fe868e9056626d22a9264 Mon Sep 17 00:00:00 2001 From: alexinea Date: Sun, 5 Jan 2020 16:31:43 +0800 Subject: [PATCH 13/15] Basic update. --- Cosmos.Standard.sln | 7 ++ build/version.props | 2 +- .../Cosmos.Extensions.Http.csproj | 2 +- .../Cosmos.Extensions.Asyncs.xml | 92 +++++++++++++++++++ .../Cosmos.Extensions.Domain.csproj | 2 +- .../Cosmos.Extensions.Preconditions.csproj | 2 +- src/Cosmos/Cosmos.xml | 38 ++++++++ 7 files changed, 141 insertions(+), 4 deletions(-) diff --git a/Cosmos.Standard.sln b/Cosmos.Standard.sln index 7ad082aa..5d60ede6 100644 --- a/Cosmos.Standard.sln +++ b/Cosmos.Standard.sln @@ -169,6 +169,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Serialization.Nett", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Test.Serialization.NettTest", "extra\serialization\tests\Cosmos.Test.Serialization.NettTest\Cosmos.Test.Serialization.NettTest.csproj", "{57DA8994-BA86-4FB8-BA92-CFB09FDE0A55}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Test.ReflectionTests", "test\Cosmos.Test.ReflectionTests\Cosmos.Test.ReflectionTests.csproj", "{F7ED45F3-8BB1-4620-A267-9F02510134E4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -391,6 +393,10 @@ Global {57DA8994-BA86-4FB8-BA92-CFB09FDE0A55}.Debug|Any CPU.Build.0 = Debug|Any CPU {57DA8994-BA86-4FB8-BA92-CFB09FDE0A55}.Release|Any CPU.ActiveCfg = Release|Any CPU {57DA8994-BA86-4FB8-BA92-CFB09FDE0A55}.Release|Any CPU.Build.0 = Release|Any CPU + {F7ED45F3-8BB1-4620-A267-9F02510134E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7ED45F3-8BB1-4620-A267-9F02510134E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7ED45F3-8BB1-4620-A267-9F02510134E4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7ED45F3-8BB1-4620-A267-9F02510134E4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -460,6 +466,7 @@ Global {43F1A15E-04EA-405F-8115-B3DD3DDD6B3B} = {BDBDE50C-D11B-4B8B-8349-0B6681CC98FF} {B1A584BE-EE50-4EF3-AC49-1E3FB91545E2} = {87D7302C-14EA-46B4-9324-0E42E39C100D} {57DA8994-BA86-4FB8-BA92-CFB09FDE0A55} = {66C97C79-C2AE-49DD-8622-CAC7DD71F21B} + {F7ED45F3-8BB1-4620-A267-9F02510134E4} = {0F01E2EF-3398-47CB-B5CB-33AF122A1BC7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D68A6AF5-79FE-4679-AD20-67D6CFCF75B4} diff --git a/build/version.props b/build/version.props index 9fb5d78a..f511f2ce 100644 --- a/build/version.props +++ b/build/version.props @@ -2,7 +2,7 @@ 0 1 - 2-beta1-101120 + 2-beta1-101135 $(VersionMajor).$(VersionMinor).$(VersionPatch) diff --git a/extra/http/src/Cosmos.Extensions.Http/Cosmos.Extensions.Http.csproj b/extra/http/src/Cosmos.Extensions.Http/Cosmos.Extensions.Http.csproj index cbe8f0f1..e1d74b17 100644 --- a/extra/http/src/Cosmos.Extensions.Http/Cosmos.Extensions.Http.csproj +++ b/extra/http/src/Cosmos.Extensions.Http/Cosmos.Extensions.Http.csproj @@ -16,7 +16,7 @@ '$(TargetFramework)'=='netstandard2.1' OR '$(TargetFramework)'=='netstandard2.0' OR '$(TargetFramework)'=='net461'"> - + diff --git a/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.xml b/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.xml index 0127ade7..c5d85d12 100644 --- a/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.xml +++ b/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.xml @@ -268,6 +268,98 @@ + + + Bounded concurrent queue + + + + + + Create a new instance of . + + + + + Create a new instance of . + + + + + + + Gets queue count + + + + + Try dequeue + + + + + + + Try enqueue + + + + + + + Concurrent Set + + + + + + Is empty + + + + + + + + + + + + + + Try add + + + + + + + Try remove + + + + + + + Values + + + + + + + + + + + + + + + + + + Asynchronous Disable Action.
diff --git a/src/Cosmos.Extensions.Domain/Cosmos.Extensions.Domain.csproj b/src/Cosmos.Extensions.Domain/Cosmos.Extensions.Domain.csproj index d0032996..ee45d468 100644 --- a/src/Cosmos.Extensions.Domain/Cosmos.Extensions.Domain.csproj +++ b/src/Cosmos.Extensions.Domain/Cosmos.Extensions.Domain.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/Cosmos.Extensions.Preconditions/Cosmos.Extensions.Preconditions.csproj b/src/Cosmos.Extensions.Preconditions/Cosmos.Extensions.Preconditions.csproj index 49a56b33..1dc3fe5a 100644 --- a/src/Cosmos.Extensions.Preconditions/Cosmos.Extensions.Preconditions.csproj +++ b/src/Cosmos.Extensions.Preconditions/Cosmos.Extensions.Preconditions.csproj @@ -15,7 +15,7 @@ - + diff --git a/src/Cosmos/Cosmos.xml b/src/Cosmos/Cosmos.xml index 00a36d0f..791547f7 100644 --- a/src/Cosmos/Cosmos.xml +++ b/src/Cosmos/Cosmos.xml @@ -4,6 +4,44 @@ Cosmos + + + Base32 Conversion Utilities + + + + + Base32 encode + + + + + + + + Base32 encode + + + + + + + + + Base32 decode + + + + + + + + Base32 decode + + + + + Base64 Conversion Utilities From a59c0f1ed76e425f00996cfa2006a38f4249a5ea Mon Sep 17 00:00:00 2001 From: alexinea Date: Sun, 5 Jan 2020 22:59:00 +0800 Subject: [PATCH 14/15] Code lceanup. --- build/version.props | 2 +- .../Cosmos.Extensions.Asyncs.xml | 20 ++++++ .../Cosmos.Extensions.Reflection.xml | 5 ++ src/Cosmos/Cosmos.xml | 66 ++++++++++--------- .../Cosmos/Conversions/Base32Conversion.cs | 35 +++++----- .../Cosmos/Conversions/Base64Conversion.cs | 57 ++++++++-------- .../Cosmos/Conversions/EncodingHelper.cs | 9 +++ .../Cosmos/Conversions/GuidConvertsion.cs | 8 +-- .../Cosmos/Conversions/NumericConversion.cs | 30 ++++----- .../Cosmos/Conversions/ObjectConversion.cs | 12 ++-- .../Scale/HexadecimalConversion.cs | 12 ++-- src/Cosmos/Cosmos/CosmosException.cs | 8 +++ src/Cosmos/Cosmos/Enums.cs | 4 +- .../Cosmos/Judgments/CollectionJudgment.cs | 16 ++--- src/Cosmos/Cosmos/Judgments/GuidJudgment.cs | 6 +- .../Cosmos/Judgments/QueryableJudgment.cs | 6 +- src/Cosmos/Cosmos/Judgments/StringJudgment.cs | 9 ++- src/Cosmos/Cosmos/Reflections.cs | 34 +++++----- src/Cosmos/Cosmos/Types.cs | 10 +-- .../Extensions.ValidationException.cs | 6 +- 20 files changed, 196 insertions(+), 159 deletions(-) create mode 100644 src/Cosmos/Cosmos/Conversions/EncodingHelper.cs diff --git a/build/version.props b/build/version.props index f511f2ce..00d5d59d 100644 --- a/build/version.props +++ b/build/version.props @@ -2,7 +2,7 @@ 0 1 - 2-beta1-101135 + 2-beta1-101136 $(VersionMajor).$(VersionMinor).$(VersionPatch) diff --git a/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.xml b/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.xml index c5d85d12..ecbcce2c 100644 --- a/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.xml +++ b/src/Cosmos.Extensions.Asyncs/Cosmos.Extensions.Asyncs.xml @@ -12525,6 +12525,26 @@ + + + CallContext for .NET Standard and .NET Core + for more info: http://www.cazzulino.com/callcontext-netstandard-netcore.html + + + + + Set data + + + + + + + Get data + + + + Call Context diff --git a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml index 3f006ea7..0d73d76d 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml +++ b/src/Cosmos.Extensions.Reflection/Cosmos.Extensions.Reflection.xml @@ -65,6 +65,11 @@ Build and throw exception + + + Build and throw exception as validation error + + Type extensions diff --git a/src/Cosmos/Cosmos.xml b/src/Cosmos/Cosmos.xml index 791547f7..ce277eff 100644 --- a/src/Cosmos/Cosmos.xml +++ b/src/Cosmos/Cosmos.xml @@ -11,34 +11,33 @@ - Base32 encode + Convert from to base32 . - + - Base32 encode + Convert from to base32 . - - + - Base32 decode + Convert from base32 to . - + - Base32 decode + Convert from base32 to array. - + @@ -47,13 +46,6 @@ Base64 Conversion Utilities - - - Convert from bytes to base64 . - - - - Convert from to base64 . @@ -62,11 +54,12 @@ - + - Convert from base64 to . + Convert from to base64 . - + + @@ -76,12 +69,11 @@ - + - Convert from to base64url . + Convert from base64 to array. - - + @@ -91,11 +83,12 @@ - + - Convert from base64url to . + Convert from to base64url . - + + @@ -104,6 +97,12 @@ + + + Convert from base64url to . + + + Boolean Conversion Utilities @@ -492,21 +491,21 @@ - + Convert from hexadecimal to . - encoding name, default is "utf-8" + - + Convert from to hexadecimal. in: A; out: 1000001 - encoding name, default is "utf-8" + @@ -638,6 +637,11 @@ + + + Throw me. + + Options for cosmos exception @@ -1115,7 +1119,7 @@ To judge whether these two collections contain same count of elements. - + diff --git a/src/Cosmos/Cosmos/Conversions/Base32Conversion.cs b/src/Cosmos/Cosmos/Conversions/Base32Conversion.cs index a88c6a2e..38bd5fea 100644 --- a/src/Cosmos/Cosmos/Conversions/Base32Conversion.cs +++ b/src/Cosmos/Cosmos/Conversions/Base32Conversion.cs @@ -7,7 +7,7 @@ namespace Cosmos.Conversions { /// public static class Base32Conversion { /// - /// Base32 encode + /// Convert from to base32 . /// /// /// @@ -47,44 +47,43 @@ public static string ToBase32String(byte[] bytes) { } /// - /// Base32 encode + /// Convert from to base32 . /// - /// - /// + /// /// /// - public static string ToBase32String(byte[] bytes, string data, Encoding encoding) { - return ToBase32String(encoding.GetBytes(data)); + public static string ToBase32String(string str, Encoding encoding = null) { + return ToBase32String(encoding.Fixed().GetBytes(str)); } /// - /// Base32 decode + /// Convert from base32 to . /// - /// + /// /// /// - public static string FromBase32String(string data, Encoding encoding) { - return encoding.GetString(FromBase32StringToBytes(data)); + public static string FromBase32String(string base32String, Encoding encoding = null) { + return encoding.Fixed().GetString(FromBase32StringToBytes(base32String)); } /// - /// Base32 decode + /// Convert from base32 to array. /// - /// + /// /// /// - public static byte[] FromBase32StringToBytes(string data) { - if (data is null) { - throw new ArgumentNullException(nameof(data)); + public static byte[] FromBase32StringToBytes(string base32String) { + if (base32String is null) { + throw new ArgumentNullException(nameof(base32String)); } - data = data.TrimEnd('='); //remove padding characters - var byteCount = data.Length * 5 / 8; //this must be TRUNCATED + base32String = base32String.TrimEnd('='); //remove padding characters + var byteCount = base32String.Length * 5 / 8; //this must be TRUNCATED var returnArray = new byte[byteCount]; byte curByte = 0, bitsRemaining = 8; var arrayIndex = 0; - foreach (var c in data) { + foreach (var c in base32String) { var cValue = CharToValue(c); int mask; diff --git a/src/Cosmos/Cosmos/Conversions/Base64Conversion.cs b/src/Cosmos/Cosmos/Conversions/Base64Conversion.cs index f369fda9..cf2dfe21 100644 --- a/src/Cosmos/Cosmos/Conversions/Base64Conversion.cs +++ b/src/Cosmos/Cosmos/Conversions/Base64Conversion.cs @@ -10,7 +10,17 @@ public static class Base64Conversion { private const string BASE64 = "===========================================+=+=/0123456789=======ABCDEFGHIJKLMNOPQRSTUVWXYZ====/=abcdefghijklmnopqrstuvwxyz====="; /// - /// Convert from bytes to base64 . + /// Convert from to base64 . + /// + /// + /// + /// + public static string ToBase64String(string str, Encoding encoding = null) { + return ToBase64String(encoding.Fixed().GetBytes(str)); + } + + /// + /// Convert from to base64 . /// /// /// @@ -19,33 +29,33 @@ public static string ToBase64String(byte[] bytes) { } /// - /// Convert from to base64 . + /// Convert from base64 to . /// - /// + /// /// /// - public static string ToBase64String(string str, Encoding encoding) { - return ToBase64String(encoding.GetBytes(str)); + public static string FromBase64String(string base64String, Encoding encoding = null) { + return encoding.Fixed().GetString(FromBase64StringToBytes(base64String)); } /// - /// Convert from base64 to . + /// Convert from base64 to array. /// /// - public static byte[] FromBase64String(string base64String) { + public static byte[] FromBase64StringToBytes(string base64String) { return Convert.FromBase64String(base64String); } /// - /// Convert from base64 to . + /// Convert from to base64url . /// - /// + /// /// /// - public static string FromBase64String(string base64String, Encoding encoding) { - return encoding.GetString(FromBase64String(base64String)); + public static string ToBase64UrlString(string str, Encoding encoding = null) { + return ToBase64UrlString(encoding.Fixed().GetBytes(str)); } - + /// /// Convert from to base64url . /// @@ -57,22 +67,21 @@ public static string ToBase64UrlString(byte[] bytes) { result.Replace('/', '_'); return result.ToString(); } - + /// - /// Convert from to base64url . + /// Convert from base64url to . /// - /// + /// /// - /// - public static string ToBase64UrlString(string str, Encoding encoding) { - return ToBase64UrlString(encoding.GetBytes(str)); + public static string FromBase64UrlString(string base64UrlString, Encoding encoding = null) { + return encoding.Fixed().GetString(FromBase64UrlStringToBytes(base64UrlString)); } - + /// /// Convert from base64url to . /// /// - public static byte[] FromBase64UrlString(string base64UrlString) { + public static byte[] FromBase64UrlStringToBytes(string base64UrlString) { var sb = new StringBuilder(); foreach (var c in base64UrlString) { if (c >= 128) continue; @@ -87,13 +96,5 @@ public static byte[] FromBase64UrlString(string base64UrlString) { return Convert.FromBase64String(sb.ToString()); } - /// - /// Convert from base64url to . - /// - /// - /// - public static string FromBase64UrlString(string base64UrlString, Encoding encoding) { - return encoding.GetString(FromBase64UrlString(base64UrlString)); - } } } \ No newline at end of file diff --git a/src/Cosmos/Cosmos/Conversions/EncodingHelper.cs b/src/Cosmos/Cosmos/Conversions/EncodingHelper.cs new file mode 100644 index 00000000..1fcc945e --- /dev/null +++ b/src/Cosmos/Cosmos/Conversions/EncodingHelper.cs @@ -0,0 +1,9 @@ +using System.Text; + +namespace Cosmos.Conversions { + internal static class EncodingHelper { + public static Encoding Fixed(this Encoding encoding) { + return encoding ?? Encoding.UTF8; + } + } +} \ No newline at end of file diff --git a/src/Cosmos/Cosmos/Conversions/GuidConvertsion.cs b/src/Cosmos/Cosmos/Conversions/GuidConvertsion.cs index a3ddc9b1..c549870e 100644 --- a/src/Cosmos/Cosmos/Conversions/GuidConvertsion.cs +++ b/src/Cosmos/Cosmos/Conversions/GuidConvertsion.cs @@ -11,11 +11,11 @@ public static class GuidConversion { /// /// public static Guid ToGuid(object obj) { - if (obj == null) { + if (obj is null) { return Guid.Empty; } - return Guid.TryParse(obj.ToString(), out Guid ret) ? ret : Guid.Empty; + return Guid.TryParse(obj.ToString(), out var ret) ? ret : Guid.Empty; } /// @@ -24,11 +24,11 @@ public static Guid ToGuid(object obj) { /// /// public static Guid? ToNullableGuid(object obj) { - if (obj == null) { + if (obj is null) { return null; } - if (Guid.TryParse(obj.ToString(), out Guid ret)) { + if (Guid.TryParse(obj.ToString(), out var ret)) { return ret; } diff --git a/src/Cosmos/Cosmos/Conversions/NumericConversion.cs b/src/Cosmos/Cosmos/Conversions/NumericConversion.cs index 5000259b..ac907f67 100644 --- a/src/Cosmos/Cosmos/Conversions/NumericConversion.cs +++ b/src/Cosmos/Cosmos/Conversions/NumericConversion.cs @@ -12,7 +12,7 @@ public static class NumericConversion { /// /// public static int ToInt32(object obj, int defaultRet = 0) { - if (obj == null) { + if (obj is null) { return defaultRet; } @@ -22,8 +22,7 @@ public static int ToInt32(object obj, int defaultRet = 0) { try { return Convert.ToInt32(ToDouble(obj, defaultRet)); - } - catch { + } catch { return defaultRet; } } @@ -34,7 +33,7 @@ public static int ToInt32(object obj, int defaultRet = 0) { /// /// public static int? ToNullableInt32(object obj) { - if (obj == null) { + if (obj is null) { return null; } @@ -52,7 +51,7 @@ public static int ToInt32(object obj, int defaultRet = 0) { /// /// public static long ToInt64(object obj, long defaultRet = 0) { - if (obj == null) { + if (obj is null) { return defaultRet; } @@ -62,8 +61,7 @@ public static long ToInt64(object obj, long defaultRet = 0) { try { return Convert.ToInt64(ToDouble(obj, defaultRet)); - } - catch { + } catch { return defaultRet; } } @@ -74,7 +72,7 @@ public static long ToInt64(object obj, long defaultRet = 0) { /// /// public static long? ToNullableInt64(object obj) { - if (obj == null) { + if (obj is null) { return null; } @@ -92,7 +90,7 @@ public static long ToInt64(object obj, long defaultRet = 0) { /// /// public static float ToFloat(object obj, float defaultRet = 0F) { - if (obj == null) { + if (obj is null) { return defaultRet; } @@ -105,7 +103,7 @@ public static float ToFloat(object obj, float defaultRet = 0F) { /// /// public static float? ToNullableFloat(object obj) { - if (obj == null) { + if (obj is null) { return null; } @@ -124,7 +122,7 @@ public static float ToFloat(object obj, float defaultRet = 0F) { /// /// public static double ToDouble(object obj, double defaultRet = 0D) { - if (obj == null) { + if (obj is null) { return defaultRet; } @@ -148,7 +146,7 @@ public static double ToRoundDouble(object obj, int digits, double defaultRet = 0 /// /// public static double? ToNullableDouble(object obj) { - if (obj == null) { + if (obj is null) { return null; } @@ -167,7 +165,7 @@ public static double ToRoundDouble(object obj, int digits, double defaultRet = 0 /// public static double? ToRoundNullableDouble(object obj, int digits) { var ret = ToNullableDouble(obj); - if (ret == null) { + if (ret is null) { return null; } @@ -181,7 +179,7 @@ public static double ToRoundDouble(object obj, int digits, double defaultRet = 0 /// /// public static decimal ToDecimal(object obj, decimal defaultRet = 0M) { - if (obj == null) { + if (obj is null) { return defaultRet; } @@ -205,7 +203,7 @@ public static decimal ToRoundDecimal(object obj, int digits, decimal defaultRet /// /// public static decimal? ToNullableDecimal(object obj) { - if (obj == null) { + if (obj is null) { return null; } @@ -224,7 +222,7 @@ public static decimal ToRoundDecimal(object obj, int digits, decimal defaultRet /// public static decimal? ToRoundNullableDecimal(object obj, int digits) { var ret = ToNullableDecimal(obj); - if (ret == null) { + if (ret is null) { return null; } diff --git a/src/Cosmos/Cosmos/Conversions/ObjectConversion.cs b/src/Cosmos/Cosmos/Conversions/ObjectConversion.cs index db97898d..a5a797c9 100644 --- a/src/Cosmos/Cosmos/Conversions/ObjectConversion.cs +++ b/src/Cosmos/Cosmos/Conversions/ObjectConversion.cs @@ -36,7 +36,7 @@ public static object To(object fromObj, Type targetType) { /// /// public static object To(object fromObj, Type targetType, object defaultValue) { - if (fromObj == null) { + if (fromObj is null) { return defaultValue; } @@ -63,8 +63,7 @@ public static object To(object fromObj, Type targetType, object defaultValue) { } return fromObj; - } - catch { + } catch { return defaultValue; } } @@ -110,8 +109,7 @@ public static TTo To(object fromObj) { public static TTo To(object fromObj, TTo defaultValue) { try { return (TTo) To(fromObj, typeof(TTo), defaultValue); - } - catch { + } catch { return defaultValue; } } @@ -142,7 +140,7 @@ public static IEnumerable ToList(string listStr, char splitChar = ',') /// /// public static DateTime ToDateTime(object obj, DateTime defaultRet = default(DateTime)) { - if (obj == null) { + if (obj is null) { return defaultRet; } @@ -156,7 +154,7 @@ public static IEnumerable ToList(string listStr, char splitChar = ',') /// /// public static DateTime? ToNullableDateTime(object obj, DateTime? defaultRet = null) { - if (obj == null) { + if (obj is null) { return defaultRet; } diff --git a/src/Cosmos/Cosmos/Conversions/Scale/HexadecimalConversion.cs b/src/Cosmos/Cosmos/Conversions/Scale/HexadecimalConversion.cs index 3308460b..ad706b8d 100644 --- a/src/Cosmos/Cosmos/Conversions/Scale/HexadecimalConversion.cs +++ b/src/Cosmos/Cosmos/Conversions/Scale/HexadecimalConversion.cs @@ -40,9 +40,9 @@ public static byte[] ToBytes(string hex) { /// Convert from hexadecimal to . /// /// - /// encoding name, default is "utf-8" + /// /// - public static string ToString(string hex, string encodingName = "utf-8") { + public static string ToString(string hex, Encoding encoding = null) { hex = hex.Replace(" ", ""); if (string.IsNullOrWhiteSpace(hex)) { return ""; @@ -55,7 +55,7 @@ public static string ToString(string hex, string encodingName = "utf-8") { } } - return Encoding.GetEncoding(encodingName).GetString(bytes); + return encoding.Fixed().GetString(bytes); } /// @@ -63,9 +63,9 @@ public static string ToString(string hex, string encodingName = "utf-8") { /// /// in: A; out: 1000001 /// - /// encoding name, default is "utf-8" + /// /// - public static string FromString(string str, string encodingName = "utf-8") - => BitConverter.ToString(Encoding.GetEncoding(encodingName).GetBytes(str)).Replace("-", " "); + public static string FromString(string str, Encoding encoding = null) + => BitConverter.ToString(encoding.Fixed().GetBytes(str)).Replace("-", " "); } } \ No newline at end of file diff --git a/src/Cosmos/Cosmos/CosmosException.cs b/src/Cosmos/Cosmos/CosmosException.cs index 1b1025fc..31036acc 100644 --- a/src/Cosmos/Cosmos/CosmosException.cs +++ b/src/Cosmos/Cosmos/CosmosException.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Runtime.Serialization; +using Cosmos.Exceptions; namespace Cosmos { // ReSharper disable InconsistentNaming @@ -119,5 +120,12 @@ protected CosmosException(CosmosExceptionOptions options) : base(options.Message /// /// public virtual string GetFullMessage() => $"{Code}:({Flag}){Message}"; + + /// + /// Throw me. + /// + public virtual void Throw() { + ExceptionHelper.PrepareForRethrow(this); + } } } \ No newline at end of file diff --git a/src/Cosmos/Cosmos/Enums.cs b/src/Cosmos/Cosmos/Enums.cs index 292dd649..61f2b385 100644 --- a/src/Cosmos/Cosmos/Enums.cs +++ b/src/Cosmos/Cosmos/Enums.cs @@ -55,8 +55,8 @@ public static string NameOf(Type type, object member) { /// 成员名、值、实例均可 /// public static string NameOf(TypeInfo typeinfo, object member) { - if (typeinfo == null) return string.Empty; - if (member == null) return string.Empty; + if (typeinfo is null) return string.Empty; + if (member is null) return string.Empty; if (member is string) return member.ToString(); return !typeinfo.IsEnum ? string.Empty : Enum.GetName(typeinfo.AsType(), member); } diff --git a/src/Cosmos/Cosmos/Judgments/CollectionJudgment.cs b/src/Cosmos/Cosmos/Judgments/CollectionJudgment.cs index fcea4212..a5da71e7 100644 --- a/src/Cosmos/Cosmos/Judgments/CollectionJudgment.cs +++ b/src/Cosmos/Cosmos/Judgments/CollectionJudgment.cs @@ -13,7 +13,7 @@ public static class CollectionJudgment { /// /// public static bool IsNull(IEnumerable coll) { - return coll == null; + return coll is null; } /// @@ -22,7 +22,7 @@ public static bool IsNull(IEnumerable coll) { /// /// public static bool IsNullOrEmpty(IEnumerable coll) { - if (coll == null) + if (coll is null) return true; return !coll.Cast().Any(); @@ -35,7 +35,7 @@ public static bool IsNullOrEmpty(IEnumerable coll) { /// /// public static bool IsNullOrEmpty(IEnumerable coll) { - return coll == null || !coll.Any(); + return coll is null || !coll.Any(); } /// @@ -53,17 +53,17 @@ public static bool ContainsAtLeast(ICollection coll, int count) { /// To judge whether these two collections contain same count of elements. /// /// - /// + /// /// /// - public static bool ContainsEqualCount(ICollection leftCcoll, ICollection rightColl) { - if (leftCcoll == null && rightColl == null) + public static bool ContainsEqualCount(ICollection leftColl, ICollection rightColl) { + if (leftColl is null && rightColl is null) return true; - if (leftCcoll == null || rightColl == null) + if (leftColl is null || rightColl is null) return false; - return leftCcoll.Count.Equals(rightColl.Count); + return leftColl.Count.Equals(rightColl.Count); } } } \ No newline at end of file diff --git a/src/Cosmos/Cosmos/Judgments/GuidJudgment.cs b/src/Cosmos/Cosmos/Judgments/GuidJudgment.cs index f8d0b127..b1b3a8c7 100644 --- a/src/Cosmos/Cosmos/Judgments/GuidJudgment.cs +++ b/src/Cosmos/Cosmos/Judgments/GuidJudgment.cs @@ -21,7 +21,7 @@ public static bool IsNullOrEmpty(Guid guid) { /// /// public static bool IsNullOrEmpty(Guid? guid) { - return guid == null || IsNullOrEmpty(guid.Value); + return guid is null || IsNullOrEmpty(guid.Value); } @@ -36,10 +36,8 @@ private static readonly Regex GuidSchema /// /// public static bool IsValid(string guidStr) { - if (string.IsNullOrWhiteSpace(guidStr)) - return false; + return !string.IsNullOrWhiteSpace(guidStr) && GuidSchema.Match(guidStr).Success; - return GuidSchema.Match(guidStr).Success; } } } \ No newline at end of file diff --git a/src/Cosmos/Cosmos/Judgments/QueryableJudgment.cs b/src/Cosmos/Cosmos/Judgments/QueryableJudgment.cs index e64561d9..8b46d4ca 100644 --- a/src/Cosmos/Cosmos/Judgments/QueryableJudgment.cs +++ b/src/Cosmos/Cosmos/Judgments/QueryableJudgment.cs @@ -13,7 +13,7 @@ public static class QueryableJudgment { /// /// public static bool ContainsAtLeast(IQueryable query, int count) { - if (query == null) + if (query is null) return false; return (from t in query.Take(count) select t).Count() >= count; @@ -27,10 +27,10 @@ public static bool ContainsAtLeast(IQueryable query, int count) { /// /// public static bool ContainsEqualCount(IQueryable query, IQueryable targetQuery) { - if (query == null && targetQuery == null) + if (query is null && targetQuery is null) return true; - if (query == null || targetQuery == null) + if (query is null || targetQuery is null) return false; return query.Count().Equals(targetQuery.Count()); diff --git a/src/Cosmos/Cosmos/Judgments/StringJudgment.cs b/src/Cosmos/Cosmos/Judgments/StringJudgment.cs index 3945dd95..0d26f007 100644 --- a/src/Cosmos/Cosmos/Judgments/StringJudgment.cs +++ b/src/Cosmos/Cosmos/Judgments/StringJudgment.cs @@ -7,7 +7,6 @@ namespace Cosmos.Judgments { /// String Judgment Utilities /// public static class StringJudgment { - static StringJudgment() { } /// /// To judge whether the string starts with the specified strings. @@ -16,7 +15,7 @@ static StringJudgment() { } /// /// public static bool StartWithThese(string str, params string[] values) { - if (string.IsNullOrWhiteSpace(str) || values == null || values.Any(string.IsNullOrWhiteSpace)) + if (string.IsNullOrWhiteSpace(str) || values is null || values.Any(string.IsNullOrWhiteSpace)) return false; return values.Any(str.StartsWith); @@ -29,7 +28,7 @@ public static bool StartWithThese(string str, params string[] values) { /// /// public static bool StartWithThese(string str, ICollection values) { - if (string.IsNullOrWhiteSpace(str) || values == null || !values.Any()) + if (string.IsNullOrWhiteSpace(str) || values is null || !values.Any()) return false; return StartWithThese(str, values.ToArray()); @@ -42,7 +41,7 @@ public static bool StartWithThese(string str, ICollection values) { /// /// public static bool EndWithThese(string str, params string[] values) { - if (string.IsNullOrWhiteSpace(str) || values == null || values.Any(string.IsNullOrWhiteSpace)) + if (string.IsNullOrWhiteSpace(str) || values is null || values.Any(string.IsNullOrWhiteSpace)) return false; return values.Any(str.EndsWith); @@ -55,7 +54,7 @@ public static bool EndWithThese(string str, params string[] values) { /// /// public static bool EndWithThese(string str, ICollection values) { - if (string.IsNullOrWhiteSpace(str) || values == null || !values.Any()) + if (string.IsNullOrWhiteSpace(str) || values is null || !values.Any()) return false; return EndWithThese(str, values.ToArray()); diff --git a/src/Cosmos/Cosmos/Reflections.cs b/src/Cosmos/Cosmos/Reflections.cs index b466bab5..38d7c3df 100644 --- a/src/Cosmos/Cosmos/Reflections.cs +++ b/src/Cosmos/Cosmos/Reflections.cs @@ -35,7 +35,7 @@ public static string GetDescription(Type type) { /// Description of special typeInfo public static string GetDescription(TypeInfo typeInfo) { var attribute = GetAttribute(typeInfo); - return attribute == null ? typeInfo.Name : attribute.Description; + return attribute is null ? typeInfo.Name : attribute.Description; } /// @@ -65,7 +65,7 @@ public static string GetDescription(Type type, string memberName) { /// Name of special member /// Description of special typeInfo public static string GetDescription(TypeInfo typeInfo, string memberName) { - if (typeInfo == null) { + if (typeInfo is null) { return string.Empty; } @@ -80,10 +80,10 @@ public static string GetDescription(TypeInfo typeInfo, string memberName) { /// Special member /// Description of special member public static string GetDescription(MemberInfo memberInfo) { - if (memberInfo == null) + if (memberInfo is null) return string.Empty; var attribute = GetAttribute(memberInfo); - return attribute == null ? memberInfo.Name : attribute.Description; + return attribute is null ? memberInfo.Name : attribute.Description; } /// @@ -103,12 +103,12 @@ public static string GetDescription(Type type, FieldInfo field) { /// Special field /// Description of special field public static string GetDescription(TypeInfo typeInfo, FieldInfo field) { - if (typeInfo == null || field == null) { + if (typeInfo is null || field == null) { return string.Empty; } var attribute = GetAttribute(field); - return attribute == null ? field.Name : attribute.Description; + return attribute is null ? field.Name : attribute.Description; } /// @@ -126,13 +126,13 @@ public static string GetDisplayName() { /// Special member /// Description of special member private static string GetDisplayName(MemberInfo memberInfo) { - if (memberInfo == null) + if (memberInfo is null) return string.Empty; var displayNameAttribute = GetAttribute(memberInfo); if (displayNameAttribute != null) return displayNameAttribute.DisplayName; var displayAttribute = GetAttribute(memberInfo); - if (displayAttribute == null) + if (displayAttribute is null) return string.Empty; return displayAttribute.Description; } @@ -166,9 +166,7 @@ public static string GetDescriptionOrDisplayName(MemberInfo memberInfo) { /// Special typeInfo of attribute /// Attribute of special field public static TAttribute GetAttribute(FieldInfo fieldInfo) where TAttribute : Attribute { - return fieldInfo == null - ? null - : fieldInfo.GetReflector().GetCustomAttributes().FirstOrDefault(); + return fieldInfo?.GetReflector().GetCustomAttributes().FirstOrDefault(); } /// @@ -178,7 +176,7 @@ public static TAttribute GetAttribute(FieldInfo fieldInfo) where TAt /// Special typeInfo of member /// Attribute of special field public static TAttribute GetAttribute(MemberInfo memberInfo) where TAttribute : Attribute { - return memberInfo == null ? null : GetAttribute(memberInfo.GetType()); + return memberInfo is null ? null : GetAttribute(memberInfo.GetType()); } /// @@ -188,7 +186,7 @@ public static TAttribute GetAttribute(MemberInfo memberInfo) where T /// Special typeInfo of attribute /// Attribute of special typeInfo public static TAttribute GetAttribute(Type type) where TAttribute : Attribute { - return type == null ? null : GetAttribute(type.GetTypeInfo()); + return type is null ? null : GetAttribute(type.GetTypeInfo()); } /// @@ -198,7 +196,7 @@ public static TAttribute GetAttribute(Type type) where TAttribute : /// Special typeInfo of attribute /// Attribute of special typeInfo public static TAttribute GetAttribute(TypeInfo typeInfo) where TAttribute : Attribute { - return typeInfo == null ? null : typeInfo.GetReflector().GetCustomAttributes().FirstOrDefault(); + return typeInfo?.GetReflector().GetCustomAttributes().FirstOrDefault(); } /// @@ -208,7 +206,7 @@ public static TAttribute GetAttribute(TypeInfo typeInfo) where TAttr /// Special typeInfo of attribute /// Attribute of special field public static TAttribute GetRequiredAttribute(FieldInfo fieldInfo) where TAttribute : Attribute { - return fieldInfo == null ? null : fieldInfo.GetReflector().GetCustomAttribute(); + return fieldInfo?.GetReflector().GetCustomAttribute(); } /// @@ -218,7 +216,7 @@ public static TAttribute GetRequiredAttribute(FieldInfo fieldInfo) w /// Special typeInfo of attribute /// Attribute of special member public static TAttribute GetRequiredAttribute(MemberInfo memberInfo) where TAttribute : Attribute { - return memberInfo == null ? null : GetRequiredAttribute(memberInfo.GetType()); + return memberInfo is null ? null : GetRequiredAttribute(memberInfo.GetType()); } /// @@ -228,7 +226,7 @@ public static TAttribute GetRequiredAttribute(MemberInfo memberInfo) /// Special typeInfo of attribute /// Attribute of special typeInfo public static TAttribute GetRequiredAttribute(Type type) where TAttribute : Attribute { - return type == null ? null : GetRequiredAttribute(type.GetTypeInfo()); + return type is null ? null : GetRequiredAttribute(type.GetTypeInfo()); } /// @@ -238,7 +236,7 @@ public static TAttribute GetRequiredAttribute(Type type) where TAttr /// Special typeInfo of attribute /// Attribute of special typeInfo public static TAttribute GetRequiredAttribute(TypeInfo typeInfo) where TAttribute : Attribute { - return typeInfo == null ? null : typeInfo.GetReflector().GetCustomAttribute(); + return typeInfo?.GetReflector().GetCustomAttribute(); } } } \ No newline at end of file diff --git a/src/Cosmos/Cosmos/Types.cs b/src/Cosmos/Cosmos/Types.cs index 0e04b9b2..eaa95f05 100644 --- a/src/Cosmos/Cosmos/Types.cs +++ b/src/Cosmos/Cosmos/Types.cs @@ -21,7 +21,7 @@ public static partial class Types { /// Object array /// public static Type[] Of(object[] objColl) { - if (objColl == null) + if (objColl is null) return null; if (!objColl.Contains(null)) return Type.GetTypeArray(objColl); @@ -53,10 +53,10 @@ public static Type[] Of(object[] objColl) { /// The generic type /// public static bool IsGenericImplementation(Type type, Type genericType) { - if (type == null) + if (type is null) throw new ArgumentNullException(nameof(type)); - if (genericType == null) + if (genericType is null) throw new ArgumentNullException(nameof(genericType)); if (!genericType.IsGenericType) @@ -100,10 +100,10 @@ bool _checkRawGenericType(Type test) /// The generic type /// public static Type GetRawTypeFromGenericClass(Type type, Type genericType) { - if (type == null) + if (type is null) throw new ArgumentNullException(nameof(type)); - if (genericType == null) + if (genericType is null) throw new ArgumentNullException(nameof(genericType)); if (!genericType.IsGenericType) diff --git a/src/Cosmos/Cosmos/Validations/Extensions.ValidationException.cs b/src/Cosmos/Cosmos/Validations/Extensions.ValidationException.cs index d153fbe7..bf5ab7ff 100644 --- a/src/Cosmos/Cosmos/Validations/Extensions.ValidationException.cs +++ b/src/Cosmos/Cosmos/Validations/Extensions.ValidationException.cs @@ -11,7 +11,7 @@ public static class ValidationExceptionExtensions { /// /// public static void ThrowAsValidationError(this ArgumentNullException exception) { - if (exception == null) + if (exception is null) return; ValidationErrors.NullAndRaise(exception); @@ -22,7 +22,7 @@ public static void ThrowAsValidationError(this ArgumentNullException exception) /// /// public static void ThrowAsValidationError(this ArgumentOutOfRangeException exception) { - if (exception == null) + if (exception is null) return; ValidationErrors.OutOfRangeAndRaise(exception); @@ -33,7 +33,7 @@ public static void ThrowAsValidationError(this ArgumentOutOfRangeException excep /// /// public static void ThrowAsValidationError(this ArgumentInvalidException exception) { - if (exception == null) + if (exception is null) return; ValidationErrors.InvalidAndRaise(exception); From 6bc09363f56a330932374bf4356dc904daad1d57 Mon Sep 17 00:00:00 2001 From: alexinea Date: Sun, 5 Jan 2020 22:59:15 +0800 Subject: [PATCH 15/15] Update fluent exception api --- .../Cosmos/Exceptions/ExceptionBuilder`1.cs | 23 +++++++++++++++++++ .../Exceptions/IFluentExceptionBuilder.cs | 5 ++++ 2 files changed, 28 insertions(+) diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs index 8818a2cf..95ab04e0 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/ExceptionBuilder`1.cs @@ -2,6 +2,7 @@ using System; using Cosmos.Exceptions.BuildingDescriptors; +using Cosmos.Validations; namespace Cosmos.Exceptions { /// @@ -85,6 +86,28 @@ public void BuildAndThrow() { CreateAndCacheExceptionInstance(); ExceptionHelper.PrepareForRethrow(CachedException); } + + public void BuildAndThrowAsValidationError() { + CreateAndCacheExceptionInstance(); + switch (CachedException) { + case ArgumentNullException exception01: + exception01.ThrowAsValidationError(); + break; + + case ArgumentOutOfRangeException exception02: + exception02.ThrowAsValidationError(); + break; + + case ArgumentInvalidException exception03: + exception03.ThrowAsValidationError(); + break; + + default: + var invalidOps = new InvalidOperationException("Unhandled exception type here."); + ExceptionHelper.PrepareForRethrow(invalidOps); + break; + } + } } } diff --git a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs index d764381a..825c0d40 100644 --- a/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs +++ b/src/Cosmos.Extensions.Reflection/Cosmos/Exceptions/IFluentExceptionBuilder.cs @@ -60,5 +60,10 @@ public interface IFluentExceptionBuilder where TException : Exceptio /// Build and throw exception /// void BuildAndThrow(); + + /// + /// Build and throw exception as validation error + /// + void BuildAndThrowAsValidationError(); } } \ No newline at end of file