diff --git a/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs b/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs index 3edacd35c1d4..f5e87c57c3e8 100644 --- a/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs +++ b/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs @@ -7,6 +7,11 @@ public ApiKeyCredential(string key) { } public static implicit operator System.ClientModel.ApiKeyCredential (string key) { throw null; } public void Update(string key) { } } + public abstract partial class AsyncClientResultCollection : System.ClientModel.ClientResult, System.Collections.Generic.IAsyncEnumerable + { + protected internal AsyncClientResultCollection(System.ClientModel.Primitives.PipelineResponse response) : base (default(System.ClientModel.Primitives.PipelineResponse)) { } + public abstract System.Collections.Generic.IAsyncEnumerator GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + } public abstract partial class BinaryContent : System.IDisposable { protected BinaryContent() { } @@ -20,11 +25,18 @@ protected BinaryContent() { } } public partial class ClientResult { - protected ClientResult(System.ClientModel.Primitives.PipelineResponse response) { } + protected ClientResult(System.ClientModel.Primitives.PipelineResponse? response) { } public static System.ClientModel.ClientResult FromOptionalValue(T? value, System.ClientModel.Primitives.PipelineResponse response) { throw null; } public static System.ClientModel.ClientResult FromResponse(System.ClientModel.Primitives.PipelineResponse response) { throw null; } public static System.ClientModel.ClientResult FromValue(T value, System.ClientModel.Primitives.PipelineResponse response) { throw null; } public System.ClientModel.Primitives.PipelineResponse GetRawResponse() { throw null; } + protected void SetRawResponse(System.ClientModel.Primitives.PipelineResponse response) { } + } + public abstract partial class ClientResultCollection : System.ClientModel.ClientResult, System.Collections.Generic.IEnumerable, System.Collections.IEnumerable + { + protected internal ClientResultCollection(System.ClientModel.Primitives.PipelineResponse response) : base (default(System.ClientModel.Primitives.PipelineResponse)) { } + public abstract System.Collections.Generic.IEnumerator GetEnumerator(); + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } } public partial class ClientResultException : System.Exception { diff --git a/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs b/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs index 2367ba7f518d..1fc9b562afc2 100644 --- a/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs +++ b/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs @@ -7,6 +7,11 @@ public ApiKeyCredential(string key) { } public static implicit operator System.ClientModel.ApiKeyCredential (string key) { throw null; } public void Update(string key) { } } + public abstract partial class AsyncClientResultCollection : System.ClientModel.ClientResult, System.Collections.Generic.IAsyncEnumerable + { + protected internal AsyncClientResultCollection(System.ClientModel.Primitives.PipelineResponse response) : base (default(System.ClientModel.Primitives.PipelineResponse)) { } + public abstract System.Collections.Generic.IAsyncEnumerator GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + } public abstract partial class BinaryContent : System.IDisposable { protected BinaryContent() { } @@ -20,11 +25,18 @@ protected BinaryContent() { } } public partial class ClientResult { - protected ClientResult(System.ClientModel.Primitives.PipelineResponse response) { } + protected ClientResult(System.ClientModel.Primitives.PipelineResponse? response) { } public static System.ClientModel.ClientResult FromOptionalValue(T? value, System.ClientModel.Primitives.PipelineResponse response) { throw null; } public static System.ClientModel.ClientResult FromResponse(System.ClientModel.Primitives.PipelineResponse response) { throw null; } public static System.ClientModel.ClientResult FromValue(T value, System.ClientModel.Primitives.PipelineResponse response) { throw null; } public System.ClientModel.Primitives.PipelineResponse GetRawResponse() { throw null; } + protected void SetRawResponse(System.ClientModel.Primitives.PipelineResponse response) { } + } + public abstract partial class ClientResultCollection : System.ClientModel.ClientResult, System.Collections.Generic.IEnumerable, System.Collections.IEnumerable + { + protected internal ClientResultCollection(System.ClientModel.Primitives.PipelineResponse response) : base (default(System.ClientModel.Primitives.PipelineResponse)) { } + public abstract System.Collections.Generic.IEnumerator GetEnumerator(); + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } } public partial class ClientResultException : System.Exception { diff --git a/sdk/core/System.ClientModel/src/Convenience/AsyncClientResultCollectionOfT.cs b/sdk/core/System.ClientModel/src/Convenience/AsyncClientResultCollectionOfT.cs new file mode 100644 index 000000000000..cbfc5cc05490 --- /dev/null +++ b/sdk/core/System.ClientModel/src/Convenience/AsyncClientResultCollectionOfT.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Threading; + +namespace System.ClientModel; + +#pragma warning disable CS1591 // public XML comments +public abstract class AsyncClientResultCollection : ClientResult, IAsyncEnumerable +{ + protected internal AsyncClientResultCollection(PipelineResponse response) : base(response) + { + } + + public abstract IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); +} +#pragma warning restore CS1591 // public XML comments diff --git a/sdk/core/System.ClientModel/src/Convenience/ClientResult.cs b/sdk/core/System.ClientModel/src/Convenience/ClientResult.cs index 5f60f040fa3f..4943f7e4ade9 100644 --- a/sdk/core/System.ClientModel/src/Convenience/ClientResult.cs +++ b/sdk/core/System.ClientModel/src/Convenience/ClientResult.cs @@ -11,7 +11,7 @@ namespace System.ClientModel; /// public class ClientResult { - private readonly PipelineResponse _response; + private PipelineResponse? _response; /// /// Create a new instance of from a service @@ -19,10 +19,8 @@ public class ClientResult /// /// The received /// from the service. - protected ClientResult(PipelineResponse response) + protected ClientResult(PipelineResponse? response) { - Argument.AssertNotNull(response, nameof(response)); - _response = response; } @@ -31,7 +29,37 @@ protected ClientResult(PipelineResponse response) /// /// the received from the service. /// - public PipelineResponse GetRawResponse() => _response; + /// No + /// value is currently available for this + /// instance. This can happen when the instance + /// is a collection type like + /// that has not yet been enumerated. + public PipelineResponse GetRawResponse() + { + if (_response is null) + { + throw new InvalidOperationException("No response is associated " + + "with this result. If the result is a collection result " + + "type, this may be because no request has been sent to the " + + "server yet."); + } + + return _response; + } + + /// + /// Update the value returned from . + /// + /// This method may be called from types derived from + /// that poll the service for status updates + /// or to retrieve additional collection values to update the raw response + /// to the response most recently returned from the service. + /// The to return + /// from . + protected void SetRawResponse(PipelineResponse response) + { + _response = response; + } #region Factory methods for ClientResult and subtypes @@ -44,7 +72,11 @@ protected ClientResult(PipelineResponse response) /// provided . /// public static ClientResult FromResponse(PipelineResponse response) - => new ClientResult(response); + { + Argument.AssertNotNull(response, nameof(response)); + + return new ClientResult(response); + } /// /// Creates a new instance of that holds the @@ -60,6 +92,8 @@ public static ClientResult FromResponse(PipelineResponse response) /// public static ClientResult FromValue(T value, PipelineResponse response) { + Argument.AssertNotNull(response, nameof(response)); + if (value is null) { string message = "ClientResult contract guarantees that ClientResult.Value is non-null. " + @@ -90,7 +124,11 @@ public static ClientResult FromValue(T value, PipelineResponse response) /// provided and . /// public static ClientResult FromOptionalValue(T? value, PipelineResponse response) - => new ClientResult(value, response); + { + Argument.AssertNotNull(response, nameof(response)); + + return new ClientResult(value, response); + } #endregion } diff --git a/sdk/core/System.ClientModel/src/Convenience/ClientResultCollectionOfT.cs b/sdk/core/System.ClientModel/src/Convenience/ClientResultCollectionOfT.cs new file mode 100644 index 000000000000..5761d53af1f1 --- /dev/null +++ b/sdk/core/System.ClientModel/src/Convenience/ClientResultCollectionOfT.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.ClientModel.Primitives; +using System.Collections; +using System.Collections.Generic; + +namespace System.ClientModel; + +#pragma warning disable CS1591 // public XML comments +public abstract class ClientResultCollection : ClientResult, IEnumerable +{ + protected internal ClientResultCollection(PipelineResponse response) : base(response) + { + } + + public abstract IEnumerator GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); +} +#pragma warning restore CS1591 // public XML comments diff --git a/sdk/core/System.ClientModel/tests/Convenience/ClientResultTests.cs b/sdk/core/System.ClientModel/tests/Convenience/ClientResultTests.cs index ccad66170e57..629f1ec27f2b 100644 --- a/sdk/core/System.ClientModel/tests/Convenience/ClientResultTests.cs +++ b/sdk/core/System.ClientModel/tests/Convenience/ClientResultTests.cs @@ -15,7 +15,6 @@ public class PipelineResponseTests [Test] public void CannotCreateClientResultFromNullResponse() { - Assert.Throws(() => new MockClientResult(null!)); Assert.Throws(() => { ClientResult result = ClientResult.FromResponse(null!); @@ -98,7 +97,6 @@ public void CannotCreateClientResultOfTFromNullResponse() { object value = new(); - Assert.Throws(() => new MockClientResult(value, null!)); Assert.Throws(() => { ClientResult result = ClientResult.FromValue(value, null!);