Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moved Linq extensions to Files.Shared #8761

Merged
merged 2 commits into from
Mar 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/Files.Shared/Extensions/DateExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Runtime.InteropServices.ComTypes;

namespace Files.Shared.Extensions
{
public static class DateExtensions
{
public static DateTime ToDateTime(this FILETIME time)
{
uint low = (uint)time.dwLowDateTime;
ulong high = (ulong)time.dwHighDateTime;
long fileTime = (long)((high << 32) + low);
try
{
return DateTime.FromFileTimeUtc(fileTime);
}
catch
{
return DateTime.FromFileTimeUtc(0xFFFFFFFF);
}
}
}
}
133 changes: 78 additions & 55 deletions src/Files.Shared/Extensions/LinqExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,52 @@
using System.Linq;
using System.Threading.Tasks;

#nullable enable

namespace Files.Shared.Extensions
{
public static class LinqExtensions
{
public static IEnumerable<TSource> ExceptBy<TSource, TKey>(
this IEnumerable<TSource> source,
IEnumerable<TSource> other,
Func<TSource, TKey> keySelector)
/// <summary>
/// Determines whether <paramref name="enumerable"/> is empty or not.
/// <br/><br/>
/// Remarks:
/// <br/>
/// This function is faster than enumerable.Count == 0 since it'll only iterate one element instead of all elements.
/// <br/>
/// This function is null-safe.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="enumerable"></param>
/// <returns></returns>
public static bool IsEmpty<T>(this IEnumerable<T> enumerable) => enumerable is null || !enumerable.Any();

public static TOut? Get<TOut, TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TOut? defaultValue = default)
{
if (dictionary is null || key is null)
{
return default;
}
if (!dictionary.ContainsKey(key))
{
if (defaultValue is TValue value)
dictionary.Add(key, value);
else
dictionary.Remove(key);
return defaultValue;
}
if (dictionary[key] is TOut o)
{
return o;
}
return default;
}

public static async Task<IEnumerable<T>> WhereAsync<T>(this IEnumerable<T> source, Func<T, Task<bool>> predicate)
{
var results = await Task.WhenAll(source.Select(async x => (x, await predicate(x))));
return results.Where(x => x.Item2).Select(x => x.x);
}

public static IEnumerable<TSource> ExceptBy<TSource, TKey>(this IEnumerable<TSource> source, IEnumerable<TSource> other, Func<TSource, TKey> keySelector)
{
var set = new HashSet<TKey>(other.Select(keySelector));
foreach (var item in source)
Expand All @@ -25,74 +61,61 @@ public static IEnumerable<TSource> ExceptBy<TSource, TKey>(
}

public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> items, Func<T, TKey> property)
{
return items.GroupBy(property).Select(x => x.First());
}
=> items.GroupBy(property).Select(x => x.First());

public static async Task<IEnumerable<T>> WhereAsync<T>(this IEnumerable<T> source, Func<T, Task<bool>> predicate)
{
var results = await Task.WhenAll(source.Select(async x => (x, await predicate(x))));
return results.Where(x => x.Item2).Select(x => x.Item1);
}
public static IEnumerable<T> IntersectBy<T, TKey>(this IEnumerable<T> items, IEnumerable<T> others, Func<T, TKey> keySelector)
=> items.Join(others.Select(keySelector), keySelector, id => id, (o, id) => o);

public static IEnumerable<TSource> IntersectBy<TSource, TKey>(
this IEnumerable<TSource> source,
IEnumerable<TSource> other,
Func<TSource, TKey> keySelector)
/// <summary>
/// Enumerates through <see cref="IEnumerable{T}"/> of elements and executes <paramref name="action"/>
/// </summary>
/// <typeparam name="T">Element of <paramref name="collection"/></typeparam>
/// <param name="collection">The collection to enumerate through</param>
/// <param name="action">The action to take every element</param>
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
return source.Join(other.Select(keySelector), keySelector, id => id, (o, id) => o);
foreach (T value in collection)
action(value);
}

public static TOut? Get<TOut, TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TOut? defaultValue = default)
public static IList<T> AddSorted<T>(this IList<T> list, T item) where T : IComparable<T>
{
// If dictionary is null or key is invalid, return default.
if (dictionary == null || key == null)
if (!list.Any() || list.Last().CompareTo(item) <= 0)
{
return defaultValue;
list.Add(item);
return list;
}

// If setting doesn't exist, create it.
if (!dictionary.ContainsKey(key))
if (list[0].CompareTo(item) >= 0)
{
dictionary[key] = (TValue)(object)defaultValue;
list.Insert(0, item);
return list;
}

return (TOut)(object)dictionary[key];
}

