Skip to content

Commit

Permalink
allow escapes-sequences in tap exchange specification (fixes #13)
Browse files Browse the repository at this point in the history
  • Loading branch information
jandelgado committed Jul 5, 2019
1 parent 76360a7 commit 5991949
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 5 deletions.
46 changes: 41 additions & 5 deletions pkg/tap_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,51 @@ type ExchangeConfiguration struct {
BindingKey string
}

// unescapeStr reutrns a string with all '\' characters removed from the
// given string
func unescapeStr(s string) string {
res := ""
inEscape := false
for _, c := range s {
if c == '\\' && !inEscape {
inEscape = true
} else {
inEscape = false
res += string(c)
}
}
return res
}

// splitExchangeAndBinding splits a string of the form "exchange:binding"
// and return exchange and binding as string. A colon can be escaped with
// \: if it is part of the exchange or binding string, e.g.
// splitExchangeAndBinding("ex\\:change:binding") -> ("ex:change", "binding", nil)
func splitExchangeAndBinding(exchangeAndBinding string) (string, string, error) {
inEscape := false
pos := -1
for i, c := range exchangeAndBinding {
if c == ':' && !inEscape {
pos = i
break
}
inEscape = (c == '\\')
}
if pos == -1 {
return "", "", errors.New("expected format `exchange`:`binding`, but got `" +
exchangeAndBinding + "`")
}
return unescapeStr(exchangeAndBinding[:pos]), unescapeStr(exchangeAndBinding[pos+1:]), nil
}

// NewExchangeConfiguration returns a pointer to a newly created
// ExchangeConfiguration object
func NewExchangeConfiguration(exchangeAndBindingStr string) (*ExchangeConfiguration, error) {
exchangeAndBinding := strings.Split(exchangeAndBindingStr, ":")
if len(exchangeAndBinding) != 2 {
return nil, errors.New("expected format `exchange`:`binding`, but got `" +
exchangeAndBindingStr + "`")
exchange, binding, err := splitExchangeAndBinding(exchangeAndBindingStr)
if err != nil {
return nil, err
}
return &ExchangeConfiguration{exchangeAndBinding[0], exchangeAndBinding[1]}, nil
return &ExchangeConfiguration{exchange, binding}, nil
}

// TapConfiguration holds the set of ExchangeCOnfigurations to tap to for a
Expand Down
27 changes: 27 additions & 0 deletions pkg/tap_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,33 @@ import (
"github.com/stretchr/testify/assert"
)

func TestUnescapeString(t *testing.T) {
assert.Equal(t, "", unescapeStr(""))
assert.Equal(t, "a", unescapeStr("a"))
assert.Equal(t, "", unescapeStr("\\"))
assert.Equal(t, "\\", unescapeStr("\\\\"))
assert.Equal(t, "a:", unescapeStr("a\\:"))
}

func TestSplitExchangeAndBindingSimpleCaseProceeds(t *testing.T) {
e, b, err := splitExchangeAndBinding("abc:def")
assert.Nil(t, err)
assert.Equal(t, "abc", e)
assert.Equal(t, "def", b)
}

func TestSplitExchangeAndBindingHonorsEscapedColons(t *testing.T) {
e, b, err := splitExchangeAndBinding("abc\\:xyz\\:123:def\\:jkl:")
assert.Nil(t, err)
assert.Equal(t, "abc:xyz:123", e)
assert.Equal(t, "def:jkl:", b)
}

func TestSplitExchangeAndBindingRaisesErrorMissingKey(t *testing.T) {
_, _, err := splitExchangeAndBinding("abcdef")
assert.NotNil(t, err)
}

func TestNewTapConfiguration(t *testing.T) {

tc, err := NewTapConfiguration("uri", "e1:b1,e2:b2")
Expand Down

0 comments on commit 5991949

Please sign in to comment.