CLI interface to medialist (fossil mirror)
修订版 | cd3f096cf3e950eb716945cb852ccb834e7f91b0 (tree) |
---|---|
时间 | 2023-03-14 10:15:17 |
作者 | mio <stigma@disr...> |
Commiter | mio |
Add nothrow version of ml_send_command
FossilOrigin-Name: 5d8042cc5ef8fb8df4e39a86b152a293507d05c2f095fcccc84e339668dd336d
@@ -147,14 +147,14 @@ struct MediaListItem | ||
147 | 147 | /// Returns: A string containing the TSV representation of *item*. |
148 | 148 | /// |
149 | 149 | string tsvRepresentation() const { |
150 | - import std.format : format; | |
151 | - | |
152 | - return "%s\t%s\t%s\t%s\t%s\t%s".format(this.title, | |
153 | - this.progress, | |
154 | - this.status, | |
155 | - this.startDate, | |
156 | - this.endDate, | |
157 | - this.lastUpdated); | |
150 | + import std.format : format; | |
151 | + | |
152 | + return "%s\t%s\t%s\t%s\t%s\t%s".format(this.title, | |
153 | + this.progress, | |
154 | + this.status, | |
155 | + this.startDate, | |
156 | + this.endDate, | |
157 | + this.lastUpdated); | |
158 | 158 | } |
159 | 159 | } |
160 | 160 |
@@ -221,7 +221,9 @@ enum MLCommand | ||
221 | 221 | /// `["(Optional) Item ID", "(Optional) Item ID", ...]` |
222 | 222 | /// |
223 | 223 | /// If no there are no "Item ID" values in `args`, then the entire |
224 | - /// list is irreversibly deleted. | |
224 | + /// list is irreversibly deleted. **NOTE**: This functionality has | |
225 | + /// been deprecated from version 0.2.0, it'll be removed in a later | |
226 | + /// version. | |
225 | 227 | /// |
226 | 228 | delete_, |
227 | 229 | /// |
@@ -455,7 +457,7 @@ MediaList* ml_open_list(string filePath, out MLError error) nothrow | ||
455 | 457 | /// |
456 | 458 | /// See_Also: ml_open_list |
457 | 459 | /// |
458 | -void ml_free_list(MediaList* list) | |
460 | +void ml_free_list(MediaList* list) nothrow | |
459 | 461 | { |
460 | 462 | import core.memory : GC; |
461 | 463 |
@@ -1018,7 +1020,7 @@ MediaListItem[] ml_fetch_items(MediaList* list, size_t[] ids ...) | ||
1018 | 1020 | /// ml_fetch_item, ml_fetch_all |
1019 | 1021 | /// |
1020 | 1022 | MediaListItem[] ml_fetch_items(MediaList* list, out MLError err, |
1021 | - size_t[] ids ...) nothrow | |
1023 | + size_t[] ids ...) nothrow | |
1022 | 1024 | { |
1023 | 1025 | import core.stdc.errno : errno, EACCES; |
1024 | 1026 |
@@ -1190,8 +1192,7 @@ MediaListItem[] ml_fetch_all(MediaList* list, out MLError error) nothrow | ||
1190 | 1192 | /// |
1191 | 1193 | /// This is the main way to interact with a MediaList. The value of |
1192 | 1194 | /// *args* will depend on the value of *command*. See `MLCommand` |
1193 | -/// for more information. If there are any errors in the way *args* | |
1194 | -/// is formatted, `MLError.invalidArgs` will be returned. | |
1195 | +/// for more information. | |
1195 | 1196 | /// |
1196 | 1197 | /// Params: |
1197 | 1198 | /// list = The MediaList to perform the action on. |
@@ -1201,33 +1202,68 @@ MediaListItem[] ml_fetch_all(MediaList* list, out MLError error) nothrow | ||
1201 | 1202 | /// Returns: If no error occurred, then `MLError.success` will be |
1202 | 1203 | /// returned. Otherwise, a value of `MLError`. |
1203 | 1204 | /// |
1205 | +/// Throws: `MLException` if there was an error in the way the *args* were | |
1206 | +/// formatted. | |
1207 | +/// | |
1204 | 1208 | /// See_Also: |
1205 | 1209 | /// MLCommand |
1206 | 1210 | /// |
1207 | -MLError ml_send_command(MediaList* list, MLCommand command, string[] args) | |
1211 | +void ml_send_command(MediaList* list, MLCommand command, string[] args) | |
1208 | 1212 | { |
1209 | - MLError res; | |
1213 | + switch (command) | |
1214 | + { | |
1215 | + case MLCommand.add: | |
1216 | + _ml_add(list, args); | |
1217 | + break; | |
1218 | + case MLCommand.delete_: | |
1219 | + _ml_delete(list, args); | |
1220 | + break; | |
1221 | + case MLCommand.update: | |
1222 | + _ml_update(list, args); | |
1223 | + break; | |
1224 | + default: | |
1225 | + throw new MLException(MLError.unknownCommand); | |
1226 | + } | |
1227 | +} | |
1210 | 1228 | |
1229 | +/// | |
1230 | +/// Perform a *command* on *list*. | |
1231 | +/// | |
1232 | +/// This is the main way to interact with a MediaList. The value of | |
1233 | +/// *args* will depend on the value of *command*. See `MLCommand` | |
1234 | +/// for more information. If there are any errors, *error* will be | |
1235 | +/// set to a value other than `MLError.success`. | |
1236 | +/// | |
1237 | +/// Params: | |
1238 | +/// list = The MediaList to perform the action on. | |
1239 | +/// command = The type of action to perform. | |
1240 | +/// args = The arguments that *command* will use. | |
1241 | +/// error = The out-parameter for determining any errrors. | |
1242 | +/// | |
1243 | +/// See_Also: | |
1244 | +/// MLCommand | |
1245 | +/// | |
1246 | +void ml_send_command(MediaList* list, MLCommand command, string[] args, | |
1247 | + out MLError error) nothrow | |
1248 | +{ | |
1211 | 1249 | switch (command) |
1212 | 1250 | { |
1213 | 1251 | case MLCommand.add: |
1214 | - res = _ml_add(list, args); | |
1252 | + _ml_add(list, args, error); | |
1215 | 1253 | break; |
1216 | 1254 | case MLCommand.delete_: |
1217 | - res = _ml_delete(list, args); | |
1255 | + _ml_delete(list, args, error); | |
1218 | 1256 | break; |
1219 | 1257 | case MLCommand.update: |
1220 | - res = _ml_update(list, args); | |
1258 | + _ml_update(list, args, error); | |
1221 | 1259 | break; |
1222 | 1260 | default: |
1223 | - res = MLError.unknownCommand; | |
1261 | + error = MLError.unknownCommand; | |
1224 | 1262 | break; |
1225 | 1263 | } |
1226 | - | |
1227 | - return res; | |
1228 | 1264 | } |
1229 | 1265 | |
1230 | -private MLError _ml_add(MediaList* list, string[] args) | |
1266 | +private void _ml_add(MediaList* list, string[] args) | |
1231 | 1267 | { |
1232 | 1268 | string title; |
1233 | 1269 | string progress = "-/-"; |
@@ -1236,7 +1272,7 @@ private MLError _ml_add(MediaList* list, string[] args) | ||
1236 | 1272 | DateTime currentDate = cast(DateTime)Clock.currTime; |
1237 | 1273 | |
1238 | 1274 | if (args.length < 1) |
1239 | - return MLError.invalidArgs; | |
1275 | + throw new MLException(MLError.invalidArgs); | |
1240 | 1276 | |
1241 | 1277 | title = args[0]; |
1242 | 1278 |
@@ -1247,7 +1283,7 @@ private MLError _ml_add(MediaList* list, string[] args) | ||
1247 | 1283 | status = (args[2] is null) ? "UNKNOWN" : args[2]; |
1248 | 1284 | |
1249 | 1285 | if (true == list.isOpen) |
1250 | - return MLError.fileAlreadyOpen; | |
1286 | + throw new MLException(MLError.fileAlreadyOpen); | |
1251 | 1287 | |
1252 | 1288 | size_t[2][6] headerPositions = _ml_get_header_positions(list); |
1253 | 1289 | int currentIndent = 0; |
@@ -1275,8 +1311,8 @@ private MLError _ml_add(MediaList* list, string[] args) | ||
1275 | 1311 | listFile.write(status); |
1276 | 1312 | break; |
1277 | 1313 | case MLHeaders.lastUpdated: |
1278 | - listFile.writef("%d-%02d-%02d", currentDate.year, currentDate.month, | |
1279 | - currentDate.day); | |
1314 | + listFile.writef("%d-%02d-%02d", currentDate.year, | |
1315 | + currentDate.month, currentDate.day); | |
1280 | 1316 | break; |
1281 | 1317 | default: |
1282 | 1318 | break; |
@@ -1284,8 +1320,25 @@ private MLError _ml_add(MediaList* list, string[] args) | ||
1284 | 1320 | } |
1285 | 1321 | |
1286 | 1322 | listFile.write("\n"); |
1323 | +} | |
1287 | 1324 | |
1288 | - return MLError.success; | |
1325 | +private void _ml_add(MediaList* list, string[] args, out MLError error) nothrow | |
1326 | +{ | |
1327 | + import core.stdc.errno : errno, EACCES; | |
1328 | + | |
1329 | + error = MLError.success; | |
1330 | + | |
1331 | + try { | |
1332 | + _ml_add(list, args); | |
1333 | + } catch (MLException e) { | |
1334 | + error = e.error; | |
1335 | + } catch (StdioException e) { | |
1336 | + error = (errno == EACCES) ? | |
1337 | + MLError.permissionError : | |
1338 | + MLError.unspecifiedError; | |
1339 | + } catch (Exception e) { | |
1340 | + error = MLError.unspecifiedError; | |
1341 | + } | |
1289 | 1342 | } |
1290 | 1343 | |
1291 | 1344 | /** |
@@ -1311,21 +1364,21 @@ private size_t[] _ml_conv_sort_num_list(const string[] args) | ||
1311 | 1364 | return ids; |
1312 | 1365 | } |
1313 | 1366 | |
1314 | -private MLError _ml_delete(MediaList* list, string[] args) | |
1367 | +private void _ml_delete(MediaList* list, string[] args) | |
1315 | 1368 | { |
1316 | 1369 | if (true == list.isOpen) |
1317 | - return MLError.fileAlreadyOpen; | |
1370 | + throw new MLException(MLError.fileAlreadyOpen); | |
1318 | 1371 | |
1319 | 1372 | if (0 == args.length) { |
1320 | - // TODO: Use system recycle bin (6518ca25e4) | |
1373 | + // NOTE: This will be removed in a version after 0.2.0. | |
1321 | 1374 | remove(list.filePath); |
1322 | - return MLError.success; | |
1375 | + return; | |
1323 | 1376 | } |
1324 | 1377 | |
1325 | 1378 | size_t[] ids = _ml_conv_sort_num_list(args); |
1326 | 1379 | |
1327 | 1380 | if (null is ids) |
1328 | - return MLError.invalidArgs; | |
1381 | + throw new MLException(MLError.invalidArgs); | |
1329 | 1382 | |
1330 | 1383 | File listFile = File(list.filePath); |
1331 | 1384 | list.isOpen = true; |
@@ -1383,17 +1436,34 @@ private MLError _ml_delete(MediaList* list, string[] args) | ||
1383 | 1436 | tempFile.close(); |
1384 | 1437 | |
1385 | 1438 | remove(tempFilePath); |
1439 | +} | |
1440 | + | |
1441 | +private void _ml_delete(MediaList* list, string[] args, out MLError error) nothrow | |
1442 | +{ | |
1443 | + import core.stdc.errno : errno, EACCES; | |
1386 | 1444 | |
1387 | - return MLError.success; | |
1445 | + error = MLError.success; | |
1446 | + | |
1447 | + try { | |
1448 | + _ml_delete(list, args); | |
1449 | + } catch (MLException me) { | |
1450 | + error = me.error; | |
1451 | + } catch (StdioException se) { | |
1452 | + error = (errno == EACCES) ? | |
1453 | + MLError.permissionError : | |
1454 | + MLError.unspecifiedError; | |
1455 | + } catch (Exception e) { | |
1456 | + error = MLError.unspecifiedError; | |
1457 | + } | |
1388 | 1458 | } |
1389 | 1459 | |
1390 | -private MLError _ml_update(MediaList* list, string[] args) | |
1460 | +private void _ml_update(MediaList* list, string[] args) | |
1391 | 1461 | { |
1392 | 1462 | if (list.isOpen) |
1393 | - return MLError.fileAlreadyOpen; | |
1463 | + throw new MLException(MLError.fileAlreadyOpen); | |
1394 | 1464 | |
1395 | 1465 | if (2 > args.length) |
1396 | - return MLError.invalidArgs; | |
1466 | + throw new MLException(MLError.invalidArgs); | |
1397 | 1467 | |
1398 | 1468 | string title = null; |
1399 | 1469 | string progress = null; |
@@ -1406,7 +1476,7 @@ private MLError _ml_update(MediaList* list, string[] args) | ||
1406 | 1476 | try { |
1407 | 1477 | id = to!size_t(args[0]); |
1408 | 1478 | } catch (Exception e) { |
1409 | - return MLError.invalidArgs; | |
1479 | + throw new MLException(MLError.invalidArgs); | |
1410 | 1480 | } |
1411 | 1481 | |
1412 | 1482 | foreach(string arg; args) { |
@@ -1569,8 +1639,23 @@ private MLError _ml_update(MediaList* list, string[] args) | ||
1569 | 1639 | listFile.write(line); |
1570 | 1640 | } |
1571 | 1641 | listFile.flush(); |
1642 | +} | |
1572 | 1643 | |
1573 | - return MLError.success; | |
1644 | +private void _ml_update(MediaList* list, string[] args, out MLError error) nothrow | |
1645 | +{ | |
1646 | + error = MLError.success; | |
1647 | + | |
1648 | + try { | |
1649 | + _ml_update(list, args); | |
1650 | + } catch (MLException me) { | |
1651 | + error = me.error; | |
1652 | + } catch (StdioException se) { | |
1653 | + error = (errno == EACCESS) ? | |
1654 | + MLError.permissionError : | |
1655 | + MLError.unspecifiedError; | |
1656 | + } catch (Exception e) { | |
1657 | + error = MLError.unspecifiedError; | |
1658 | + } | |
1574 | 1659 | } |
1575 | 1660 | |
1576 | 1661 | private enum MLHeaders |