From efe66899a2fa4db567e4623d53ac054053ea4aec Mon Sep 17 00:00:00 2001 From: David Date: Mon, 7 Nov 2022 09:41:22 -0500 Subject: [PATCH 1/2] chore: Ensure building delegates are static --- src/Uno.Extensions.Reactive/Core/Feed.T.cs | 16 ++++---- src/Uno.Extensions.Reactive/Core/Feed.cs | 6 +-- .../Core/ListFeed.T.cs | 4 +- src/Uno.Extensions.Reactive/Core/ListFeed.cs | 2 +- src/Uno.Extensions.Reactive/Core/State.T.cs | 38 +++++++++---------- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/Uno.Extensions.Reactive/Core/Feed.T.cs b/src/Uno.Extensions.Reactive/Core/Feed.T.cs index 7535c62395..ab78dddd8d 100644 --- a/src/Uno.Extensions.Reactive/Core/Feed.T.cs +++ b/src/Uno.Extensions.Reactive/Core/Feed.T.cs @@ -19,7 +19,7 @@ public static class Feed // We set the T on the class to it greatly helps typ /// The provider of the message enumerable sequence. /// A feed that encapsulate the source. public static IFeed Create(Func>> sourceProvider) - => AttachedProperty.GetOrCreate(sourceProvider, sp => new CustomFeed(sp)); + => AttachedProperty.GetOrCreate(sourceProvider, static sp => new CustomFeed(sp)); /// /// Gets or create a custom feed from a raw sequence of . @@ -27,7 +27,7 @@ public static IFeed Create(FuncThe provider of the message enumerable sequence. /// A feed that encapsulate the source. public static IFeed Create(Func>> sourceProvider) - => AttachedProperty.GetOrCreate(sourceProvider, sp => new CustomFeed(_ => sp())); + => AttachedProperty.GetOrCreate(sourceProvider, static sp => new CustomFeed(_ => sp())); /// /// Gets or create a custom feed from an async method. @@ -38,7 +38,7 @@ public static IFeed Create(Func>> sourceProvider) public static IFeed Async(AsyncFunc> valueProvider, Signal? refresh = null) => refresh is null ? AttachedProperty.GetOrCreate(valueProvider, vp => new AsyncFeed(vp)) - : AttachedProperty.GetOrCreate(refresh, valueProvider, (r, vp) => new AsyncFeed(vp, r)); + : AttachedProperty.GetOrCreate(refresh, valueProvider, static (r, vp) => new AsyncFeed(vp, r)); /// /// Gets or create a custom feed from an async method. @@ -49,7 +49,7 @@ public static IFeed Async(AsyncFunc> valueProvider, Signal? refresh public static IFeed Async(AsyncFunc valueProvider, Signal? refresh = null) => refresh is null ? AttachedProperty.GetOrCreate(valueProvider, vp => new AsyncFeed(vp)) - : AttachedProperty.GetOrCreate(refresh, valueProvider, (r, vp) => new AsyncFeed(vp, r)); + : AttachedProperty.GetOrCreate(refresh, valueProvider, static (r, vp) => new AsyncFeed(vp, r)); /// /// Gets or create a custom feed from an async enumerable sequence of value. @@ -57,7 +57,7 @@ public static IFeed Async(AsyncFunc valueProvider, Signal? refresh = null) /// The async enumerable sequence of value of the resulting feed. /// A feed that encapsulate the source. public static IFeed AsyncEnumerable(Func>> enumerableProvider) - => AttachedProperty.GetOrCreate(enumerableProvider, ep => new AsyncEnumerableFeed(ep)); + => AttachedProperty.GetOrCreate(enumerableProvider, static ep => new AsyncEnumerableFeed(ep)); /// /// Gets or create a custom feed from an async enumerable sequence of value. @@ -65,7 +65,7 @@ public static IFeed AsyncEnumerable(Func>> enumera /// The async enumerable sequence of value of the resulting feed. /// A feed that encapsulate the source. public static IFeed AsyncEnumerable(Func>> enumerableProvider) - => AttachedProperty.GetOrCreate(enumerableProvider, ep => new AsyncEnumerableFeed(ep)); + => AttachedProperty.GetOrCreate(enumerableProvider, static ep => new AsyncEnumerableFeed(ep)); /// /// Gets or create a custom feed from an async enumerable sequence of value. @@ -73,7 +73,7 @@ public static IFeed AsyncEnumerable(FuncThe async enumerable sequence of value of the resulting feed. /// A feed that encapsulate the source. public static IFeed AsyncEnumerable(Func> enumerableProvider) - => AttachedProperty.GetOrCreate(enumerableProvider, ep => new AsyncEnumerableFeed(ep)); + => AttachedProperty.GetOrCreate(enumerableProvider, static ep => new AsyncEnumerableFeed(ep)); /// /// Gets or create a custom feed from an async enumerable sequence of value. @@ -81,5 +81,5 @@ public static IFeed AsyncEnumerable(Func> enumerableProvi /// The async enumerable sequence of value of the resulting feed. /// A feed that encapsulate the source. public static IFeed AsyncEnumerable(Func> enumerableProvider) - => AttachedProperty.GetOrCreate(enumerableProvider, ep => new AsyncEnumerableFeed(ep)); + => AttachedProperty.GetOrCreate(enumerableProvider, static ep => new AsyncEnumerableFeed(ep)); } diff --git a/src/Uno.Extensions.Reactive/Core/Feed.cs b/src/Uno.Extensions.Reactive/Core/Feed.cs index 8c753b1a5c..4ae9afc71a 100644 --- a/src/Uno.Extensions.Reactive/Core/Feed.cs +++ b/src/Uno.Extensions.Reactive/Core/Feed.cs @@ -65,7 +65,7 @@ public static IFeed AsyncEnumerable(Func Where( this IFeed source, Predicate predicate) - => AttachedProperty.GetOrCreate(source, predicate, (src, p) => new WhereFeed(src, p)); + => AttachedProperty.GetOrCreate(source, predicate, static (src, p) => new WhereFeed(src, p)); /// /// Gets or create a feed that projects each value of a source feed. @@ -78,7 +78,7 @@ public static IFeed Where( public static IFeed Select( this IFeed source, Func selector) - => AttachedProperty.GetOrCreate(source, selector, (src, s) => new SelectFeed(src, s)); + => AttachedProperty.GetOrCreate(source, selector, static (src, s) => new SelectFeed(src, s)); /// /// Gets or create a feed that asynchronously projects each value of a source feed. @@ -91,6 +91,6 @@ public static IFeed Select( public static IFeed SelectAsync( this IFeed source, AsyncFunc selector) - => AttachedProperty.GetOrCreate(source, selector, (src, s) => new SelectAsyncFeed(src, s)); + => AttachedProperty.GetOrCreate(source, selector, static (src, s) => new SelectAsyncFeed(src, s)); #endregion } diff --git a/src/Uno.Extensions.Reactive/Core/ListFeed.T.cs b/src/Uno.Extensions.Reactive/Core/ListFeed.T.cs index fc1c29423f..5cbea47279 100644 --- a/src/Uno.Extensions.Reactive/Core/ListFeed.T.cs +++ b/src/Uno.Extensions.Reactive/Core/ListFeed.T.cs @@ -74,7 +74,7 @@ public static IListFeed AsyncEnumerable(FuncThe async method to load a page of items. /// A paginated list feed. public static IListFeed AsyncPaginatedByCursor(TCursor firstPage, GetPage getPage) - => AttachedProperty.GetOrCreate(getPage.Target ?? getPage.Method, (firstPage, getPage), (_, args) => new PaginatedListFeed(args.firstPage, args.getPage)); + => AttachedProperty.GetOrCreate(getPage.Target ?? getPage.Method, (firstPage, getPage), static (_, args) => new PaginatedListFeed(args.firstPage, args.getPage)); /// /// Creates a list feed for a paginated collection. @@ -82,5 +82,5 @@ public static IListFeed AsyncPaginatedByCursor(TCursor firstPage, Ge /// The async method to load a page of items. /// A paginated list feed. public static IListFeed AsyncPaginated(AsyncFunc> getPage) - => AttachedProperty.GetOrCreate(getPage, gp => new PaginatedListFeed, T>(ByIndexCursor.First, ByIndexCursor.GetPage(gp))); + => AttachedProperty.GetOrCreate(getPage, static gp => new PaginatedListFeed, T>(ByIndexCursor.First, ByIndexCursor.GetPage(gp))); } diff --git a/src/Uno.Extensions.Reactive/Core/ListFeed.cs b/src/Uno.Extensions.Reactive/Core/ListFeed.cs index c5f0b0bfa9..49f722312f 100644 --- a/src/Uno.Extensions.Reactive/Core/ListFeed.cs +++ b/src/Uno.Extensions.Reactive/Core/ListFeed.cs @@ -81,7 +81,7 @@ public static IListFeed AsyncPaginated(AsyncFunc Where( this IListFeed source, Predicate predicate) - => AttachedProperty.GetOrCreate(source, predicate, (src, p) => new WhereListFeed(src, p)); + => AttachedProperty.GetOrCreate(source, predicate, static (src, p) => new WhereListFeed(src, p)); //public static IListFeed Select( // this IListFeed source, diff --git a/src/Uno.Extensions.Reactive/Core/State.T.cs b/src/Uno.Extensions.Reactive/Core/State.T.cs index 7cc35beeec..347ff83a2d 100644 --- a/src/Uno.Extensions.Reactive/Core/State.T.cs +++ b/src/Uno.Extensions.Reactive/Core/State.T.cs @@ -25,7 +25,7 @@ public static partial class State /// A feed that encapsulate the source. public static IState Create(TOwner owner, Func>> sourceProvider) where TOwner : class - => AttachedProperty.GetOrCreate(owner, sourceProvider, (o, sp) => S(o, new CustomFeed(sp))); + => AttachedProperty.GetOrCreate(owner, sourceProvider, static (o, sp) => S(o, new CustomFeed(sp))); /// /// Creates a custom feed from a raw sequence of . @@ -34,7 +34,7 @@ public static IState Create(TOwner owner, FuncA feed that encapsulate the source. [EditorBrowsable(EditorBrowsableState.Never)] internal static IState Create(Func>> sourceProvider) - => AttachedProperty.GetOrCreate(Validate(sourceProvider), sp => S(sp, new CustomFeed(sp))); + => AttachedProperty.GetOrCreate(Validate(sourceProvider), static sp => S(sp, new CustomFeed(sp))); /// /// Creates a custom feed from a raw sequence of . @@ -45,7 +45,7 @@ internal static IState Create(FuncA feed that encapsulate the source. public static IState Create(TOwner owner, Func>> sourceProvider) where TOwner : class - => AttachedProperty.GetOrCreate(owner, sourceProvider, (o, sp) => S(o, new CustomFeed(_ => sp()))); + => AttachedProperty.GetOrCreate(owner, sourceProvider, static (o, sp) => S(o, new CustomFeed(_ => sp()))); /// /// Creates a custom feed from a raw sequence of . @@ -54,7 +54,7 @@ public static IState Create(TOwner owner, FuncA feed that encapsulate the source. [EditorBrowsable(EditorBrowsableState.Never)] internal static IState Create(Func>> sourceProvider) - => AttachedProperty.GetOrCreate(Validate(sourceProvider), sp => S(sp, new CustomFeed(_ => sp()))); + => AttachedProperty.GetOrCreate(Validate(sourceProvider), static sp => S(sp, new CustomFeed(_ => sp()))); /// /// Gets or creates an empty state. @@ -72,7 +72,7 @@ public static IState Empty(TOwner owner, [CallerMemberName] string? n name ?? throw new InvalidOperationException("The name of the state must not be null"), line <0 ? throw new InvalidOperationException("The provided line number is invalid.") : line ), - (o, _) => SourceContext.GetOrCreate(o).CreateState(Option.None())); + static (o, _) => SourceContext.GetOrCreate(o).CreateState(Option.None())); /// /// Gets or creates a state from a static initial value. @@ -84,7 +84,7 @@ public static IState Empty(TOwner owner, [CallerMemberName] string? n public static IState Value(TOwner owner, Func valueProvider) where TOwner : class // Note: We force the usage of delegate so 2 properties which are doing State.Value(this, () => 42) will effectively have 2 distinct states. - => AttachedProperty.GetOrCreate(owner, valueProvider, (o, v) => SourceContext.GetOrCreate(o).CreateState(Option.Some(v()))); + => AttachedProperty.GetOrCreate(owner, valueProvider, static (o, v) => SourceContext.GetOrCreate(o).CreateState(Option.Some(v()))); /// /// Gets or creates a state from a static initial value. @@ -96,7 +96,7 @@ public static IState Value(TOwner owner, Func valueProvider) public static IState Value(TOwner owner, Func> valueProvider) where TOwner : class // Note: We force the usage of delegate so 2 properties which are doing State.Value(this, () => 42) will effectively have 2 distinct states. - => AttachedProperty.GetOrCreate(owner, valueProvider, (o, v) => SourceContext.GetOrCreate(owner).CreateState(v())); + => AttachedProperty.GetOrCreate(owner, valueProvider, static (o, v) => SourceContext.GetOrCreate(o).CreateState(v())); /// /// Gets or creates a state from an async method. @@ -108,7 +108,7 @@ public static IState Value(TOwner owner, Func> valueProvide /// A feed that encapsulate the source. public static IState Async(TOwner owner, AsyncFunc> valueProvider, Signal? refresh = null) where TOwner : class - => AttachedProperty.GetOrCreate(owner, (valueProvider, refresh), (o, args) => S(o, new AsyncFeed(args.valueProvider, args.refresh))); + => AttachedProperty.GetOrCreate(owner, (valueProvider, refresh), static (o, args) => S(o, new AsyncFeed(args.valueProvider, args.refresh))); /// /// Gets or creates a state from an async method. @@ -120,7 +120,7 @@ public static IState Async(TOwner owner, AsyncFunc> valuePr internal static IState Async(AsyncFunc> valueProvider, Signal? refresh = null) => refresh is null ? AttachedProperty.GetOrCreate(Validate(valueProvider), vp => S(vp, new AsyncFeed(vp))) - : AttachedProperty.GetOrCreate(refresh, Validate(valueProvider), (r, vp) => S(vp, new AsyncFeed(vp, r))); + : AttachedProperty.GetOrCreate(refresh, Validate(valueProvider), static (r, vp) => S(vp, new AsyncFeed(vp, r))); /// /// Gets or creates a state from an async method. @@ -132,7 +132,7 @@ internal static IState Async(AsyncFunc> valueProvider, Signal? refr /// A feed that encapsulate the source. public static IState Async(TOwner owner, AsyncFunc valueProvider, Signal? refresh = null) where TOwner : class - => AttachedProperty.GetOrCreate(owner, (valueProvider, refresh), (o, args) => S(o, new AsyncFeed(args.valueProvider, args.refresh))); + => AttachedProperty.GetOrCreate(owner, (valueProvider, refresh), static (o, args) => S(o, new AsyncFeed(args.valueProvider, args.refresh))); /// /// Gets or creates a state from an async method. @@ -143,8 +143,8 @@ public static IState Async(TOwner owner, AsyncFunc valueProvider, [EditorBrowsable(EditorBrowsableState.Never)] internal static IState Async(AsyncFunc valueProvider, Signal? refresh = null) => refresh is null - ? AttachedProperty.GetOrCreate(Validate(valueProvider), vp => S(vp, new AsyncFeed(vp))) - : AttachedProperty.GetOrCreate(refresh, Validate(valueProvider), (r, vp) => S(vp, new AsyncFeed(vp, r))); + ? AttachedProperty.GetOrCreate(Validate(valueProvider), static vp => S(vp, new AsyncFeed(vp))) + : AttachedProperty.GetOrCreate(refresh, Validate(valueProvider), static (r, vp) => S(vp, new AsyncFeed(vp, r))); /// /// Gets or creates a state from an async enumerable sequence of value. @@ -155,7 +155,7 @@ internal static IState Async(AsyncFunc valueProvider, Signal? refresh = nu /// A feed that encapsulate the source. public static IState AsyncEnumerable(TOwner owner, Func>> enumerableProvider) where TOwner : class - => AttachedProperty.GetOrCreate(owner, enumerableProvider, (o, ep) => S(o, new AsyncEnumerableFeed(ep))); + => AttachedProperty.GetOrCreate(owner, enumerableProvider, static (o, ep) => S(o, new AsyncEnumerableFeed(ep))); /// /// Gets or creates a state from an async enumerable sequence of value. @@ -166,7 +166,7 @@ public static IState AsyncEnumerable(TOwner owner, FuncA feed that encapsulate the source. public static IState AsyncEnumerable(TOwner owner, Func>> enumerableProvider) where TOwner : class - => AttachedProperty.GetOrCreate(owner, enumerableProvider, (o, ep) => S(o, new AsyncEnumerableFeed(ep))); + => AttachedProperty.GetOrCreate(owner, enumerableProvider, static (o, ep) => S(o, new AsyncEnumerableFeed(ep))); /// /// Gets or creates a state from an async enumerable sequence of value. @@ -175,7 +175,7 @@ public static IState AsyncEnumerable(TOwner owner, FuncA feed that encapsulate the source. [EditorBrowsable(EditorBrowsableState.Never)] internal static IState AsyncEnumerable(Func>> enumerableProvider) - => AttachedProperty.GetOrCreate(Validate(enumerableProvider), ep => S(ep, new AsyncEnumerableFeed(ep))); + => AttachedProperty.GetOrCreate(Validate(enumerableProvider), static ep => S(ep, new AsyncEnumerableFeed(ep))); /// /// Gets or creates a state from an async enumerable sequence of value. @@ -186,7 +186,7 @@ internal static IState AsyncEnumerable(Func>> enum /// A feed that encapsulate the source. public static IState AsyncEnumerable(TOwner owner, Func> enumerableProvider) where TOwner : class - => AttachedProperty.GetOrCreate(owner, enumerableProvider, (o, ep) => S(o, new AsyncEnumerableFeed(ep))); + => AttachedProperty.GetOrCreate(owner, enumerableProvider, static (o, ep) => S(o, new AsyncEnumerableFeed(ep))); /// /// Gets or creates a state from an async enumerable sequence of value. @@ -197,7 +197,7 @@ public static IState AsyncEnumerable(TOwner owner, FuncA feed that encapsulate the source. public static IState AsyncEnumerable(TOwner owner, Func> enumerableProvider) where TOwner : class - => AttachedProperty.GetOrCreate(owner, enumerableProvider, (o, ep) => S(o, new AsyncEnumerableFeed(ep))); + => AttachedProperty.GetOrCreate(owner, enumerableProvider, static (o, ep) => S(o, new AsyncEnumerableFeed(ep))); /// /// Gets or creates a state from an async enumerable sequence of value. @@ -206,7 +206,7 @@ public static IState AsyncEnumerable(TOwner owner, FuncA feed that encapsulate the source. [EditorBrowsable(EditorBrowsableState.Never)] internal static IState AsyncEnumerable(Func> enumerableProvider) - => AttachedProperty.GetOrCreate(Validate(enumerableProvider), ep => S(ep, new AsyncEnumerableFeed(ep))); + => AttachedProperty.GetOrCreate(Validate(enumerableProvider), static ep => S(ep, new AsyncEnumerableFeed(ep))); /// /// Gets or creates a state from an async enumerable sequence of value. @@ -217,7 +217,7 @@ internal static IState AsyncEnumerable(Func> enumerablePr /// A feed that encapsulate the source. public static IState FromFeed(TOwner owner, IFeed feed) where TOwner : class - => AttachedProperty.GetOrCreate(owner, feed, (o, f) => S(o, f)); + => AttachedProperty.GetOrCreate(owner, feed, static (o, f) => S(o, f)); private static TKey Validate(TKey key, [CallerMemberName] string? caller = null) where TKey : Delegate From 0d045fa4945bb6fac326d6f25765f9b8ef713e67 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 7 Nov 2022 10:15:08 -0500 Subject: [PATCH 2/2] docs: Add doc on Option --- src/Uno.Extensions.Core/Option.T.cs | 58 +++++++++++++++++++++++++++ src/Uno.Extensions.Core/OptionType.cs | 16 ++++++-- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/Uno.Extensions.Core/Option.T.cs b/src/Uno.Extensions.Core/Option.T.cs index 2b505b1be5..4a2db72237 100644 --- a/src/Uno.Extensions.Core/Option.T.cs +++ b/src/Uno.Extensions.Core/Option.T.cs @@ -5,14 +5,31 @@ namespace Uno.Extensions; +/// +/// A wrapper over a optional value that describes its absence or presence. +/// +/// The type of the value public readonly struct Option : IOption, IEquatable> { + /// + /// Creates a new optional value that is flagged as present. + /// + /// The value. + /// The optional value. public static Option Some(T value) => new(OptionType.Some, value); + /// + /// Creates a new optional value that is flagged as absent. + /// + /// The optional value. public static Option None() => default; + /// + /// Creates a new optional value that is flagged as neither present nor absent. + /// + /// The optional value. public static Option Undefined() => new(OptionType.Undefined); @@ -25,40 +42,73 @@ internal Option(OptionType type, T? value = default) _value = value; } + /// + /// Gets the type of this optional value. + /// public OptionType Type => _type; + /// + /// Gets a boolean that indicates if the of this optional is . + /// public bool IsUndefined() => _type is OptionType.Undefined; + /// + /// Gets a boolean that indicates if the of this optional is . + /// public bool IsNone() => _type is OptionType.None; + /// + /// Gets a boolean that indicates if the of this optional is . + /// + /// The value is any. public bool IsSome([NotNullWhen(true)] out T value) { value = _value!; return _type is OptionType.Some; } + /// bool IOption.IsSome(out object? value) { value = _value; return _type is OptionType.Some; } + /// + /// Gets the value if is , other returns the default(). + /// + /// The value if Some, default(T) otherwise. public T? SomeOrDefault() => _value; + /// object? IOption.SomeOrDefault() => _value; + /// + /// Gets the value if is , other returns the . + /// + /// The default value to return is this optional value is not present. + /// The value if Some, otherwise. public T SomeOrDefault(T defaultValue) => _type is OptionType.Some ? _value! : defaultValue; + /// + /// Creates a new optional value that is flagged as present. + /// + /// The value. public static implicit operator Option(T value) => new(OptionType.Some, value); + /// + /// Gets the value of an option value if its is + /// + /// The optional value. + /// If the is not . public static explicit operator T(Option option) { if (option._type is not OptionType.Some) @@ -69,9 +119,17 @@ public static explicit operator T(Option option) return option._value!; } + /// + /// Changes the type of an optional value. + /// + /// The optional value. public static explicit operator Option(Option option) => new(option._type, option._value); + /// + /// Changes the type of an optional value. + /// + /// The optional value. public static explicit operator Option(Option option) => new(option._type, option._value is T value ? value : default); diff --git a/src/Uno.Extensions.Core/OptionType.cs b/src/Uno.Extensions.Core/OptionType.cs index 3552f6e99d..ee680563bc 100644 --- a/src/Uno.Extensions.Core/OptionType.cs +++ b/src/Uno.Extensions.Core/OptionType.cs @@ -1,15 +1,25 @@ -#pragma warning disable CS1591 // XML Doc, will be moved elsewhere - -using System; +using System; using System.Linq; namespace Uno.Extensions; +/// +/// Defines the possible types of an +/// public enum OptionType : short { + /// + /// Indicates the absence of a value + /// None = 0, // The default so default(Option) == Option.None + /// + /// Indicates the presence of a value + /// Some = 1, + /// + /// Indicates that incertitude about the presence or the absence of a value. + /// Undefined = -1, }