// Copyright 2019 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // See the License for the specific language governing permissions and // limitations under the License. package texttree const ( // TreeBody indicates the current operator sub-tree is not finished, still // has child operators to be attached on. TreeBody = '│' // TreeMiddleNode indicates this operator is not the last child of the // current sub-tree rooted by its parent. TreeMiddleNode = '├' // TreeLastNode indicates this operator is the last child of the current // sub-tree rooted by its parent. TreeLastNode = '└' // TreeGap is used to represent the gap between the branches of the tree. TreeGap = ' ' // TreeNodeIdentifier is used to replace the treeGap once we need to attach // a node to a sub-tree. TreeNodeIdentifier = '─' ) // Indent4Child appends more blank to the `indent` string func Indent4Child(indent string, isLastChild bool) string { if !isLastChild { return string(append([]rune(indent), TreeBody, TreeGap)) } // If the current node is the last node of the current operator tree, we // need to end this sub-tree by changing the closest treeBody to a treeGap. indentBytes := []rune(indent) for i := len(indentBytes) - 1; i >= 0; i-- { if indentBytes[i] == TreeBody { indentBytes[i] = TreeGap break } } return string(append(indentBytes, TreeBody, TreeGap)) } // PrettyIdentifier returns a pretty identifier which contains indent and tree node hierarchy indicator func PrettyIdentifier(id, indent string, isLastChild bool) string { if len(indent) == 0 { return id } indentBytes := []rune(indent) for i := len(indentBytes) - 1; i >= 0; i-- { if indentBytes[i] != TreeBody { continue } // Here we attach a new node to the current sub-tree by changing // the closest treeBody to a: // 1. treeLastNode, if this operator is the last child. // 2. treeMiddleNode, if this operator is not the last child.. if isLastChild { indentBytes[i] = TreeLastNode } else { indentBytes[i] = TreeMiddleNode } break } // Replace the treeGap between the treeBody and the node to a // treeNodeIdentifier. indentBytes[len(indentBytes)-1] = TreeNodeIdentifier return string(indentBytes) + id }