1 /**
2  * Parsing mime/subclasses files.
3  * Authors:
4  *  $(LINK2 https://github.com/FreeSlave, Roman Chistokhodov)
5  * License:
6  *  $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
7  * Copyright:
8  *  Roman Chistokhodov, 2015-2016
9  */
10 
11 module mime.files.subclasses;
12 
13 public import mime.files.common;
14 
15 private {
16     import std.algorithm;
17     import std.exception;
18     import std.range;
19     import std.traits;
20     import std.typecons;
21 }
22 
23 ///Represents one line in subclasses file.
24 alias Tuple!(string, "mimeType", string, "parent") SubclassLine;
25 
26 /**
27  * Parse mime/subclasses file by line ignoring empty lines and comments.
28  * Returns:
29  *  Range of $(D SubclassLine) tuples.
30  * Throws:
31  *  $(D mime.files.common.MimeFileException) on parsing error.
32  */
33 auto subclassesFileReader(Range)(Range byLine) if(isInputRange!Range && is(ElementType!Range : string)) {
34     return byLine.filter!(lineFilter).map!(function(string line) {
35         auto splitted = std.algorithm.splitter(line);
36         if (!splitted.empty) {
37             auto mimeType = splitted.front;
38             splitted.popFront();
39             if (!splitted.empty) {
40                 auto parent = splitted.front;
41                 return SubclassLine(mimeType, parent);
42             }
43         }
44         throw new MimeFileException("Malformed subclasses file: must be 2 words per line", line);
45     });
46 }
47 
48 ///
49 unittest
50 {
51     string[] lines = ["application/javascript application/ecmascript", "text/x-markdown text/plain"];
52     auto expected = [SubclassLine("application/javascript", "application/ecmascript"), SubclassLine("text/x-markdown", "text/plain")];
53     assert(equal(subclassesFileReader(lines), expected));
54 
55     assertThrown!MimeFileException(subclassesFileReader(["application/javascript"]).array, "must throw");
56 }