public static string FormatStructure(this ILinks <ulong> links, ulong linkIndex, Func <Link <ulong>, bool> isElement, Action <StringBuilder, Link <ulong> > appendElement, bool renderIndex = false, bool renderDebug = false) { var sb = new StringBuilder(); var visited = new HashSet <ulong>(); links.AppendStructure(sb, visited, linkIndex, isElement, appendElement, renderIndex, renderDebug); return(sb.ToString()); }
public static void AppendStructure(this ILinks <ulong> links, StringBuilder sb, HashSet <ulong> visited, ulong linkIndex, Func <Link <ulong>, bool> isElement, Action <StringBuilder, Link <ulong> > appendElement, bool renderIndex = false, bool renderDebug = false) { if (sb == null) { throw new ArgumentNullException(nameof(sb)); } if (linkIndex == Constants.Null || linkIndex == Constants.Any || linkIndex == Constants.Itself) { return; } if (links.Exists(linkIndex)) { if (visited.Add(linkIndex)) { sb.Append('('); var link = new Link <ulong>(links.GetLink(linkIndex)); if (renderIndex) { sb.Append(link.Index); sb.Append(':'); } if (link.Source == link.Index) { sb.Append(link.Index); } else { var source = new Link <ulong>(links.GetLink(link.Source)); if (isElement(source)) { appendElement(sb, source); } else { links.AppendStructure(sb, visited, source.Index, isElement, appendElement, renderIndex); } } sb.Append(' '); if (link.Target == link.Index) { sb.Append(link.Index); } else { var target = new Link <ulong>(links.GetLink(link.Target)); if (isElement(target)) { appendElement(sb, target); } else { links.AppendStructure(sb, visited, target.Index, isElement, appendElement, renderIndex); } } sb.Append(')'); } else { if (renderDebug) { sb.Append('*'); } sb.Append(linkIndex); } } else { if (renderDebug) { sb.Append('~'); } sb.Append(linkIndex); } }