1 module parsing.list_parser;
2 
3 import std..string;
4 import std.algorithm;
5 import std.array;
6 
7 /// Parse a list from a file in the format:
8 /// ---
9 /// # comment
10 /// One item per line # you can have inline comments too
11 /// ---
12 /// Comment character can be customized as the second argument to constructor
13 /// It will automatically strip spaces in the processed lines
14 class ConfigList
15 {
16 	string[] items;
17 	this(string inBuffer, bool stripSpaces = true, string commentChar = "#")
18 	{
19 		// strip the inBuffer of any white space or spurious whitespace before processing
20 		inBuffer = strip(inBuffer);
21 		// Split with lineSplitter as a lazy range, and alloc only once
22 		// ignore any comment lines
23 		items = inBuffer.lineSplitter()
24 			.map!(line => strip(line))
25 			.filter!(line => !line.startsWith(commentChar))
26 			// taking care of inline comments
27 			.map!((line){
28 				if (auto split = line.findSplit(commentChar))
29 					return split[0];
30 				else
31 					return line;
32 			})
33 			.map!(line => stripSpaces ? strip(line) : line)
34 			.array();
35 	}
36 
37 	bool canFind(string x)
38 	{
39 		return items.canFind(x);
40 	}
41 	
42 	string opIndex(ulong key)
43 	{
44 		return items[key];
45 	}
46 
47 	ulong lenght()
48 	{
49 		return items.length;
50 	}
51 
52 	unittest
53 	{
54 		auto testStr = "
55 		# first line comment
56 		/dev/sda # some comment
57 		# comment in random line
58 		/dev/sdb
59 		/dev/sdc
60 		/dev/sde
61 		";
62 		ConfigList cl = new ConfigList(testStr);
63 		assert(cl.items[0] == "/dev/sda", "inline comment not stripped");
64 		assert(cl.items[1] == "/dev/sdb", "second line wasn't parsed correctly");
65 	}
66 }