1 module cif.location;
2 
3 import std.datetime.date : TimeOfDay;
4 import std.string : strip;
5 import std.typecons : Nullable;
6 
7 import cif.utils : parseTime;
8 
9 struct OriginLocation
10 {
11     string location;
12     char suffix;
13     TimeOfDay scheduledDeparture;
14     TimeOfDay publicDeparture;
15     string platform;
16     string line;
17     string engineeringAllowance;
18     string pathingAllowance;
19     string activity;
20     string performanceAllowance;
21 
22     this(string record)
23     {
24         this.location = strip(record[2 .. 9]);
25         this.suffix = record[9];
26         this.scheduledDeparture = parseTime(record[10 .. 15]);
27         this.publicDeparture = parseTime(record[15 .. 19]);
28         this.platform = strip(record[19 .. 22]);
29         this.line = strip(record[22 .. 25]);
30         this.engineeringAllowance = strip(record[25 .. 27]);
31         this.pathingAllowance = strip(record[27 .. 29]);
32         this.activity = record[29 .. 41];
33         this.performanceAllowance = strip(record[41 .. 43]);
34     }
35 
36     unittest
37     {
38         auto line = "LOCREWE   1302 13023         TB                                                 ";
39         const OriginLocation origin = OriginLocation(line);
40 
41         assert(origin.location == "CREWE");
42         assert(origin.suffix == ' ');
43         assert(origin.scheduledDeparture == TimeOfDay(13, 2, 0));
44         assert(origin.publicDeparture == TimeOfDay(13, 2, 0));
45         assert(origin.platform == "3");
46         assert(origin.line == "");
47         assert(origin.engineeringAllowance == "");
48         assert(origin.pathingAllowance == "");
49         assert(origin.activity == "TB          ");
50         assert(origin.performanceAllowance == "");
51     }
52 }
53 
54 struct IntermediateLocation
55 {
56     string location;
57     char suffix;
58     Nullable!TimeOfDay scheduledArrival;
59     Nullable!TimeOfDay scheduledDeparture;
60     Nullable!TimeOfDay scheduledPass;
61     TimeOfDay publicArrival;
62     TimeOfDay publicDeparture;
63     string platform;
64     string line;
65     string path;
66     string activity;
67     string engineeringAllowance;
68     string pathingAllowance;
69     string performanceAllowance;
70 
71     this(string record)
72     {
73         this.location = strip(record[2 .. 9]);
74         this.suffix = record[9];
75 
76         if (record[10] != ' ')
77         {
78             this.scheduledArrival = parseTime(record[10 .. 15]);
79         }
80 
81         if (record[15] != ' ')
82         {
83             this.scheduledDeparture = parseTime(record[15 .. 20]);
84         }
85 
86         if (record[20] != ' ')
87         {
88             this.scheduledDeparture = parseTime(record[20 .. 25]);
89         }
90 
91         this.publicArrival = parseTime(record[25 .. 29]);
92         this.publicDeparture = parseTime(record[29 .. 33]);
93         this.platform = strip(record[33 .. 36]);
94         this.line = strip(record[36 .. 39]);
95         this.path = strip(record[39 .. 42]);
96         this.activity = record[42 .. 54];
97         this.engineeringAllowance = strip(record[54 .. 56]);
98         this.pathingAllowance = strip(record[56 .. 58]);
99         this.performanceAllowance = strip(record[58 .. 60]);
100     }
101 
102     unittest
103     {
104         auto line = "LIMKNSCEN 1124 1125      112411255  SL FL T           1                         ";
105         const IntermediateLocation intermediate = IntermediateLocation(line);
106 
107         assert(intermediate.location == "MKNSCEN");
108         assert(intermediate.suffix == ' ');
109         assert(intermediate.scheduledArrival == TimeOfDay(11, 24, 0));
110         assert(intermediate.scheduledDeparture == TimeOfDay(11, 25, 0));
111         assert(intermediate.scheduledPass.isNull());
112         assert(intermediate.publicArrival == TimeOfDay(11, 24, 0));
113         assert(intermediate.publicDeparture == TimeOfDay(11, 25, 0));
114         assert(intermediate.platform == "5");
115         assert(intermediate.line == "SL");
116         assert(intermediate.path == "FL");
117         assert(intermediate.activity == "T           ");
118         assert(intermediate.engineeringAllowance == "1");
119         assert(intermediate.pathingAllowance == "");
120         assert(intermediate.performanceAllowance == "");
121     }
122 }
123 
124 struct TerminatingLocation
125 {
126     string location;
127     char suffix;
128     TimeOfDay scheduledArrival;
129     TimeOfDay publicArrival;
130     string platform;
131     string path;
132     string activity;
133 
134     this(string record)
135     {
136         this.location = strip(record[2 .. 9]);
137         this.suffix = record[9];
138         this.scheduledArrival = parseTime(record[10 .. 15]);
139         this.publicArrival = parseTime(record[15 .. 19]);
140         this.platform = strip(record[19 .. 22]);
141         this.path = strip(record[22 .. 25]);
142         this.activity = record[25 .. 37];
143     }
144 
145     unittest
146     {
147         auto line = "LTSTONEGS 1531 1531      TF                                                     ";
148         const TerminatingLocation terminus = TerminatingLocation(line);
149 
150         assert(terminus.location == "STONEGS");
151         assert(terminus.suffix == ' ');
152         assert(terminus.scheduledArrival == TimeOfDay(15, 31, 0));
153         assert(terminus.publicArrival == TimeOfDay(15, 31, 0));
154         assert(terminus.platform == "");
155         assert(terminus.path == "");
156         assert(terminus.activity == "TF          ");
157     }
158 }