diff --git a/Remora.Results.sln.DotSettings b/Remora.Results.sln.DotSettings index cc1f393..cc4671d 100644 --- a/Remora.Results.sln.DotSettings +++ b/Remora.Results.sln.DotSettings @@ -122,10 +122,19 @@ <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static fields (not private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy> True True True True + True True True True diff --git a/Remora.Results/AggregateResult.cs b/Remora.Results/AggregateResult.cs new file mode 100644 index 0000000..e0d3450 --- /dev/null +++ b/Remora.Results/AggregateResult.cs @@ -0,0 +1,87 @@ +// +// AggregateResult.cs +// +// Author: +// Jarl Gullberg +// +// Copyright (c) Jarl Gullberg +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +using System.Collections.Generic; +using System.Linq; +using JetBrains.Annotations; + +namespace Remora.Results; + +/// +[PublicAPI] +public readonly struct AggregateResult : IResult +{ + /// + /// Gets a value indicating whether all the contained results were successful. + /// + public bool IsSuccess { get; } + + /// + /// Gets an containing the failed results. + /// + public IResultError Error => new AggregateError(_lookup[false].ToArray()); + + /// + /// + /// Always returns null. + /// + public IResult? Inner { get; } = null; + + /// + /// Gets a collection of successful results. + /// + public IEnumerable SuccessfulResults => _lookup[true]; + + /// + /// Gets a collection of failed results. + /// + public IEnumerable FailedResults => _lookup[false]; + + /// + /// Gets a readonly collection of the results contained in this collection. + /// + public IReadOnlyCollection Results => _results; + + private readonly IResult[] _results; + private readonly ILookup _lookup; + + /// + /// Initializes a new instance of the struct. + /// + /// The results to use. + public AggregateResult(params IResult[] results) + : this(results.All(it => it.IsSuccess), results) + { + } + + /// + /// Initializes a new instance of the struct. + /// + /// A value indicating whether all the results are successful. + /// The results. + internal AggregateResult(bool isSuccess, IResult[] results) + { + this.IsSuccess = isSuccess; + _results = results; + _lookup = this.Results.ToLookup(it => it.IsSuccess); + } +} diff --git a/Remora.Results/AggregateResultBuilder.cs b/Remora.Results/AggregateResultBuilder.cs new file mode 100644 index 0000000..2f70be9 --- /dev/null +++ b/Remora.Results/AggregateResultBuilder.cs @@ -0,0 +1,63 @@ +// +// AggregateResultBuilder.cs +// +// Author: +// Jarl Gullberg +// +// Copyright (c) Jarl Gullberg +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Remora.Results; + +/// +/// Allows for the construction of an AggregateResult. +/// +/// +/// This is intended for use within a foreach loop or in situations where results are added on their own +/// rather than as a group. If you have all the results available together, use . +/// +[PublicAPI] +public class AggregateResultBuilder +{ + private List _results = new(); + private bool _allSuccessful = true; + + /// + /// Adds the result to the collection. + /// + /// The result to add. + public void Add(IResult result) + { + if (!result.IsSuccess) + { + _allSuccessful = false; + } + + _results.Add(result); + } + + /// + /// Builds the . + /// + /// A new AggregateResult. + public AggregateResult Build() + { + return new AggregateResult(_allSuccessful, _results.ToArray()); + } +}