github.com/xuyutom/docker@v1.6.0/pkg/parsers/filters/parse.go (about) 1 package filters 2 3 import ( 4 "encoding/json" 5 "errors" 6 "regexp" 7 "strings" 8 ) 9 10 type Args map[string][]string 11 12 // Parse the argument to the filter flag. Like 13 // 14 // `docker ps -f 'created=today' -f 'image.name=ubuntu*'` 15 // 16 // If prev map is provided, then it is appended to, and returned. By default a new 17 // map is created. 18 func ParseFlag(arg string, prev Args) (Args, error) { 19 var filters Args = prev 20 if prev == nil { 21 filters = Args{} 22 } 23 if len(arg) == 0 { 24 return filters, nil 25 } 26 27 if !strings.Contains(arg, "=") { 28 return filters, ErrorBadFormat 29 } 30 31 f := strings.SplitN(arg, "=", 2) 32 name := strings.ToLower(strings.TrimSpace(f[0])) 33 value := strings.TrimSpace(f[1]) 34 filters[name] = append(filters[name], value) 35 36 return filters, nil 37 } 38 39 var ErrorBadFormat = errors.New("bad format of filter (expected name=value)") 40 41 // packs the Args into an string for easy transport from client to server 42 func ToParam(a Args) (string, error) { 43 // this way we don't URL encode {}, just empty space 44 if len(a) == 0 { 45 return "", nil 46 } 47 48 buf, err := json.Marshal(a) 49 if err != nil { 50 return "", err 51 } 52 return string(buf), nil 53 } 54 55 // unpacks the filter Args 56 func FromParam(p string) (Args, error) { 57 args := Args{} 58 if len(p) == 0 { 59 return args, nil 60 } 61 err := json.Unmarshal([]byte(p), &args) 62 if err != nil { 63 return nil, err 64 } 65 return args, nil 66 } 67 68 func (filters Args) MatchKVList(field string, sources map[string]string) bool { 69 fieldValues := filters[field] 70 71 //do not filter if there is no filter set or cannot determine filter 72 if len(fieldValues) == 0 { 73 return true 74 } 75 76 if sources == nil || len(sources) == 0 { 77 return false 78 } 79 80 outer: 81 for _, name2match := range fieldValues { 82 testKV := strings.SplitN(name2match, "=", 2) 83 84 for k, v := range sources { 85 if len(testKV) == 1 { 86 if k == testKV[0] { 87 continue outer 88 } 89 } else if k == testKV[0] && v == testKV[1] { 90 continue outer 91 } 92 } 93 94 return false 95 } 96 97 return true 98 } 99 100 func (filters Args) Match(field, source string) bool { 101 fieldValues := filters[field] 102 103 //do not filter if there is no filter set or cannot determine filter 104 if len(fieldValues) == 0 { 105 return true 106 } 107 for _, name2match := range fieldValues { 108 match, err := regexp.MatchString(name2match, source) 109 if err != nil { 110 continue 111 } 112 if match { 113 return true 114 } 115 } 116 return false 117 }