Restructured the project structure back to the way it was, there's no reasonable way to split the modules

This commit is contained in:
Kwoth
2024-04-26 22:26:24 +00:00
parent 6c9c8bf63e
commit e0819f760c
768 changed files with 192 additions and 1047 deletions

View File

@@ -0,0 +1,11 @@
#nullable disable
namespace NadekoBot.Common.Yml;
[AttributeUsage(AttributeTargets.Property)]
public class CommentAttribute : Attribute
{
public string Comment { get; }
public CommentAttribute(string comment)
=> Comment = comment;
}

View File

@@ -0,0 +1,65 @@
#nullable disable
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.TypeInspectors;
namespace NadekoBot.Common.Yml;
public class CommentGatheringTypeInspector : TypeInspectorSkeleton
{
private readonly ITypeInspector _innerTypeDescriptor;
public CommentGatheringTypeInspector(ITypeInspector innerTypeDescriptor)
=> _innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException(nameof(innerTypeDescriptor));
public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object container)
=> _innerTypeDescriptor.GetProperties(type, container).Select(d => new CommentsPropertyDescriptor(d));
private sealed class CommentsPropertyDescriptor : IPropertyDescriptor
{
public string Name { get; }
public Type Type
=> _baseDescriptor.Type;
public Type TypeOverride
{
get => _baseDescriptor.TypeOverride;
set => _baseDescriptor.TypeOverride = value;
}
public int Order { get; set; }
public ScalarStyle ScalarStyle
{
get => _baseDescriptor.ScalarStyle;
set => _baseDescriptor.ScalarStyle = value;
}
public bool CanWrite
=> _baseDescriptor.CanWrite;
private readonly IPropertyDescriptor _baseDescriptor;
public CommentsPropertyDescriptor(IPropertyDescriptor baseDescriptor)
{
_baseDescriptor = baseDescriptor;
Name = baseDescriptor.Name;
}
public void Write(object target, object value)
=> _baseDescriptor.Write(target, value);
public T GetCustomAttribute<T>()
where T : Attribute
=> _baseDescriptor.GetCustomAttribute<T>();
public IObjectDescriptor Read(object target)
{
var comment = _baseDescriptor.GetCustomAttribute<CommentAttribute>();
return comment is not null
? new CommentsObjectDescriptor(_baseDescriptor.Read(target), comment.Comment)
: _baseDescriptor.Read(target);
}
}
}

View File

@@ -0,0 +1,30 @@
#nullable disable
using YamlDotNet.Core;
using YamlDotNet.Serialization;
namespace NadekoBot.Common.Yml;
public sealed class CommentsObjectDescriptor : IObjectDescriptor
{
public string Comment { get; }
public object Value
=> _innerDescriptor.Value;
public Type Type
=> _innerDescriptor.Type;
public Type StaticType
=> _innerDescriptor.StaticType;
public ScalarStyle ScalarStyle
=> _innerDescriptor.ScalarStyle;
private readonly IObjectDescriptor _innerDescriptor;
public CommentsObjectDescriptor(IObjectDescriptor innerDescriptor, string comment)
{
_innerDescriptor = innerDescriptor;
Comment = comment;
}
}

View File

@@ -0,0 +1,29 @@
#nullable disable
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.ObjectGraphVisitors;
namespace NadekoBot.Common.Yml;
public class CommentsObjectGraphVisitor : ChainedObjectGraphVisitor
{
public CommentsObjectGraphVisitor(IObjectGraphVisitor<IEmitter> nextVisitor)
: base(nextVisitor)
{
}
public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context)
{
if (value is CommentsObjectDescriptor commentsDescriptor
&& !string.IsNullOrWhiteSpace(commentsDescriptor.Comment))
{
var parts = commentsDescriptor.Comment.Split('\n');
foreach (var part in parts)
context.Emit(new Comment(part.Trim(), false));
}
return base.EnterMapping(key, value, context);
}
}

View File

@@ -0,0 +1,35 @@
#nullable disable
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.EventEmitters;
namespace NadekoBot.Common.Yml;
public class MultilineScalarFlowStyleEmitter : ChainedEventEmitter
{
public MultilineScalarFlowStyleEmitter(IEventEmitter nextEmitter)
: base(nextEmitter)
{
}
public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
{
if (typeof(string).IsAssignableFrom(eventInfo.Source.Type))
{
var value = eventInfo.Source.Value as string;
if (!string.IsNullOrEmpty(value))
{
var isMultiLine = value.IndexOfAny(new[] { '\r', '\n', '\x85', '\x2028', '\x2029' }) >= 0;
if (isMultiLine)
{
eventInfo = new(eventInfo.Source)
{
Style = ScalarStyle.Literal
};
}
}
}
nextEmitter.Emit(eventInfo, emitter);
}
}

View File

@@ -0,0 +1,47 @@
#nullable disable
using SixLabors.ImageSharp.PixelFormats;
using System.Globalization;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;
namespace NadekoBot.Common.Yml;
public class Rgba32Converter : IYamlTypeConverter
{
public bool Accepts(Type type)
=> type == typeof(Rgba32);
public object ReadYaml(IParser parser, Type type)
{
var scalar = parser.Consume<Scalar>();
var result = Rgba32.ParseHex(scalar.Value);
return result;
}
public void WriteYaml(IEmitter emitter, object value, Type type)
{
var color = (Rgba32)value;
var val = (uint)((color.B << 0) | (color.G << 8) | (color.R << 16));
emitter.Emit(new Scalar(val.ToString("X6").ToLower()));
}
}
public class CultureInfoConverter : IYamlTypeConverter
{
public bool Accepts(Type type)
=> type == typeof(CultureInfo);
public object ReadYaml(IParser parser, Type type)
{
var scalar = parser.Consume<Scalar>();
var result = new CultureInfo(scalar.Value);
return result;
}
public void WriteYaml(IEmitter emitter, object value, Type type)
{
var ci = (CultureInfo)value;
emitter.Emit(new Scalar(ci.Name));
}
}

View File

@@ -0,0 +1,25 @@
#nullable disable
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;
namespace NadekoBot.Common.Yml;
public class UriConverter : IYamlTypeConverter
{
public bool Accepts(Type type)
=> type == typeof(Uri);
public object ReadYaml(IParser parser, Type type)
{
var scalar = parser.Consume<Scalar>();
var result = new Uri(scalar.Value);
return result;
}
public void WriteYaml(IEmitter emitter, object value, Type type)
{
var uri = (Uri)value;
emitter.Emit(new Scalar(uri.ToString()));
}
}

View File

@@ -0,0 +1,28 @@
#nullable disable
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace NadekoBot.Common.Yml;
public class Yaml
{
public static ISerializer Serializer
=> new SerializerBuilder().WithTypeInspector(inner => new CommentGatheringTypeInspector(inner))
.WithEmissionPhaseObjectGraphVisitor(args
=> new CommentsObjectGraphVisitor(args.InnerVisitor))
.WithEventEmitter(args => new MultilineScalarFlowStyleEmitter(args))
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithIndentedSequences()
.WithTypeConverter(new Rgba32Converter())
.WithTypeConverter(new CultureInfoConverter())
.WithTypeConverter(new UriConverter())
.Build();
public static IDeserializer Deserializer
=> new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithTypeConverter(new Rgba32Converter())
.WithTypeConverter(new CultureInfoConverter())
.WithTypeConverter(new UriConverter())
.IgnoreUnmatchedProperties()
.Build();
}