1 module nxt.byline;
2 
3 /** Type of NewLine Encoding.
4  */
5 enum Newline
6 {
7 	any,						// Any of win, mac or unix
8 	win,						// Windows: "\r\n"
9 	mac,						// Mac OS: '\r'
10 	unix,					   // UNIX/Linux: '\n'
11 	native,					 // Current OS decides: '\n'
12 }
13 
14 /** Split Input by line.
15  *
16  * See_Also: http://forum.dlang.org/thread/fjqpdfzmitcxxzpwlbgb@forum.dlang.org#post-rwxrytxqqurrazifugje:40forum.dlang.org
17  *
18  * TODO: This should fail with better error message:
19  * assert(equal((cast(ubyte[])"a\nb").byLine!(Newline.any), ["a", "b"]));
20  */
21 auto byLine(Newline nl = Newline.any, Range)(Range input)
22 if (is(typeof(Range.init[0 .. 0])) && // can be sliced
23 	is(typeof(Range.init[0]) : char)) {
24 	import nxt.splitter_ex : splitterASCIIAmong;
25 	static if (nl == Newline.native) {
26 		version (Windows)
27 			return input.splitterASCIIAmong!('\r', '\n');
28 		else version (Posix)
29 			return input.splitterASCIIAmong!('\n');
30 		else
31 			static assert(0, "Neither on Windows nor Posix!");
32 	}
33 	else
34 	{
35 		static if (nl == Newline.unix)
36 			return input.splitterASCIIAmong!('\n');
37 		else static if (nl == Newline.win)
38 			return input.splitterASCIIAmong!('\r', '\n');
39 		else static if (nl == Newline.mac)
40 			return input.splitterASCIIAmong!('\r');
41 		else static if (nl == Newline.any)
42 			return input.splitterASCIIAmong!('\r', '\n');
43 		else
44 			static assert(0, "Handle Newline." ~ nl.stringof);
45 	}
46 }
47 
48 ///
49 pure nothrow @safe @nogc unittest {
50 	import std.algorithm.comparison: equal;
51 	assert(equal("a\nb".byLine!(Newline.native), ["a", "b"].s[]));
52 	assert(equal("a\r\nb".byLine!(Newline.win), ["a", "b"].s[]));
53 	assert(equal("a\rb".byLine!(Newline.mac), ["a", "b"].s[]));
54 	assert(equal("a\nb".byLine!(Newline.unix), ["a", "b"].s[]));
55 	assert(equal("a\nb".byLine!(Newline.any), ["a", "b"].s[]));
56 }
57 
58 version (unittest) {
59 	import nxt.array_help : s;
60 }