mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2026-10-25 12:10:56 -04:00
Applied codestyle to all .cs files
This commit is contained in:
@@ -5,15 +5,14 @@ using SixLabors.ImageSharp.PixelFormats;
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Settings service for bot-wide configuration.
|
||||
/// Settings service for bot-wide configuration.
|
||||
/// </summary>
|
||||
public sealed class BotConfigService : ConfigServiceBase<BotConfig>
|
||||
{
|
||||
public override string Name { get; } = "bot";
|
||||
|
||||
private const string FilePath = "data/bot.yml";
|
||||
private static readonly TypedKey<BotConfig> changeKey = new("config.bot.updated");
|
||||
|
||||
public override string Name { get; } = "bot";
|
||||
|
||||
public BotConfigService(IConfigSeria serializer, IPubSub pubSub)
|
||||
: base(FilePath, serializer, pubSub, changeKey)
|
||||
{
|
||||
@@ -25,15 +24,12 @@ public sealed class BotConfigService : ConfigServiceBase<BotConfig>
|
||||
AddParsedProp("console.type", bs => bs.ConsoleOutputType, Enum.TryParse, ConfigPrinters.ToString);
|
||||
AddParsedProp("locale", bs => bs.DefaultLocale, ConfigParsers.Culture, ConfigPrinters.Culture);
|
||||
AddParsedProp("prefix", bs => bs.Prefix, ConfigParsers.String, ConfigPrinters.ToString);
|
||||
|
||||
|
||||
Migrate();
|
||||
}
|
||||
|
||||
private void Migrate()
|
||||
{
|
||||
if (data.Version < 2)
|
||||
{
|
||||
ModifyConfig(c => c.Version = 2);
|
||||
}
|
||||
if (data.Version < 2) ModifyConfig(c => c.Version = 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
#nullable disable
|
||||
using System.Globalization;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using System.Globalization;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Custom setting value parsers for types which don't have them by default
|
||||
/// Custom setting value parsers for types which don't have them by default
|
||||
/// </summary>
|
||||
public static class ConfigParsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Default string parser. Passes input to output and returns true.
|
||||
/// Default string parser. Passes input to output and returns true.
|
||||
/// </summary>
|
||||
public static bool String(string input, out string output)
|
||||
{
|
||||
@@ -42,5 +42,5 @@ public static class ConfigPrinters
|
||||
=> culture.Name;
|
||||
|
||||
public static string Color(Rgba32 color)
|
||||
=> ((uint) ((color.B << 0) | (color.G << 8) | (color.R << 16))).ToString("X6");
|
||||
}
|
||||
=> ((uint)((color.B << 0) | (color.G << 8) | (color.R << 16))).ToString("X6");
|
||||
}
|
||||
@@ -1,37 +1,45 @@
|
||||
using NadekoBot.Common.Configs;
|
||||
using NadekoBot.Common.Yml;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using NadekoBot.Common.Yml;
|
||||
using NadekoBot.Common.Configs;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Base service for all settings services
|
||||
/// Base service for all settings services
|
||||
/// </summary>
|
||||
/// <typeparam name="TSettings">Type of the settings</typeparam>
|
||||
public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
where TSettings : ICloneable<TSettings>, new()
|
||||
{
|
||||
// todo future config arrays are not copied - they're not protected from mutations
|
||||
public TSettings Data
|
||||
=> data.Clone();
|
||||
|
||||
public abstract string Name { get; }
|
||||
protected readonly string _filePath;
|
||||
protected readonly IConfigSeria _serializer;
|
||||
protected readonly IPubSub _pubSub;
|
||||
private readonly TypedKey<TSettings> _changeKey;
|
||||
|
||||
protected TSettings data;
|
||||
|
||||
// todo future config arrays are not copied - they're not protected from mutations
|
||||
public TSettings Data => data.Clone();
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
private readonly Dictionary<string, Func<TSettings, string, bool>> _propSetters = new();
|
||||
private readonly Dictionary<string, Func<object>> _propSelectors = new();
|
||||
private readonly Dictionary<string, Func<object, string>> _propPrinters = new();
|
||||
private readonly Dictionary<string, string> _propComments = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initialized an instance of <see cref="ConfigServiceBase{TSettings}"/>
|
||||
/// Initialized an instance of <see cref="ConfigServiceBase{TSettings}" />
|
||||
/// </summary>
|
||||
/// <param name="filePath">Path to the file where the settings are serialized/deserialized to and from</param>
|
||||
/// <param name="serializer">Serializer which will be used</param>
|
||||
/// <param name="pubSub">Pubsub implementation for signaling when settings are updated</param>
|
||||
/// <param name="changeKey">Key used to signal changed event</param>
|
||||
protected ConfigServiceBase(string filePath, IConfigSeria serializer, IPubSub pubSub,
|
||||
protected ConfigServiceBase(
|
||||
string filePath,
|
||||
IConfigSeria serializer,
|
||||
IPubSub pubSub,
|
||||
TypedKey<TSettings> changeKey)
|
||||
{
|
||||
_filePath = filePath;
|
||||
@@ -55,7 +63,7 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads data from disk. If file doesn't exist, it will be created with default values
|
||||
/// Loads data from disk. If file doesn't exist, it will be created with default values
|
||||
/// </summary>
|
||||
protected void Load()
|
||||
{
|
||||
@@ -70,7 +78,7 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads new data and publishes the new state
|
||||
/// Loads new data and publishes the new state
|
||||
/// </summary>
|
||||
public void Reload()
|
||||
{
|
||||
@@ -79,26 +87,20 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Doesn't do anything by default. This method will be executed after
|
||||
/// <see cref="data"/> is reloaded from <see cref="_filePath"/> or new data is recieved
|
||||
/// from the publish event
|
||||
/// Doesn't do anything by default. This method will be executed after
|
||||
/// <see cref="data" /> is reloaded from <see cref="_filePath" /> or new data is recieved
|
||||
/// from the publish event
|
||||
/// </summary>
|
||||
protected virtual void OnStateUpdate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void Save()
|
||||
{
|
||||
var strData = _serializer.Serialize(data);
|
||||
File.WriteAllText(_filePath, strData);
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, Func<TSettings, string, bool>> _propSetters = new();
|
||||
private readonly Dictionary<string, Func<object>> _propSelectors = new();
|
||||
private readonly Dictionary<string, Func<object, string>> _propPrinters = new();
|
||||
private readonly Dictionary<string, string> _propComments = new();
|
||||
|
||||
|
||||
protected void AddParsedProp<TProp>(
|
||||
string key,
|
||||
Expression<Func<TSettings, TProp>> selector,
|
||||
@@ -108,19 +110,21 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
{
|
||||
checker ??= _ => true;
|
||||
key = key.ToLowerInvariant();
|
||||
_propPrinters[key] = obj => printer((TProp)obj);
|
||||
_propPrinters[key] = obj => printer((TProp)obj);
|
||||
_propSelectors[key] = () => selector.Compile()(data);
|
||||
_propSetters[key] = Magic(selector, parser, checker);
|
||||
_propComments[key] = ((MemberExpression)selector.Body).Member.GetCustomAttribute<CommentAttribute>()?.Comment;
|
||||
}
|
||||
|
||||
private Func<TSettings, string, bool> Magic<TProp>(Expression<Func<TSettings, TProp>> selector,
|
||||
SettingParser<TProp> parser, Func<TProp, bool> checker)
|
||||
private Func<TSettings, string, bool> Magic<TProp>(
|
||||
Expression<Func<TSettings, TProp>> selector,
|
||||
SettingParser<TProp> parser,
|
||||
Func<TProp, bool> checker)
|
||||
=> (target, input) =>
|
||||
{
|
||||
if (!parser(input, out var value))
|
||||
return false;
|
||||
|
||||
|
||||
if (!checker(value))
|
||||
return false;
|
||||
|
||||
@@ -129,22 +133,22 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
var prop = (PropertyInfo)expr.Member;
|
||||
|
||||
var expressions = new List<MemberExpression>();
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
expr = expr.Expression as MemberExpression;
|
||||
if (expr is null)
|
||||
break;
|
||||
|
||||
|
||||
expressions.Add(expr);
|
||||
}
|
||||
|
||||
|
||||
foreach (var memberExpression in expressions.AsEnumerable().Reverse())
|
||||
{
|
||||
var localProp = (PropertyInfo) memberExpression.Member;
|
||||
var localProp = (PropertyInfo)memberExpression.Member;
|
||||
targetObject = localProp.GetValue(targetObject);
|
||||
}
|
||||
|
||||
|
||||
prop!.SetValue(targetObject, value, null);
|
||||
return true;
|
||||
};
|
||||
@@ -155,8 +159,7 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
public string GetSetting(string prop)
|
||||
{
|
||||
prop = prop.ToLowerInvariant();
|
||||
if (!_propSelectors.TryGetValue(prop, out var selector) ||
|
||||
!_propPrinters.TryGetValue(prop, out var printer))
|
||||
if (!_propSelectors.TryGetValue(prop, out var selector) || !_propPrinters.TryGetValue(prop, out var printer))
|
||||
return default;
|
||||
|
||||
return printer(selector());
|
||||
@@ -171,8 +174,7 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
}
|
||||
|
||||
private bool SetProperty(TSettings target, string key, string value)
|
||||
=> _propSetters.TryGetValue(key.ToLowerInvariant(), out var magic)
|
||||
&& magic(target, value);
|
||||
=> _propSetters.TryGetValue(key.ToLowerInvariant(), out var magic) && magic(target, value);
|
||||
|
||||
public bool SetSetting(string prop, string newValue)
|
||||
{
|
||||
@@ -181,8 +183,8 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
{
|
||||
success = SetProperty(bs, prop, newValue);
|
||||
});
|
||||
|
||||
if(success)
|
||||
|
||||
if (success)
|
||||
PublishChange();
|
||||
|
||||
return success;
|
||||
@@ -196,4 +198,4 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
Save();
|
||||
PublishChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,4 @@ namespace NadekoBot.Services;
|
||||
public interface IConfigMigrator
|
||||
{
|
||||
public void EnsureMigrated();
|
||||
}
|
||||
}
|
||||
@@ -2,42 +2,45 @@
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Interface that all services which deal with configs should implement
|
||||
/// Interface that all services which deal with configs should implement
|
||||
/// </summary>
|
||||
public interface IConfigService
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the config
|
||||
/// Name of the config
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Loads new data and publishes the new state
|
||||
/// Loads new data and publishes the new state
|
||||
/// </summary>
|
||||
void Reload();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of props you can set
|
||||
/// Gets the list of props you can set
|
||||
/// </summary>
|
||||
/// <returns>List of props</returns>
|
||||
IReadOnlyList<string> GetSettableProps();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified property
|
||||
/// Gets the value of the specified property
|
||||
/// </summary>
|
||||
/// <param name="prop">Prop name</param>
|
||||
/// <returns>Value of the prop</returns>
|
||||
string GetSetting(string prop);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified property
|
||||
/// Gets the value of the specified property
|
||||
/// </summary>
|
||||
/// <param name="prop">Prop name</param>
|
||||
/// <returns>Value of the prop</returns>
|
||||
string GetComment(string prop);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the specified property
|
||||
/// Sets the value of the specified property
|
||||
/// </summary>
|
||||
/// <param name="prop">Property to set</param>
|
||||
/// <param name="newValue">Value to set the property to</param>
|
||||
/// <returns>Success</returns>
|
||||
bool SetSetting(string prop, string newValue);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate which describes a parser which can convert string input into given data type
|
||||
/// Delegate which describes a parser which can convert string input into given data type
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">Data type to convert string to</typeparam>
|
||||
public delegate bool SettingParser<TData>(string input, out TData output);
|
||||
public delegate bool SettingParser<TData>(string input, out TData output);
|
||||
Reference in New Issue
Block a user