Added Filter, FilterRegexp and FilterPrefix
diff --git a/properties.go b/properties.go
index a5aaa21..e9386fb 100644
--- a/properties.go
+++ b/properties.go
@@ -12,6 +12,7 @@
"io"
"log"
"os"
+ "regexp"
"strconv"
"strings"
"time"
@@ -319,6 +320,41 @@
// ----------------------------------------------------------------------------
+// Filter returns a new properties object which contains all properties
+// for which the key matches the pattern.
+func (p *Properties) Filter(pattern string) (*Properties, error) {
+ re, err := regexp.Compile(pattern)
+ if err != nil {
+ return nil, err
+ }
+
+ return p.FilterRegexp(re), nil
+}
+
+// FilterRegexp returns a new properties object which contains all properties
+// for which the key matches the regular expression.
+func (p *Properties) FilterRegexp(re *regexp.Regexp) *Properties {
+ pp := NewProperties()
+ for k, v := range p.m {
+ if re.MatchString(k) {
+ pp.Set(k, v)
+ }
+ }
+ return pp
+}
+
+// FilterPrefix returns a new properties object which contains all properties
+// for which the key starts with the prefix.
+func (p *Properties) FilterPrefix(prefix string) *Properties {
+ pp := NewProperties()
+ for k, v := range p.m {
+ if strings.HasPrefix(k, prefix) {
+ pp.Set(k, v)
+ }
+ }
+ return pp
+}
+
// Len returns the number of keys.
func (p *Properties) Len() int {
return len(p.m)
diff --git a/properties_test.go b/properties_test.go
index ef5ce2c..ba5d6be 100644
--- a/properties_test.go
+++ b/properties_test.go
@@ -299,6 +299,53 @@
// ----------------------------------------------------------------------------
+type filterTest struct {
+ input string
+ pattern string
+ keys []string
+ err string
+}
+
+var filterTests = []*filterTest{
+ &filterTest{"", "", []string{}, ""},
+ &filterTest{"", "abc", []string{}, ""},
+ &filterTest{"key=value", "", []string{"key"}, ""},
+ &filterTest{"key=value", "key=", []string{}, ""},
+ &filterTest{"key=value\nfoo=bar", "", []string{"foo", "key"}, ""},
+ &filterTest{"key=value\nfoo=bar", "f", []string{"foo"}, ""},
+ &filterTest{"key=value\nfoo=bar", "fo", []string{"foo"}, ""},
+ &filterTest{"key=value\nfoo=bar", "foo", []string{"foo"}, ""},
+ &filterTest{"key=value\nfoo=bar", "fooo", []string{}, ""},
+ &filterTest{"key=value\nkey2=value2\nfoo=bar", "ey", []string{"key", "key2"}, ""},
+ &filterTest{"key=value\nkey2=value2\nfoo=bar", "key", []string{"key", "key2"}, ""},
+ &filterTest{"key=value\nkey2=value2\nfoo=bar", "^key", []string{"key", "key2"}, ""},
+ &filterTest{"key=value\nkey2=value2\nfoo=bar", "^(key|foo)", []string{"foo", "key", "key2"}, ""},
+ &filterTest{"key=value\nkey2=value2\nfoo=bar", "[ abc", nil, "error parsing regexp.*"},
+}
+
+// ----------------------------------------------------------------------------
+
+type filterPrefixTest struct {
+ input string
+ prefix string
+ keys []string
+}
+
+var filterPrefixTests = []*filterPrefixTest{
+ &filterPrefixTest{"", "", []string{}},
+ &filterPrefixTest{"", "abc", []string{}},
+ &filterPrefixTest{"key=value", "", []string{"key"}},
+ &filterPrefixTest{"key=value", "key=", []string{}},
+ &filterPrefixTest{"key=value\nfoo=bar", "", []string{"foo", "key"}},
+ &filterPrefixTest{"key=value\nfoo=bar", "f", []string{"foo"}},
+ &filterPrefixTest{"key=value\nfoo=bar", "fo", []string{"foo"}},
+ &filterPrefixTest{"key=value\nfoo=bar", "foo", []string{"foo"}},
+ &filterPrefixTest{"key=value\nfoo=bar", "fooo", []string{}},
+ &filterPrefixTest{"key=value\nkey2=value2\nfoo=bar", "key", []string{"key", "key2"}},
+}
+
+// ----------------------------------------------------------------------------
+
// TestBasic tests basic single key/value combinations with all possible
// whitespace, delimiter and newline permutations.
func (l *TestSuite) TestBasic(c *C) {
@@ -470,6 +517,44 @@
c.Assert(func() { p.MustGetString("invalid") }, PanicMatches, "unknown property: invalid")
}
+func (l *TestSuite) TestFilter(c *C) {
+ for _, test := range filterTests {
+ p, err := parse(test.input)
+ c.Assert(err, IsNil)
+ pp, err := p.Filter(test.pattern)
+ if err != nil {
+ c.Assert(err, ErrorMatches, test.err)
+ continue
+ }
+ c.Assert(pp, NotNil)
+ c.Assert(pp.Len(), Equals, len(test.keys))
+ for _, key := range test.keys {
+ v1, ok1 := p.Get(key)
+ v2, ok2 := pp.Get(key)
+ c.Assert(ok1, Equals, true)
+ c.Assert(ok2, Equals, true)
+ c.Assert(v1, Equals, v2)
+ }
+ }
+}
+
+func (l *TestSuite) TestFilterPrefix(c *C) {
+ for _, test := range filterPrefixTests {
+ p, err := parse(test.input)
+ c.Assert(err, IsNil)
+ pp := p.FilterPrefix(test.prefix)
+ c.Assert(pp, NotNil)
+ c.Assert(pp.Len(), Equals, len(test.keys))
+ for _, key := range test.keys {
+ v1, ok1 := p.Get(key)
+ v2, ok2 := pp.Get(key)
+ c.Assert(ok1, Equals, true)
+ c.Assert(ok2, Equals, true)
+ c.Assert(v1, Equals, v2)
+ }
+ }
+}
+
func (l *TestSuite) TestKeys(c *C) {
for _, test := range keysTests {
p, err := parse(test.input)