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 {
25     import nxt.splitter_ex : splitterASCIIAmong;
26     static if (nl == Newline.native)
27     {
28         version (Windows)
29         {
30             return input.splitterASCIIAmong!('\r', '\n');
31         }
32         else version (Posix)
33         {
34             return input.splitterASCIIAmong!('\n');
35         }
36         else
37         {
38             static assert(0, "Neither on Windows nor Posix!");
39         }
40     }
41     else
42     {
43         static if (nl == Newline.unix)
44         {
45             return input.splitterASCIIAmong!('\n');
46         }
47         else static if (nl == Newline.win)
48         {
49             return input.splitterASCIIAmong!('\r', '\n');
50         }
51         else static if (nl == Newline.mac)
52         {
53             return input.splitterASCIIAmong!('\r');
54         }
55         else static if (nl == Newline.any)
56         {
57             return input.splitterASCIIAmong!('\r', '\n');
58         }
59         else
60         {
61             static assert(0, "Handle Newline." ~ nl.stringof);
62         }
63     }
64 }
65 
66 ///
67 @safe pure nothrow @nogc unittest
68 {
69     import std.algorithm.comparison: equal;
70     assert(equal("a\nb".byLine!(Newline.native), ["a", "b"].s[]));
71     assert(equal("a\r\nb".byLine!(Newline.win), ["a", "b"].s[]));
72     assert(equal("a\rb".byLine!(Newline.mac), ["a", "b"].s[]));
73     assert(equal("a\nb".byLine!(Newline.unix), ["a", "b"].s[]));
74     assert(equal("a\nb".byLine!(Newline.any), ["a", "b"].s[]));
75 }
76 
77 version(unittest)
78 {
79     import nxt.array_help : s;
80 }