Skip to content

Commit d252601

Browse files
committed
add support for nullable, minor cleanup, improve UrlBuilder
1 parent 56638cc commit d252601

32 files changed

Lines changed: 703 additions & 528 deletions

.github/dependabot.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,6 @@ updates:
5555
- "xunit.core"
5656
- "xunit.extensibility.*"
5757
- "xunit.runner.*"
58+
ignore:
59+
- dependency-name: FluentAssertions
60+
versions: [">=8.0.0"]

FluentRest.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{A4E004F2-9E26-4A47-A509-F8DA024A8436}"
77
ProjectSection(SolutionItems) = preProject
88
coverlet.runsettings = coverlet.runsettings
9+
.github\dependabot.yml = .github\dependabot.yml
910
src\Directory.Build.props = src\Directory.Build.props
1011
.github\workflows\dotnet.yml = .github\workflows\dotnet.yml
1112
README.md = README.md

src/FluentRest.Fake/FakeContainerBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public FakeContainerBuilder(FakeResponseContainer container) : base(container)
4949
/// <exception cref="System.ArgumentNullException"><paramref name="value" /> is <see langword="null" />.</exception>
5050
public FakeResponseBuilder Url(string value)
5151
{
52-
if (value == null)
52+
if (value is null)
5353
throw new ArgumentNullException(nameof(value));
5454

5555
Container.RequestUri = new Uri(value, UriKind.Absolute);
@@ -65,7 +65,7 @@ public FakeResponseBuilder Url(string value)
6565
/// <exception cref="System.ArgumentNullException"><paramref name="value" /> is <see langword="null" />.</exception>
6666
public FakeResponseBuilder Url(Uri value)
6767
{
68-
if (value == null)
68+
if (value is null)
6969
throw new ArgumentNullException(nameof(value));
7070

7171
Container.RequestUri = value;

src/FluentRest.Fake/FakeContentBuilder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ public FakeContentBuilder(FakeResponseContainer container) : base(container)
2727
/// <exception cref="ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
2828
public FakeContentBuilder Header(string name, string value)
2929
{
30-
if (name == null)
30+
if (name is null)
3131
throw new ArgumentNullException(nameof(name));
3232

33-
if (value == null)
33+
if (value is null)
3434
Container.ResponseMessage.ContentHeaders.Remove(name);
3535
else
3636
Container.ResponseMessage.ContentHeaders[name] = new List<string>(new[] { value });
@@ -60,7 +60,7 @@ public FakeContentBuilder Data<T>(T value, SerializeResponseContentCallback seri
6060
}
6161
else
6262
{
63-
if (serializer == null)
63+
if (serializer is null)
6464
serializer = this.Container.SerializeResponseContentCallback ?? DefaultSerializer;
6565

6666
content = serializer(value, typeof(T));

src/FluentRest.Fake/FakeResponseBuilder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public FakeResponseBuilder StatusCode(HttpStatusCode value)
4040
/// <exception cref="ArgumentNullException"><paramref name="value" /> is <see langword="null" />.</exception>
4141
public FakeResponseBuilder ReasonPhrase(string value)
4242
{
43-
if (value == null)
43+
if (value is null)
4444
throw new ArgumentNullException(nameof(value));
4545

4646
Container.ResponseMessage.ReasonPhrase = value;
@@ -56,10 +56,10 @@ public FakeResponseBuilder ReasonPhrase(string value)
5656
/// <exception cref="ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
5757
public FakeResponseBuilder Header(string name, string value)
5858
{
59-
if (name == null)
59+
if (name is null)
6060
throw new ArgumentNullException(nameof(name));
6161

62-
if (value == null)
62+
if (value is null)
6363
Container.ResponseMessage.ResponseHeaders.Remove(name);
6464
else
6565
Container.ResponseMessage.ResponseHeaders[name] = new List<string>(new[] { value });
@@ -77,7 +77,7 @@ public FakeResponseBuilder Header(string name, string value)
7777
/// <exception cref="ArgumentNullException"><paramref name="builder" /> is <see langword="null" />.</exception>
7878
public FakeResponseBuilder Content(Action<FakeContentBuilder> builder)
7979
{
80-
if (builder == null)
80+
if (builder is null)
8181
throw new ArgumentNullException(nameof(builder));
8282

8383
var contentBuilder = new FakeContentBuilder(Container);

src/FluentRest.Fake/FileMessageStore.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public override async Task<HttpResponseMessage> LoadAsync(HttpRequestMessage req
8080
private async Task SaveContent(HttpResponseMessage response, string contentPath)
8181
{
8282
// don't save content if not success
83-
if (!response.IsSuccessStatusCode || response.Content == null || response.StatusCode == HttpStatusCode.NoContent)
83+
if (!response.IsSuccessStatusCode || response.Content is null || response.StatusCode == HttpStatusCode.NoContent)
8484
return;
8585

8686
var contents = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
@@ -118,7 +118,7 @@ private async Task<HttpResponseMessage> LoadResponse(HttpContent httpContent, st
118118
fakeResponse = await JsonSerializer.DeserializeAsync<FakeResponseMessage>(reader);
119119

120120
var httpResponse = Convert(fakeResponse);
121-
if (httpContent == null)
121+
if (httpContent is null)
122122
return httpResponse;
123123

124124
// copy headers

src/FluentRest.Fake/MemoryMessageStore.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public class MemoryMessageStore : FakeMessageStore
4545
public override async Task SaveAsync(HttpRequestMessage request, HttpResponseMessage response)
4646
{
4747
// don't save content if not success
48-
if (!response.IsSuccessStatusCode || response.Content == null || response.StatusCode == HttpStatusCode.NoContent)
48+
if (!response.IsSuccessStatusCode || response.Content is null || response.StatusCode == HttpStatusCode.NoContent)
4949
return;
5050

5151
var httpContent = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
@@ -93,7 +93,7 @@ public override Task<HttpResponseMessage> LoadAsync(HttpRequestMessage request)
9393

9494
taskSource.SetResult(httpResponse);
9595

96-
if (container.HttpContent == null)
96+
if (container.HttpContent is null)
9797
return taskSource.Task;
9898

9999
var httpContent = new ByteArrayContent(container.HttpContent);
@@ -116,7 +116,7 @@ public override Task<HttpResponseMessage> LoadAsync(HttpRequestMessage request)
116116
/// <exception cref="ArgumentNullException"></exception>
117117
public void Register(Action<FakeContainerBuilder> builder)
118118
{
119-
if (builder == null)
119+
if (builder is null)
120120
throw new ArgumentNullException(nameof(builder));
121121

122122
var container = new FakeResponseContainer

src/FluentRest.NewtonsoftJson/NewtonsoftJsonSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public NewtonsoftJsonSerializer(JsonSerializerSettings settings = null)
4949
/// <returns>The <see cref="HttpContent"/> that the data object serialized to.</returns>
5050
public Task<HttpContent> SerializeAsync(object data)
5151
{
52-
if (data == null)
52+
if (data is null)
5353
return null;
5454

5555
string json;
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#if NETSTANDARD2_0
2+
namespace System.Diagnostics.CodeAnalysis;
3+
4+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
5+
public sealed class AllowNullAttribute : Attribute
6+
{ }
7+
8+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
9+
public sealed class DisallowNullAttribute : Attribute
10+
{ }
11+
12+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
13+
public sealed class MaybeNullAttribute : Attribute
14+
{ }
15+
16+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
17+
public sealed class NotNullAttribute : Attribute
18+
{ }
19+
20+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
21+
public sealed class MaybeNullWhenAttribute : Attribute
22+
{
23+
public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
24+
25+
public bool ReturnValue { get; }
26+
}
27+
28+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
29+
public sealed class NotNullWhenAttribute : Attribute
30+
{
31+
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
32+
33+
public bool ReturnValue { get; }
34+
}
35+
36+
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
37+
public sealed class NotNullIfNotNullAttribute : Attribute
38+
{
39+
public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
40+
41+
public string ParameterName { get; }
42+
}
43+
44+
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
45+
public sealed class DoesNotReturnAttribute : Attribute
46+
{ }
47+
48+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
49+
public sealed class DoesNotReturnIfAttribute : Attribute
50+
{
51+
public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
52+
53+
public bool ParameterValue { get; }
54+
}
55+
56+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
57+
public sealed class MemberNotNullAttribute : Attribute
58+
{
59+
public MemberNotNullAttribute(string member) => Members = [member];
60+
61+
public MemberNotNullAttribute(params string[] members) => Members = members;
62+
63+
public string[] Members { get; }
64+
}
65+
66+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
67+
public sealed class MemberNotNullWhenAttribute : Attribute
68+
{
69+
public MemberNotNullWhenAttribute(bool returnValue, string member)
70+
{
71+
ReturnValue = returnValue;
72+
Members = [member];
73+
}
74+
75+
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
76+
{
77+
ReturnValue = returnValue;
78+
Members = members;
79+
}
80+
81+
public bool ReturnValue { get; }
82+
83+
public string[] Members { get; }
84+
}
85+
#endif

src/FluentRest/DictionaryExtensions.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
13
namespace FluentRest;
24

35
/// <summary>
@@ -19,16 +21,16 @@ public static class DictionaryExtensions
1921
/// <exception cref="ArgumentNullException"><paramref name="key" /> is <see langword="null" /></exception>
2022
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TValue> valueFactory)
2123
{
22-
if (key == null)
24+
if (key is null)
2325
throw new ArgumentNullException(nameof(key));
2426

2527
if (dictionary.TryGetValue(key, out var value))
2628
return value;
2729

28-
value = valueFactory(key);
29-
dictionary.Add(key, value);
30+
var factoryValue = valueFactory(key);
31+
dictionary.Add(key, factoryValue);
3032

31-
return value;
33+
return factoryValue;
3234
}
3335

3436
/// <summary>
@@ -45,7 +47,7 @@ public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dicti
4547
/// <exception cref="ArgumentNullException"><paramref name="key" /> is <see langword="null" /></exception>
4648
public static bool TryAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
4749
{
48-
if (key == null)
50+
if (key is null)
4951
throw new ArgumentNullException(nameof(key));
5052

5153
if (dictionary.ContainsKey(key))
@@ -65,9 +67,9 @@ public static bool TryAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionar
6567
/// <param name="value">When this method returns, value contains the object removed from the Dictionary or the default value if the operation failed.</param>
6668
/// <returns><c>true</c> if an object was removed successfully; otherwise, <c>false</c>.</returns>
6769
/// <exception cref="ArgumentNullException"><paramref name="key" /> is <see langword="null" /></exception>
68-
public static bool TryRemove<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, out TValue value)
70+
public static bool TryRemove<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, [MaybeNullWhen(false)] out TValue? value)
6971
{
70-
if (key == null)
72+
if (key is null)
7173
throw new ArgumentNullException(nameof(key));
7274

7375
if (!dictionary.TryGetValue(key, out value))
@@ -89,7 +91,7 @@ public static bool TryRemove<TKey, TValue>(this IDictionary<TKey, TValue> dictio
8991
/// <exception cref="System.ArgumentNullException">Thrown if key is a <c>null</c> reference </exception>
9092
public static bool TryUpdate<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue newValue, TValue comparisonValue)
9193
{
92-
if (key == null)
94+
if (key is null)
9395
throw new ArgumentNullException(nameof(key));
9496

9597
if (!dictionary.TryGetValue(key, out var value))

0 commit comments

Comments
 (0)