1package glob
2
3import "strings"
4
5// The character which is treated like a glob
6const GLOB = "*"
7
8// Glob will test a string pattern, potentially containing globs, against a
9// subject string. The result is a simple true/false, determining whether or
10// not the glob pattern matched the subject text.
11func Glob(pattern, subj string) bool {
12	// Empty pattern can only match empty subject
13	if pattern == "" {
14		return subj == pattern
15	}
16
17	// If the pattern _is_ a glob, it matches everything
18	if pattern == GLOB {
19		return true
20	}
21
22	parts := strings.Split(pattern, GLOB)
23
24	if len(parts) == 1 {
25		// No globs in pattern, so test for equality
26		return subj == pattern
27	}
28
29	leadingGlob := strings.HasPrefix(pattern, GLOB)
30	trailingGlob := strings.HasSuffix(pattern, GLOB)
31	end := len(parts) - 1
32
33	// Go over the leading parts and ensure they match.
34	for i := 0; i < end; i++ {
35		idx := strings.Index(subj, parts[i])
36
37		switch i {
38		case 0:
39			// Check the first section. Requires special handling.
40			if !leadingGlob && idx != 0 {
41				return false
42			}
43		default:
44			// Check that the middle parts match.
45			if idx < 0 {
46				return false
47			}
48		}
49
50		// Trim evaluated text from subj as we loop over the pattern.
51		subj = subj[idx+len(parts[i]):]
52	}
53
54	// Reached the last section. Requires special handling.
55	return trailingGlob || strings.HasSuffix(subj, parts[end])
56}
57