github.com/campoy/docker@v1.8.0-rc1/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 if err := json.NewDecoder(strings.NewReader(p)).Decode(&args); err != nil { 62 return nil, err 63 } 64 return args, nil 65 } 66 67 func (filters Args) MatchKVList(field string, sources map[string]string) bool { 68 fieldValues := filters[field] 69 70 //do not filter if there is no filter set or cannot determine filter 71 if len(fieldValues) == 0 { 72 return true 73 } 74 75 if sources == nil || len(sources) == 0 { 76 return false 77 } 78 79 outer: 80 for _, name2match := range fieldValues { 81 testKV := strings.SplitN(name2match, "=", 2) 82 83 for k, v := range sources { 84 if len(testKV) == 1 { 85 if k == testKV[0] { 86 continue outer 87 } 88 } else if k == testKV[0] && v == testKV[1] { 89 continue outer 90 } 91 } 92 93 return false 94 } 95 96 return true 97 } 98 99 func (filters Args) Match(field, source string) bool { 100 fieldValues := filters[field] 101 102 //do not filter if there is no filter set or cannot determine filter 103 if len(fieldValues) == 0 { 104 return true 105 } 106 for _, name2match := range fieldValues { 107 match, err := regexp.MatchString(name2match, source) 108 if err != nil { 109 continue 110 } 111 if match { 112 return true 113 } 114 } 115 return false 116 }