namespace InnovEnergy.SysTools.Remote; public readonly struct RemotePath { public SysPath Path { get; } public SshHost Host { get; } public RemotePath Parent => Path.Parent.At(Host); public String Tail => Path.Tail; public String Head => Path.Head; public String Extension => Path.Extension; public RemotePath(SshHost host, SysPath path) { Host = host; Path = path; } public RemotePath At(SshHost host) { return new RemotePath(host, Path); } public RemotePath ToRelative() => Path.ToRelative().At(Host); public RemotePath ToAbsolute() => Path.ToAbsolute().At(Host); public RemotePath ToEnvRef() => Path.ToEnvRef().At(Host); public RemotePath RelativeTo(RemotePath referencePath) { if (!Host.Equals(referencePath.Host)) throw new ArgumentException(nameof(referencePath)); return Path.RelativeTo(referencePath.Path).At(Host); } public RemotePath RelativeTo(SysPath referencePath) { return Path.RelativeTo(referencePath).At(Host); } public Boolean IsSubPathOf(RemotePath referencePath) { var (host, path) = referencePath; return Host.Equals(host) && Path.IsSubPathOf(path); } public RemotePath Append(SysPath right) { return Path.Append(right).At(Host); } #region equality public Boolean Equals(RemotePath other) { var (host, path) = other; return Path.Equals(path) && Host.Equals(host); } public override Boolean Equals(Object obj) { return obj is RemotePath other && Equals(other); } public override Int32 GetHashCode() { unchecked { return (Path.GetHashCode() * 397) ^ Host.GetHashCode(); } } #endregion equality #region operators public static RemotePath operator /(RemotePath left, SysPath right) => left.Append(right); public static RemotePath operator /(RemotePath left, String right) => left.Append(right); public static Boolean operator ==(RemotePath left, RemotePath right) => left.Equals(right); public static Boolean operator !=(RemotePath left, RemotePath right) => left.Equals(right); public static implicit operator String(RemotePath remotePath) => remotePath.ToString(); #endregion public void Deconstruct(out SshHost host, out SysPath path) { path = Path; host = Host; } public override String ToString() => $"{Host}:{Path}"; }