Huge refactor; Passing tests

This commit is contained in:
2024-01-13 01:25:32 +01:00
parent a03fafebcf
commit 7bc6086509
18 changed files with 500 additions and 208 deletions
@@ -0,0 +1,12 @@
using System.Reflection;
namespace SimpleHttpServer.Types;
internal struct EndpointInvocationInfo {
internal readonly MethodInfo methodInfo;
internal readonly List<(string, (Type type, bool isOptional))> queryParameters;
public EndpointInvocationInfo(MethodInfo methodInfo, List<(string, (Type type, bool isOptional))> queryParameters) {
this.methodInfo = methodInfo ?? throw new ArgumentNullException(nameof(methodInfo));
this.queryParameters = queryParameters ?? throw new ArgumentNullException(nameof(queryParameters));
}
}
@@ -0,0 +1,11 @@
namespace SimpleHttpServer.Types.Exceptions;
[Serializable]
public class AssertionFailedException : Exception {
public AssertionFailedException() { }
public AssertionFailedException(string message) : base(message) { }
public AssertionFailedException(string message, Exception inner) : base(message, inner) { }
protected AssertionFailedException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
@@ -0,0 +1,17 @@
using System.Runtime.Serialization;
namespace SimpleHttpServer.Types.Exceptions;
[Serializable]
internal class MissingParameterConverterException : Exception {
public MissingParameterConverterException() {
}
public MissingParameterConverterException(string? message) : base(message) {
}
public MissingParameterConverterException(string? message, Exception? innerException) : base(message, innerException) {
}
protected MissingParameterConverterException(SerializationInfo info, StreamingContext context) : base(info, context) {
}
}
@@ -0,0 +1,5 @@
namespace SimpleHttpServer;
public interface IParameterConverter {
bool TryConvertFromString(string value, out object result);
}
@@ -0,0 +1,21 @@
namespace SimpleHttpServer.Types;
/// <summary>
/// Specifies the name of a http endpoint parameter. If this attribute is not specified, the variable name is used instead.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
public sealed class ParameterAttribute : Attribute {
// See the attribute guidelines at
// http://go.microsoft.com/fwlink/?LinkId=85236
public string Name { get; }
public bool IsOptional { get; }
public ParameterAttribute(string name, bool isOptional = false) {
if (string.IsNullOrWhiteSpace(name)) {
throw new ArgumentException($"'{nameof(name)}' cannot be null or whitespace.", nameof(name));
}
Name = name;
IsOptional = isOptional;
}
}
@@ -0,0 +1,16 @@
namespace SimpleHttpServer.Types.ParameterConverters;
internal class BoolParsableParameterConverter : IParameterConverter {
public bool TryConvertFromString(string value, out object result) {
var normalized = value.ToLowerInvariant();
if (normalized is "true" or "1") {
result = true;
return true;
} else if (normalized is "false" or "0") {
result = false;
return true;
} else {
result = false;
return false;
}
}
}
@@ -0,0 +1,10 @@
using System.Diagnostics.CodeAnalysis;
namespace SimpleHttpServer.Types.ParameterConverters;
internal class ParsableParameterConverter<T> : IParameterConverter where T : IParsable<T> {
public bool TryConvertFromString(string value, [NotNullWhen(true)] out object result) {
bool ok = T.TryParse(value, null, out T? res);
result = res!;
return ok;
}
}