// Kyoo - A portable and vast media library solution. // Copyright (c) Kyoo. // // See AUTHORS.md and LICENSE file in the project root for full license information. // // Kyoo is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // Kyoo is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Kyoo. If not, see . using System; using System.Linq.Expressions; using Kyoo.Utils; namespace Kyoo.Abstractions.Controllers { /// /// Information about how a query should be sorted. What factor should decide the sort and in which order. /// /// For witch type this sort applies public readonly struct Sort { /// /// The sort key. This member will be used to sort the results. /// public Expression> Key { get; } /// /// If this is set to true, items will be sorted in descend order else, they will be sorted in ascendant order. /// public bool Descendant { get; } /// /// Create a new instance. /// /// The sort key given. It is assigned to . /// Should this be in descendant order? The default is false. /// If the given key is not a member. public Sort(Expression> key, bool descendant = false) { Key = key; Descendant = descendant; if (!Utility.IsPropertyExpression(Key)) throw new ArgumentException("The given sort key is not valid."); } /// /// Create a new instance from a key's name (case insensitive). /// /// A key name with an optional order specifier. Format: "key:asc", "key:desc" or "key". /// An invalid key or sort specifier as been given. public Sort(string sortBy) { if (string.IsNullOrEmpty(sortBy)) { Key = null; Descendant = false; return; } string key = sortBy.Contains(':') ? sortBy[..sortBy.IndexOf(':')] : sortBy; string order = sortBy.Contains(':') ? sortBy[(sortBy.IndexOf(':') + 1)..] : null; ParameterExpression param = Expression.Parameter(typeof(T), "x"); MemberExpression property = Expression.Property(param, key); Key = property.Type.IsValueType ? Expression.Lambda>(Expression.Convert(property, typeof(object)), param) : Expression.Lambda>(property, param); Descendant = order switch { "desc" => true, "asc" => false, null => false, _ => throw new ArgumentException($"The sort order, if set, should be :asc or :desc but it was :{order}.") }; } } }