sharplib/imm/Imm.cs
2023-12-02 14:30:52 -08:00

126 lines
2.7 KiB
C#

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<T>
where T : Versioned<T>
{
public uint Version { get; protected set; } = 0;
public string Reason { get; protected set; } = "";
public T Process( Func<T, T> fn, string reason = "" )
{
var newT = fn( ( T )this );
return newT with
{
Version = newT.Version + 1,
Reason = reason,
};
}
}
public record class Recorded<T> : Versioned<T>
where T : Recorded<T>
{
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<T, T> 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<T> : Recorded<T>
where T : Timed<T>
{
public readonly DateTime CreatedAt = DateTime.Now;
public DateTime TouchedAt { get; set; } = DateTime.Now;
public T Process( Func<T, T> 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
{
}
}