github.com/sdqri/sequined@v0.0.0-20240421190656-fc6bf956f4d8/internal/hyperrenderer/hyper_renderer.go (about)

     1  package hyperrenderer
     2  
     3  import (
     4  	"io"
     5  )
     6  
     7  type HyperRenderer interface {
     8  	GetID() string
     9  	GetPath() string
    10  	Render(wr io.Writer) error
    11  	GetLinks() []HyperRenderer
    12  }
    13  
    14  func GetPaths(node HyperRenderer) []string {
    15  	paths := make([]string, 0)
    16  	for _, page := range node.GetLinks() {
    17  		paths = append(paths, page.GetPath())
    18  	}
    19  	return paths
    20  }
    21  
    22  type VisitedMap map[HyperRenderer]struct{}
    23  
    24  // boolean value indicates whether the traversal should be terminated or not.
    25  type VisitFunc func(HyperRenderer) bool
    26  
    27  func Traverse(root HyperRenderer, f VisitFunc) VisitedMap {
    28  	visited := make(VisitedMap)
    29  	traverse(root, visited, f)
    30  	return visited
    31  }
    32  
    33  func traverse(root HyperRenderer, visited VisitedMap, f VisitFunc) {
    34  	if _, ok := visited[root]; ok {
    35  		return
    36  	}
    37  
    38  	visited[root] = struct{}{}
    39  	if shouldBreak := f(root); shouldBreak {
    40  		return
    41  	}
    42  
    43  	links := root.GetLinks()
    44  	for _, link := range links {
    45  		traverse(link, visited, f)
    46  	}
    47  }
    48  
    49  func NoOpVisit(hr HyperRenderer) bool {
    50  	return false
    51  }
    52  
    53  func CreatePathMap(root HyperRenderer) map[string]HyperRenderer {
    54  	nodeMap := make(map[string]HyperRenderer)
    55  	Traverse(root, func(hr HyperRenderer) bool {
    56  		nodeMap[hr.GetPath()] = hr
    57  		return false
    58  	})
    59  	return nodeMap
    60  }
    61  
    62  func FindHyperRendererByPath(root HyperRenderer, path string) HyperRenderer {
    63  	found := root
    64  	Traverse(root, func(hr HyperRenderer) bool {
    65  		if path == hr.GetPath() {
    66  			found = hr
    67  			return true
    68  		}
    69  		return false
    70  	})
    71  	return found
    72  }
    73  
    74  func FindHyperRendererByID(root HyperRenderer, targetID string) HyperRenderer {
    75  	found := root
    76  	Traverse(root, func(hr HyperRenderer) bool {
    77  		if hr.GetID() == targetID {
    78  			found = hr
    79  			return true
    80  		}
    81  		return false
    82  	})
    83  
    84  	return found
    85  }