tree.go
func (n *node) addChild(child *node, prefix string) *node {
	search := prefix

	// handler leaf node added to the tree is the child.
	// this may be overridden later down the flow
	hn := child

	// Parse next segment
	segTyp, _, segRexpat, segTail, segStartIdx, segEndIdx := patNextSegment(search)

	// Add child depending on next up segment
	switch segTyp {

	case ntStatic:
		// Search prefix is all static (that is, has no params in path)
		// noop

	default:
		// Search prefix contains a param, regexp or wildcard

		if segTyp == ntRegexp {
			rex, err := regexp.Compile(segRexpat)
			if err != nil {
				panic(fmt.Sprintf("chi: invalid regexp pattern '%s' in route param", segRexpat))
			}
			child.prefix = segRexpat
			child.rex = rex
		}

		if segStartIdx == 0 {
			// Route starts with a param
			child.typ = segTyp

			if segTyp == ntCatchAll {
				segStartIdx = -1
			} else {
				segStartIdx = segEndIdx
			}
			if segStartIdx < 0 {
				segStartIdx = len(search)
			}
			child.tail = segTail // for params, we set the tail

			if segStartIdx != len(search) {
				// add static edge for the remaining part, split the end.
				// its not possible to have adjacent param nodes, so its certainly
				// going to be a static node next.

				search = search[segStartIdx:] // advance search position

				nn := &node{
					typ:    ntStatic,
					label:  search[0],
					prefix: search,
				}
				hn = child.addChild(nn, search)
			}

		} else if segStartIdx > 0 {
			// Route has some param

			// starts with a static segment
			child.typ = ntStatic
			child.prefix = search[:segStartIdx]
			child.rex = nil

			// add the param edge node
			search = search[segStartIdx:]

			nn := &node{
				typ:   segTyp,
				label: search[0],
				tail:  segTail,
			}
			hn = child.addChild(nn, search)

		}
	}

	n.children[child.typ] = append(n.children[child.typ], child)
	n.children[child.typ].Sort()
	return hn
}
func (n *node) addChild(child *node, prefix string) *node {
	search := prefix

	// handler leaf node added to the tree is the child.
	// this may be overridden later down the flow
	hn := child

	// Parse next segment
	segTyp, _, segRexpat, segTail, segStartIdx, segEndIdx := patNextSegment(search)

	// Add child depending on next up segment
	switch segTyp {

	case ntStatic:
		// Search prefix is all static (that is, has no params in path)
		// noop

	default:
		// Search prefix contains a param, regexp or wildcard

		if segTyp == ntRegexp {
			rex, err := regexp.Compile(segRexpat)
			if err != nil {
				panic(fmt.Sprintf("chi: invalid regexp pattern '%s' in route param", segRexpat))
			}
			child.prefix = segRexpat
			child.rex = rex
		}

		if segStartIdx == 0 {
			// Route starts with a param
			child.typ = segTyp

			if segTyp == ntCatchAll {
				segStartIdx = -1
			} else {
				segStartIdx = segEndIdx
			}
			if segStartIdx < 0 {
				segStartIdx = len(search)
			}
			child.tail = segTail // for params, we set the tail

			if segStartIdx != len(search) {
				// add static edge for the remaining part, split the end.
				// its not possible to have adjacent param nodes, so its certainly
				// going to be a static node next.

				search = search[segStartIdx:] // advance search position

				nn := &node{
					typ:    ntStatic,
					label:  search[0],
					prefix: search,
				}
				hn = child.addChild(nn, search)
			}

		} else if segStartIdx > 0 {
			// Route has some param

			// starts with a static segment
			child.typ = ntStatic
			child.prefix = search[:segStartIdx]
			child.rex = nil

			// add the param edge node
			search = search[segStartIdx:]

			nn := &node{
				typ:   segTyp,
				label: search[0],
				tail:  segTail,
			}
			hn = child.addChild(nn, search)

		}
	}

	n.children[child.typ] = append(n.children[child.typ], child)
	n.children[child.typ].Sort()
	return hn
}
func ( n * node ) addChild ( child * node , prefix string ) * node { search := prefix // handler leaf node added to the tree is the child. // this may be overridden later down the flow hn := child // Parse next segment segTyp , _ , segRexpat , segTail , segStartIdx , segEndIdx := patNextSegment ( search ) // Add child depending on next up segment switch segTyp { case ntStatic : // Search prefix is all static (that is, has no params in path) // noop default : // Search prefix contains a param, regexp or wildcard if segTyp == ntRegexp { rex , err := regexp . Compile ( segRexpat ) if err != nil { panic ( fmt . Sprintf ( " " , segRexpat ) ) } child . prefix = segRexpat child . rex = rex } if segStartIdx == 0 { // Route starts with a param child . typ = segTyp if segTyp == ntCatchAll { segStartIdx = - 1 } else { segStartIdx = segEndIdx } if segStartIdx < 0 { segStartIdx = len ( search ) } child . tail = segTail // for params, we set the tail if segStartIdx != len ( search ) { // add static edge for the remaining part, split the end. // its not possible to have adjacent param nodes, so its certainly // going to be a static node next. search = search [ segStartIdx : ] // advance search position nn := & node { typ : ntStatic , label : search [ 0 ] , prefix : search , } hn = child . addChild ( nn , search ) } } else if segStartIdx > 0 { // Route has some param // starts with a static segment child . typ = ntStatic child . prefix = search [ : segStartIdx ] child . rex = nil // add the param edge node search = search [ segStartIdx : ] nn := & node { typ : segTyp , label : search [ 0 ] , tail : segTail , } hn = child . addChild ( nn , search ) } } n . children [ child . typ ] = append ( n . children [ child . typ ] , child ) n . children [ child . typ ] . Sort ( ) return hn }
// addChild appends the new `child` node to the tree using the `pattern` as the trie key.
// For a URL router like chi's, we split the static, param, regexp and wildcard segments
// into different nodes. In addition, addChild will recursively call itself until every
// pattern segment is added to the url pattern tree as individual nodes, depending on type.
addChild appends the new child node to the tree using the pattern as the trie key . For a URL router like chi s we split the static param regexp and wildcard segments into different nodes . In addition addChild will recursively call itself until every pattern segment is added to the url pattern tree as individual nodes depending on type .