Add emqx_topic:tokens/1 function (#2305)

* Add emqx_topic:tokens/1 function
This commit is contained in:
Feng Lee 2019-03-13 23:31:44 +08:00 committed by turtleDeng
parent 111b66121c
commit 56718e35cb
2 changed files with 33 additions and 9 deletions

View File

@ -14,10 +14,13 @@
-module(emqx_topic). -module(emqx_topic).
-include("emqx_mqtt.hrl").
-export([match/2]). -export([match/2]).
-export([validate/1, validate/2]). -export([validate/1, validate/2]).
-export([levels/1]). -export([levels/1]).
-export([triples/1]). -export([triples/1]).
-export([tokens/1]).
-export([words/1]). -export([words/1]).
-export([wildcard/1]). -export([wildcard/1]).
-export([join/1, prepend/2]). -export([join/1, prepend/2]).
@ -35,8 +38,6 @@
-define(MAX_TOPIC_LEN, 4096). -define(MAX_TOPIC_LEN, 4096).
-include("emqx_mqtt.hrl").
%% @doc Is wildcard topic? %% @doc Is wildcard topic?
-spec(wildcard(topic() | words()) -> true | false). -spec(wildcard(topic() | words()) -> true | false).
wildcard(Topic) when is_binary(Topic) -> wildcard(Topic) when is_binary(Topic) ->
@ -147,13 +148,19 @@ bin('#') -> <<"#">>;
bin(B) when is_binary(B) -> B; bin(B) when is_binary(B) -> B;
bin(L) when is_list(L) -> list_to_binary(L). bin(L) when is_list(L) -> list_to_binary(L).
-spec(levels(topic()) -> pos_integer()).
levels(Topic) when is_binary(Topic) -> levels(Topic) when is_binary(Topic) ->
length(words(Topic)). length(tokens(Topic)).
%% @doc Split topic to tokens.
-spec(tokens(topic()) -> list(binary())).
tokens(Topic) ->
binary:split(Topic, <<"/">>, [global]).
%% @doc Split Topic Path to Words %% @doc Split Topic Path to Words
-spec(words(topic()) -> words()). -spec(words(topic()) -> words()).
words(Topic) when is_binary(Topic) -> words(Topic) when is_binary(Topic) ->
[word(W) || W <- binary:split(Topic, <<"/">>, [global])]. [word(W) || W <- tokens(Topic)].
word(<<>>) -> ''; word(<<>>) -> '';
word(<<"+">>) -> '+'; word(<<"+">>) -> '+';

View File

@ -20,8 +20,17 @@
-compile(export_all). -compile(export_all).
-compile(nowarn_export_all). -compile(nowarn_export_all).
-import(emqx_topic, [wildcard/1, match/2, validate/1, triples/1, join/1, -import(emqx_topic,
words/1, systop/1, feed_var/3, parse/1]). [wildcard/1,
match/2,
validate/1,
triples/1,
join/1,
words/1,
systop/1,
feed_var/3,
parse/1
]).
-define(N, 10000). -define(N, 10000).
@ -32,6 +41,7 @@ all() ->
t_triples, t_triples,
t_join, t_join,
t_levels, t_levels,
t_tokens,
t_words, t_words,
t_systop, t_systop,
t_feed_var, t_feed_var,
@ -165,6 +175,9 @@ t_triples_perf(_) ->
t_levels(_) -> t_levels(_) ->
?assertEqual(4, emqx_topic:levels(<<"a/b/c/d">>)). ?assertEqual(4, emqx_topic:levels(<<"a/b/c/d">>)).
t_tokens(_) ->
?assertEqual([<<"a">>, <<"b">>, <<"+">>, <<"#">>], emqx_topic:tokens(<<"a/b/+/#">>)).
t_words(_) -> t_words(_) ->
['', <<"a">>, '+', '#'] = words(<<"/a/+/#">>), ['', <<"a">>, '+', '#'] = words(<<"/a/+/#">>),
['', <<"abkc">>, <<"19383">>, '+', <<"akakdkkdkak">>, '#'] = words(<<"/abkc/19383/+/akakdkkdkak/#">>), ['', <<"abkc">>, <<"19383">>, '+', <<"akakdkkdkak">>, '#'] = words(<<"/abkc/19383/+/akakdkkdkak/#">>),
@ -193,9 +206,12 @@ t_systop(_) ->
?assertEqual(SysTop2,systop(<<"abc">>)). ?assertEqual(SysTop2,systop(<<"abc">>)).
t_feed_var(_) -> t_feed_var(_) ->
?assertEqual(<<"$queue/client/clientId">>, feed_var(<<"$c">>, <<"clientId">>, <<"$queue/client/$c">>)), ?assertEqual(<<"$queue/client/clientId">>,
?assertEqual(<<"username/test/client/x">>, feed_var(<<"%u">>, <<"test">>, <<"username/%u/client/x">>)), feed_var(<<"$c">>, <<"clientId">>, <<"$queue/client/$c">>)),
?assertEqual(<<"username/test/client/clientId">>, feed_var(<<"%c">>, <<"clientId">>, <<"username/test/client/%c">>)). ?assertEqual(<<"username/test/client/x">>,
feed_var(<<"%u">>, <<"test">>, <<"username/%u/client/x">>)),
?assertEqual(<<"username/test/client/clientId">>,
feed_var(<<"%c">>, <<"clientId">>, <<"username/test/client/%c">>)).
long_topic() -> long_topic() ->
iolist_to_binary([[integer_to_list(I), "/"] || I <- lists:seq(0, 10000)]). iolist_to_binary([[integer_to_list(I), "/"] || I <- lists:seq(0, 10000)]).
@ -208,3 +224,4 @@ t_parse(_) ->
?assertEqual({<<"$local/$queue/topic">>, #{}}, parse(<<"$local/$queue/topic">>)), ?assertEqual({<<"$local/$queue/topic">>, #{}}, parse(<<"$local/$queue/topic">>)),
?assertEqual({<<"$local/$share/group/a/b/c">>, #{}}, parse(<<"$local/$share/group/a/b/c">>)), ?assertEqual({<<"$local/$share/group/a/b/c">>, #{}}, parse(<<"$local/$share/group/a/b/c">>)),
?assertEqual({<<"$fastlane/topic">>, #{}}, parse(<<"$fastlane/topic">>)). ?assertEqual({<<"$fastlane/topic">>, #{}}, parse(<<"$fastlane/topic">>)).