1 /++
2 +
3 +/
4 module virc.numerics.monitor;
5 
6 import std.algorithm : among;
7 
8 import virc.numerics.definitions;
9 /++
10 +
11 +/
12 //730 <nick> :target[!user@host][,target[!user@host]]*
13 auto parseNumeric(Numeric numeric : Numeric.RPL_MONONLINE, T)(T input) {
14 	import std.algorithm : map, splitter;
15 	import virc.common : User;
16 	import virc.usermask : UserMask;
17 	input.popFront();
18 	auto split = input.front.splitter(",");
19 	return split.map!((x) { User user; user.mask = UserMask(x); return user; });
20 }
21 ///
22 @safe pure nothrow @nogc unittest { //Numeric.RPL_MONONLINE
23 	import std.range : only;
24 	{
25 		auto logon = parseNumeric!(Numeric.RPL_MONONLINE)(only("test", "someone!someIdent@example.net"));
26 		assert(logon.front.mask.nickname == "someone");
27 		assert(logon.front.mask.ident == "someIdent");
28 		assert(logon.front.mask.host == "example.net");
29 	}
30 	{
31 		auto logon = parseNumeric!(Numeric.RPL_MONONLINE)(only("test", "someone!someIdent@example.net,someone2!someOther@example.com"));
32 		assert(logon.front.mask.nickname == "someone");
33 		assert(logon.front.mask.ident == "someIdent");
34 		assert(logon.front.mask.host == "example.net");
35 		logon.popFront();
36 		assert(logon.front.mask.nickname == "someone2");
37 		assert(logon.front.mask.ident == "someOther");
38 		assert(logon.front.mask.host == "example.com");
39 	}
40 }
41 
42 /++
43 +
44 +/
45 //731 <nick> :target[,target2]*
46 //732 <nick> :target[,target2]*
47 auto parseNumeric(Numeric numeric, T)(T input) if (numeric.among(Numeric.RPL_MONOFFLINE,Numeric.RPL_MONLIST)) {
48 	import std.algorithm.iteration : map, splitter;
49 	import virc.common : User;
50 	input.popFront();
51 	auto split = input.front.splitter(",");
52 	return split.map!((x) { User user; user.mask.nickname = x; return user; });
53 }
54 ///
55 @safe pure nothrow @nogc unittest { //Numeric.RPL_MONOFFLINE
56 	import std.range : only;
57 	{
58 		auto logoff = parseNumeric!(Numeric.RPL_MONONLINE)(only("test", "someone"));
59 		assert(logoff.front.mask.nickname == "someone");
60 		assert(logoff.front.mask.ident.isNull);
61 		assert(logoff.front.mask.host.isNull);
62 	}
63 	{
64 		auto logoff = parseNumeric!(Numeric.RPL_MONONLINE)(only("test", "someone,someone2"));
65 		assert(logoff.front.mask.nickname == "someone");
66 		assert(logoff.front.mask.ident.isNull);
67 		assert(logoff.front.mask.host.isNull);
68 		logoff.popFront();
69 		assert(logoff.front.mask.nickname == "someone2");
70 		assert(logoff.front.mask.ident.isNull);
71 		assert(logoff.front.mask.host.isNull);
72 	}
73 }
74 
75 /++
76 +
77 +/
78 //734 <nick> <limit> <targets> :Monitor list is full.
79 auto parseNumeric(Numeric numeric : Numeric.ERR_MONLISTFULL, T)(T input) {
80 	import std.conv : to;
81 	import std.range : front, popFront;
82 	import std.typecons : Tuple;
83 	import virc.common : User;
84 	input.popFront();
85 	auto limit = input.front.to!ulong;
86 	input.popFront();
87 	User user;
88 	user.mask.nickname = input.front;
89 	return Tuple!(ulong, "limit", User, "userAdded")(limit, user);
90 }
91 ///
92 @safe pure /+nothrow @nogc+/ unittest { //Numeric.ERR_MONLISTFULL
93 	import std.range : only;
94 	auto test = parseNumeric!(Numeric.ERR_MONLISTFULL)(only("someone", "5", "someone2", "Monitor list is full."));
95 	assert(test.limit == 5);
96 	assert(test.userAdded.nickname == "someone2");
97 }