2020-02-09 02:35:16 +00:00
|
|
|
using System;
|
2017-07-01 16:23:57 +00:00
|
|
|
using System.Collections.Generic;
|
2017-07-20 21:55:42 +00:00
|
|
|
using System.Linq;
|
2017-08-07 20:33:23 +00:00
|
|
|
using System.Threading.Tasks;
|
2017-07-20 21:55:42 +00:00
|
|
|
using System.Xml.Linq;
|
2017-07-01 16:23:57 +00:00
|
|
|
|
2018-03-10 08:05:56 +00:00
|
|
|
namespace Jackett.Common.Utils
|
2017-07-01 16:23:57 +00:00
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
// Prefer built in NullReferenceException || ArgumentNullException || NoNullAllowedException
|
2017-07-01 16:23:57 +00:00
|
|
|
public class NonNullException : Exception
|
|
|
|
{
|
|
|
|
public NonNullException() : base("Parameter cannot be null")
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class NonNull<T> where T : class
|
|
|
|
{
|
|
|
|
public NonNull(T val)
|
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
// doesn't throw Exception?
|
2017-07-01 16:23:57 +00:00
|
|
|
if (val == null)
|
|
|
|
new NonNullException();
|
|
|
|
|
|
|
|
Value = val;
|
|
|
|
}
|
|
|
|
|
2020-02-25 16:08:03 +00:00
|
|
|
public static implicit operator T(NonNull<T> n) => n.Value;
|
2017-07-01 16:23:57 +00:00
|
|
|
|
2020-02-10 22:16:19 +00:00
|
|
|
private readonly T Value;
|
2017-07-01 16:23:57 +00:00
|
|
|
}
|
|
|
|
|
2017-08-08 15:02:16 +00:00
|
|
|
public static class GenericConversionExtensions
|
2017-07-01 16:23:57 +00:00
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
public static IEnumerable<T> ToEnumerable<T>(this T obj) => new T[] { obj };
|
2017-08-07 20:33:23 +00:00
|
|
|
|
2020-02-25 16:08:03 +00:00
|
|
|
public static NonNull<T> ToNonNull<T>(this T obj) where T : class => new NonNull<T>(obj);
|
2017-07-01 16:23:57 +00:00
|
|
|
}
|
|
|
|
|
2017-08-08 15:02:16 +00:00
|
|
|
public static class EnumerableExtension
|
2017-07-01 16:23:57 +00:00
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
public static string AsString(this IEnumerable<char> chars) => string.Concat(chars);
|
2017-08-08 15:02:16 +00:00
|
|
|
|
2020-02-25 16:08:03 +00:00
|
|
|
// Should be collection.Any()
|
|
|
|
// Remove in favor of existing built in function?
|
|
|
|
public static bool IsEmpty<T>(this IEnumerable<T> collection) => collection.Count() > 0;
|
2017-08-08 15:02:16 +00:00
|
|
|
|
2020-02-25 16:08:03 +00:00
|
|
|
public static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> list) => list.SelectMany(x => x);
|
2017-07-01 16:23:57 +00:00
|
|
|
}
|
|
|
|
|
2020-02-25 16:08:03 +00:00
|
|
|
// TODO This class should be removed in favor of explicit conversions
|
2017-07-01 16:23:57 +00:00
|
|
|
public static class StringExtension
|
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
// string.IsNullOrWhitespace already checks string.IsNullOrEmpty should remove this?
|
|
|
|
public static bool IsNullOrEmptyOrWhitespace(this string str) => string.IsNullOrEmpty(str) || string.IsNullOrWhiteSpace(str);
|
2017-07-20 21:55:42 +00:00
|
|
|
|
2020-02-25 16:08:03 +00:00
|
|
|
public static DateTime ToDateTime(this string str) => DateTime.Parse(str);
|
2017-07-20 21:55:42 +00:00
|
|
|
|
2020-02-25 16:08:03 +00:00
|
|
|
public static Uri ToUri(this string str) => new Uri(str);
|
2017-07-01 16:23:57 +00:00
|
|
|
}
|
2017-07-10 20:58:44 +00:00
|
|
|
|
|
|
|
public static class CollectionExtension
|
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
// IEnumerable class above already does this. All ICollection are IEnumerable, so favor IEnumerable?
|
|
|
|
public static bool IsEmpty<T>(this ICollection<T> obj) => obj.Count == 0;
|
2017-07-10 20:58:44 +00:00
|
|
|
|
2020-02-25 16:08:03 +00:00
|
|
|
|
|
|
|
public static bool IsEmptyOrNull<T>(this ICollection<T> obj) => obj?.IsEmpty() == true;
|
2017-07-10 20:58:44 +00:00
|
|
|
}
|
2017-07-20 21:55:42 +00:00
|
|
|
|
|
|
|
public static class XElementExtension
|
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
public static XElement First(this XElement element, string name) => element.Descendants(name).First();
|
2017-07-20 21:55:42 +00:00
|
|
|
|
2020-02-25 16:08:03 +00:00
|
|
|
public static string FirstValue(this XElement element, string name) => element.First(name).Value;
|
2017-07-20 21:55:42 +00:00
|
|
|
}
|
2017-08-06 18:44:22 +00:00
|
|
|
|
2017-08-08 15:02:16 +00:00
|
|
|
public static class KeyValuePairsExtension
|
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
public static IDictionary<Key, Value> ToDictionary<Key, Value>(this IEnumerable<KeyValuePair<Key, Value>> pairs) => pairs.ToDictionary(x => x.Key, x => x.Value);
|
2017-08-08 15:02:16 +00:00
|
|
|
}
|
|
|
|
|
2017-08-06 18:44:22 +00:00
|
|
|
public static class ParseExtension
|
|
|
|
{
|
|
|
|
public static T? TryParse<T>(this string value) where T : struct
|
|
|
|
{
|
|
|
|
var type = typeof(T);
|
|
|
|
var parseMethods = type.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).Where(m => m.Name == "Parse");
|
|
|
|
var parseMethod = parseMethods.Where(m =>
|
|
|
|
{
|
|
|
|
var parameters = m.GetParameters();
|
|
|
|
var hasOnlyOneParameter = parameters.Count() == 1;
|
|
|
|
var firstParameterIsString = parameters.First().ParameterType == typeof(string);
|
|
|
|
|
|
|
|
return hasOnlyOneParameter && firstParameterIsString;
|
|
|
|
}).First();
|
|
|
|
if (parseMethod == null)
|
|
|
|
return null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var val = parseMethod.Invoke(null, new object[] { value });
|
|
|
|
return (T)val;
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-08-07 20:33:23 +00:00
|
|
|
|
|
|
|
public static class TaskExtensions
|
|
|
|
{
|
|
|
|
public static Task<IEnumerable<TResult>> Until<TResult>(this IEnumerable<Task<TResult>> tasks, TimeSpan timeout)
|
|
|
|
{
|
|
|
|
var timeoutTask = Task.Delay(timeout);
|
|
|
|
var aggregateTask = Task.WhenAll(tasks);
|
|
|
|
var anyTask = Task.WhenAny(timeoutTask, aggregateTask);
|
|
|
|
var continuation = anyTask.ContinueWith((_) =>
|
|
|
|
{
|
|
|
|
var completedTasks = tasks.Where(t => t.Status == TaskStatus.RanToCompletion);
|
|
|
|
var results = completedTasks.Select(t => t.Result);
|
|
|
|
return results;
|
|
|
|
});
|
|
|
|
|
|
|
|
return continuation;
|
|
|
|
}
|
|
|
|
}
|
2017-07-01 16:23:57 +00:00
|
|
|
}
|