using System; using System.Collections.Generic; using FluentValidation; using MfGames.Gallium; using Zio; namespace MfGames.Nitride.IO.Paths; /// /// Moves various files to indexes of a direction with the base filename. /// [WithProperties] public partial class MoveToIndexPath : OperationBase { private readonly ReplacePath replacePath; private readonly IValidator validator; public MoveToIndexPath( IValidator validator, ReplacePath replacePath) { this.validator = validator; this.replacePath = replacePath; this.CanMoveCallback = DefaultCanMoveCallback; } /// /// Gets or sets the callback to determine if the file should be moved. /// This will not be called if the file is already an index. /// public Func? CanMoveCallback { get; set; } /// /// Default implement of the operation moves .html, .htm, .md, and /// .markdown files into their indexes. /// /// /// True if the file should move, otherwise false. public static bool DefaultCanMoveCallback(UPath path) { return path.GetExtensionWithDot() switch { ".htm" => true, ".html" => true, ".md" => true, ".markdown" => true, _ => false, }; } public override IEnumerable Run(IEnumerable input) { this.validator.ValidateAndThrow(this); return this.replacePath.WithReplacement(this.RunReplacement) .Run(input); } private UPath RunReplacement( Entity _, UPath path) { // See if we are already an index. If that is true, then we don't // have to move any further. string? nameWithoutExtension = path.GetNameWithoutExtension(); if (nameWithoutExtension is null or "index") { return path; } // See if the path should be moved. If it can't, then just stop // processing. if (!this.CanMoveCallback!.Invoke(path)) { return path; } // Move the file to an index. UPath parent = path.GetDirectory(); string? extension = path.GetExtensionWithDot(); string index = "index" + extension; return parent / nameWithoutExtension / index; } }