using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; // A spot for immutable helpers namespace imm { public record class Versioned where T : Versioned { public uint Version { get; protected set; } = 0; public string Reason { get; protected set; } = ""; public T Process( Func fn, string reason = "" ) { var newT = fn( ( T )this ); return newT with { Version = newT.Version + 1, Reason = reason, }; } } public record class Recorded : Versioned where T : Recorded { public T? Old { get; protected set; } public string Expression { get; protected set; } = ""; public string MemberName { get; protected set; } = ""; public string FilePath { get; protected set; } = ""; public int LineNumber { get; protected set; } = -1; public T Record( string reason = "", [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0 ) { var orig = ( T )this; var newT = base.Process( ( old ) => old with { Old = orig, MemberName = memberName, FilePath = filePath, LineNumber = lineNumber, }, reason ); return newT; } public T Process( Func fn, string reason = "", [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0, [CallerArgumentExpression("fn")] string expression = default ) { var orig = ( T )this; return ( T )this with { //Do the Versioned code here Version = orig.Version + 1, //Recorded Old = orig, Expression = expression, MemberName = memberName, FilePath = filePath, LineNumber = lineNumber, }; } } public record class Timed : Recorded where T : Timed { public readonly DateTime CreatedAt = DateTime.Now; public DateTime TouchedAt { get; set; } = DateTime.Now; public T Process( Func fn, string reason = "", [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0, [CallerArgumentExpression("fn")] string expression = default ) { var orig = ( T )this; return ( T )this with { //Versioned Version = orig.Version + 1, //Recorded Old = orig, Expression = expression, MemberName = memberName, FilePath = filePath, LineNumber = lineNumber, TouchedAt = DateTime.Now, }; } } public static class Util { } }