Created
October 21, 2016 17:09
-
-
Save inhies/2c80924727fa8eba0d5465da6dbef33e to your computer and use it in GitHub Desktop.
Revisions
-
inhies created this gist
Oct 21, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,132 @@ package main import ( "log" "strings" ) type check struct { Sub, Topic string ShouldMatch bool } func main() { tests := []check{ {"myhome/groundfloor/+/temperature", "myhome/groundfloor/livingroom/temperature", true}, {"myhome/groundfloor/+/temperature", "myhome/groundfloor/kitchen/temperature", true}, {"myhome/groundfloor/+/temperature", "myhome/groundfloor/kitchen/brightness", false}, {"myhome/groundfloor/+/temperature", "myhome/firstfloor/kitchen/temperature", false}, {"myhome/groundfloor/+/temperature", "myhome/groundfloor/kitchen/fridge/temperature", false}, {"myhome/groundfloor/#", "myhome/groundfloor/livingroom/temperature", true}, {"myhome/groundfloor/#", "myhome/groundfloor/kitchen/temperature", true}, {"myhome/groundfloor/#", "myhome/groundfloor/kitchen/brightness", true}, {"myhome/groundfloor/#", "myhome/firstfloor/kitchen/temperature", false}, {"a/b/c/d", "a/b/c/d", true}, {"+/b/c/d", "a/b/c/d", true}, {"a/+/c/d", "a/b/c/d", true}, {"a/+/+/d", "a/b/c/d", true}, {"+/+/+/+", "a/b/c/d", true}, {"a/b/c", "a/b/c/d", false}, {"b/+/c/d", "a/b/c/d", false}, {"+/+/+", "a/b/c/d", false}, {"#", "a/b/c/d", true}, {"a/#", "a/b/c/d", true}, {"a/b/#", "a/b/c/d", true}, {"a/b/c/#", "a/b/c/d", true}, {"+/b/c/#", "a/b/c/d", true}, {"a/+/topic", "a//topic", true}, {"+/a/topic", "/a/topic", true}, {"#", "/a/topic", true}, {"a/topic/+", "a/topic/", true}, {"a/topic/#", "a/topic/", true}, {"sport/tennis/player1/#", "sport/tennis/player1", true}, {"sport/tennis/player1/#", "sport/tennis/player1/ranking", true}, {"sport/tennis/player1/#", "sport/tennis/player1/score/wimbledon", true}, {"sport/#", "sport/tennis/player1", true}, {"sport/tennis/#", "sport/tennis/player1", true}, {"sport/tennis#", "sport/tennis/player1", false}, {"sport/tennis/#/ranking", "sport/tennis/player1", false}, {"sport/tennis/+", "sport/tennis/player1", true}, {"sport/tennis/+", "sport/tennis/player1/ranking", false}, {"sport/+", "sport", false}, {"sport/+", "sport/", true}, {"+/+", "/finance", true}, {"/+", "/finance", true}, {"+", "/finance", false}, } for i, v := range tests { if CheckTopic(v.Sub, v.Topic) != v.ShouldMatch { log.Fatalf("Failed on %v: %v", i, v) } } } // CheckTopic returns true if a message topic satisfies // a message subscription. func CheckTopic(sub, topic string) bool { s := strings.Split(sub, "/") t := strings.Split(topic, "/") // Check for leading '$' first, becuase we don't want to accidentally // match it using a wildcard later. '$' topics are reserved for the // broker to use and is not for clients. if (sub[0] == '$' && topic[0] != '$') || (topic[0] == '$' && sub[0] != '$') { return false } // Work through the subscription section by section and see if it matches the // topic exatly or via wildcards. for i := 0; i < len(s) && i < len(t); i++ { switch s[i] { case "+": //Single wildcard, dont need to compare continue case "#": if i < len(s)-1 { // Invalid, # is not the last character return false } // Everything after this doesn't matter return true default: if s[i] != t[i] { // This section of the topic and subscription // dont match, so the topic is not a match for // the subscription return false } } } // If we made it this far, everything has matched so far if len(s) == len(t) { // Topic and subscription both have the same amount of sections // and they all matched so return true. return true } else { // the topic and subscription have a mismatch in the number of // sections, but if the last character is this wildcard, then // everything will match if s[len(s)-1] == "#" { return true } // Either the topic or subscription is longer than the other // and the wildcard is not on the end, so they are not a match return false } }