public static DateTime ToDateTime(this System.Runtime.InteropServices.ComTypes.FILETIME time)
{
ulong high = (ulong)time.dwHighDateTime;
uint low = (uint)time.dwLowDateTime;
long fileTime = (long)((high << 32) + low);
try
{
return DateTime.FromFileTimeUtc(fileTime);
}
catch
int index = list.ToList().BinarySearch(item);
if (index < 0)
{
return DateTime.FromFileTimeUtc(0xFFFFFFFF);
index = ~index;
}
list.Insert(index, item);
return list;
}

public static async Task WithTimeoutAsync(this Task task,
TimeSpan timeout)
/// <summary>
/// Removes all elements from the specified index to the end of the list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="index"></param>
public static List<T> RemoveFrom<T>(this List<T> list, int index)
{
if (task == await Task.WhenAny(task, Task.Delay(timeout)))
if (!list.Any())
{
await task;
return list;
}
}

public static async Task<T?> WithTimeoutAsync<T>(this Task<T> task,
TimeSpan timeout, T? defaultValue = default)
{
if (task == await Task.WhenAny(task, Task.Delay(timeout)))
if (index <= 0)
{
return await task;
return new List<T>(0);
}

return defaultValue;
return list.Take(index - 1).ToList();
}
}
}
25 changes: 25 additions & 0 deletions src/Files.Shared/Extensions/TaskExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Threading.Tasks;

namespace Files.Shared.Extensions
{
public static class TaskExtensions
{
public static async Task WithTimeoutAsync(this Task task, TimeSpan timeout)
{
if (task == await Task.WhenAny(task, Task.Delay(timeout)))
{
await task;
}
}

public static async Task<T?> WithTimeoutAsync<T>(this Task<T> task, TimeSpan timeout, T? defaultValue = default)
{
if (task == await Task.WhenAny(task, Task.Delay(timeout)))
{
return await task;
}
return defaultValue;
}
}
}
7 changes: 4 additions & 3 deletions src/Files.Uwp/BaseLayout.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
using Files.Shared.Enums;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.Backend.Services.Settings;
using Files.EventArguments;
using Files.Extensions;
using Files.Filesystem;
using Files.Filesystem.StorageItems;
using Files.Helpers;
using Files.Helpers.ContextFlyouts;
using Files.Interacts;
using Files.Backend.Services.Settings;
using Files.Shared.Enums;
using Files.Shared.Extensions;
using Files.UserControls;
using Files.ViewModels;
using Files.ViewModels.Previews;
using Files.Views;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.Toolkit.Uwp;
using Microsoft.Toolkit.Uwp.UI;
using System;
Expand Down
4 changes: 2 additions & 2 deletions src/Files.Uwp/Controllers/TerminalController.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Files.DataModels;
using Files.Shared.Enums;
using Files.Extensions;
using Files.Filesystem;
using Files.Helpers;
using Files.Shared.Enums;
using Files.Shared.Extensions;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
Expand Down
82 changes: 0 additions & 82 deletions src/Files.Uwp/Extensions/LinqExtensions.cs

This file was deleted.

1 change: 0 additions & 1 deletion src/Files.Uwp/Files.Uwp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@
<DependentUpon>ImagePreview.xaml</DependentUpon>
</Compile>
<Compile Include="Extensions\EnumerableExtensions.cs" />
<Compile Include="Extensions\LinqExtensions.cs" />
<Compile Include="Filesystem\Cloud\CloudDriveSyncStatusUI.cs" />
<Compile Include="Filesystem\Cloud\Providers\AppleCloudProvider.cs" />
<Compile Include="Filesystem\Cloud\Providers\BoxCloudProvider.cs" />
Expand Down
9 changes: 4 additions & 5 deletions src/Files.Uwp/Filesystem/LibraryManager.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using Files.Shared;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.Backend.Services.Settings;
using Files.DataModels.NavigationControlItems;
using Files.Extensions;
using Files.Helpers;
using Files.Backend.Services.Settings;
using Files.Shared;
using Files.Shared.Extensions;
using Files.UserControls;
using Files.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.Toolkit.Uwp;
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
Expand Down
2 changes: 1 addition & 1 deletion src/Files.Uwp/Filesystem/StorageItems/BaseStorageItem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Files.Extensions;
using Files.Shared.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Files.Extensions;
using Files.Shared.Extensions;
using System;
using System.Collections;
using System.Collections.Generic;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Files.Backend.Services.Settings;
using Files.Extensions;
using CommunityToolkit.Mvvm.DependencyInjection;
using Files.Backend.Services.Settings;
using Files.Shared.EventArguments;
using Files.Shared.Extensions;
using Files.Uwp.Serialization;
using Files.Uwp.Serialization.Implementation;
using CommunityToolkit.Mvvm.DependencyInjection;
using System.Collections.Generic;
using System.IO;
using Windows.Storage;
Expand Down
Loading