using System; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Compat; namespace LibGit2Sharp { /// /// Holds the meta data of a . /// public class TreeEntryDefinition : IEquatable { private Lazy target; private static readonly LambdaEqualityHelper equalityHelper = new LambdaEqualityHelper(x => x.Mode, x => x.TargetType, x => x.TargetId); internal static readonly Enum[] BlobModes = new Enum[] { Mode.NonExecutableFile, Mode.ExecutableFile, Mode.NonExecutableGroupWritableFile, Mode.SymbolicLink }; /// /// Needed for mocking purposes. /// protected TreeEntryDefinition() { } /// /// Gets file mode. /// public virtual Mode Mode { get; private set; } /// /// Gets the of the target being pointed at. /// public virtual TreeEntryTargetType TargetType { get; private set; } /// /// Gets the of the target being pointed at. /// public virtual ObjectId TargetId { get; private set; } internal virtual GitObject Target { get { return target.Value; } } internal static TreeEntryDefinition From(TreeEntry treeEntry) { return new TreeEntryDefinition { Mode = treeEntry.Mode, TargetType = treeEntry.TargetType, TargetId = treeEntry.TargetId, target = new Lazy(() => treeEntry.Target) }; } internal static TreeEntryDefinition From(Blob blob, Mode mode) { return new TreeEntryDefinition { Mode = mode, TargetType = TreeEntryTargetType.Blob, TargetId = blob.Id, target = new Lazy(() => blob) }; } internal static TreeEntryDefinition TransientBlobFrom(string filePath, Mode mode) { Ensure.ArgumentConformsTo(mode, m => m.HasAny(BlobModes), "mode"); return new TransientBlobTreeEntryDefinition { Builder = odb => odb.CreateBlob(filePath), Mode = mode, }; } internal static TreeEntryDefinition From(ObjectId objectId) { return new TreeEntryDefinition { Mode = Mode.GitLink, TargetType = TreeEntryTargetType.GitLink, TargetId = objectId, target = new Lazy(() => { throw new InvalidOperationException("Shouldn't be necessary."); }), }; } internal static TreeEntryDefinition From(Tree tree) { return new TreeEntryDefinition { Mode = Mode.Directory, TargetType = TreeEntryTargetType.Tree, TargetId = tree.Id, target = new Lazy(() => tree) }; } /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as TreeEntryDefinition); } /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// True if the specified is equal to the current ; otherwise, false. public bool Equals(TreeEntryDefinition other) { return equalityHelper.Equals(this, other); } /// /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() { return equalityHelper.GetHashCode(this); } /// /// Tests if two are equal. /// /// First to compare. /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(TreeEntryDefinition left, TreeEntryDefinition right) { return Equals(left, right); } /// /// Tests if two are different. /// /// First to compare. /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(TreeEntryDefinition left, TreeEntryDefinition right) { return !Equals(left, right); } } internal abstract class TransientTreeEntryDefinition : TreeEntryDefinition { public override ObjectId TargetId { get { return ObjectId.Zero; } } internal override GitObject Target { get { return null; } } } internal class TransientTreeTreeEntryDefinition : TransientTreeEntryDefinition { public override Mode Mode { get { return Mode.Directory; } } public override TreeEntryTargetType TargetType { get { return TreeEntryTargetType.Tree; } } } internal class TransientBlobTreeEntryDefinition : TransientTreeEntryDefinition { public override TreeEntryTargetType TargetType { get { return TreeEntryTargetType.Blob; } } public Func Builder { get; set; } } }