using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Threading; using FluentValidation; using MfGames.Gallium; using MfGames.Nitride.Generators; using NodaTime; using Zio; namespace MfGames.Nitride.Temporal; /// /// Sets the instant in the file based on the path of the entity. This /// defaults to a generous regular expression that handles most formats of /// four digit year, a separator, two digit month, a separator, and a two /// digit day of month. /// [WithProperties] public partial class SetInstantFromPath : OperationBase { private readonly TimeService clock; private readonly IValidator validator; public SetInstantFromPath( IValidator validator, TimeService clock) { this.validator = validator; this.clock = clock; this.PathRegex = new Regex( @"(?\d{4})[/-](?\d{2})[/-](?\d{2})"); } /// /// Gets or sets a regular expression that has three named expressions: /// year, month, and day. /// public Regex? PathRegex { get; set; } /// public override IEnumerable Run( IEnumerable input, CancellationToken cancellationToken = default) { this.validator.ValidateAndThrow(this); return input.SelectEntity(this.Set); } private Entity Set( Entity entity, UPath path) { // See if the path matches the given expression. Match match = this.PathRegex!.Match(path.ToString()); if (!match.Success) { return entity; } // Create an Instant from this. Instant instant = this.clock.CreateInstant( Convert.ToInt32(match.Groups["year"].Value), Convert.ToInt32(match.Groups["month"].Value), Convert.ToInt32(match.Groups["day"].Value)); return entity.Set(instant); } }