1 /** 2 * Hand-written definition of CWL v1.0 CommandLineTool 3 * 4 * Authors: Tomoya Tanjo 5 * Copyright: © 2021 Tomoya Tanjo 6 * License: Apache-2.0 7 */ 8 module cwl.schema; 9 10 import salad.context : LoadingContext; 11 import salad.exception; 12 import salad.meta; 13 import salad.type; 14 import salad.util; 15 16 @documentRoot class CommandLineTool 17 { 18 @idMap("id", "type") 19 CommandInputParameter[] inputs_; 20 @idMap("id", "type") 21 CommandOutputParameter[] outputs_; 22 immutable class_ = "CommandLineTool"; 23 @id Optional!string id_; 24 @idMap("class") 25 Optional!( 26 Either!( 27 InlineJavascriptRequirement, 28 SchemaDefRequirement, 29 DockerRequirement, 30 SoftwareRequirement, 31 InitialWorkDirRequirement, 32 EnvVarRequirement, 33 ShellCommandRequirement, 34 ResourceRequirement, 35 )[] 36 ) requirements_; 37 @idMap("class") Optional!(Any[]) hints_; 38 Optional!string label_; 39 Optional!string doc_; 40 Optional!CWLVersion cwlVersion_; 41 Optional!(string, string[]) baseCommand_; 42 Optional!(Either!(string, CommandLineBinding)[]) arguments_; 43 Optional!string stdin_; 44 Optional!string stderr_; 45 Optional!string stdout_; 46 Optional!(int[]) successCodes_; 47 Optional!(int[]) temporaryFailCodes_; 48 Optional!(int[]) permanentFailCodes_; 49 50 mixin genCtor; 51 mixin genIdentifier; 52 } 53 54 class CommandInputParameter 55 { 56 @id string id_; 57 Optional!string label_; 58 Optional!(string, string[]) secondaryFiles_; 59 Optional!bool streamable_; 60 Optional!(string, string[]) doc_; 61 Optional!(string, string[]) format_; 62 Optional!CommandLineBinding inputBinding_; 63 Optional!( 64 CWLType, 65 CommandInputRecordSchema, 66 CommandInputEnumSchema, 67 CommandInputArraySchema, 68 string, 69 Either!( 70 CWLType, 71 CommandInputRecordSchema, 72 CommandInputEnumSchema, 73 CommandInputArraySchema, 74 string 75 )[] 76 ) type_; 77 78 mixin genCtor; 79 mixin genIdentifier; 80 } 81 82 class CommandLineBinding 83 { 84 Optional!bool loadContents_; 85 Optional!int position_; 86 Optional!string prefix_; 87 Optional!bool separate_; 88 Optional!string itemSeparator_; 89 Optional!string valueFrom_; 90 Optional!bool shellQuote_; 91 92 mixin genCtor; 93 mixin genIdentifier; 94 } 95 96 class Any 97 { 98 import dyaml : Node, NodeType; 99 100 Node value_; 101 102 alias value_ this; 103 104 this(Node node, in LoadingContext context = LoadingContext.init) 105 { 106 docEnforce(node.type != NodeType.null_, 107 "Any should be non-null", node); 108 value_ = node; 109 } 110 } 111 112 class CWLType 113 { 114 import dyaml : Node; 115 116 enum Types{ 117 null_ = "null", 118 boolean_ = "boolean", 119 int_ = "int", 120 long_ = "long", 121 float_ = "float", 122 double_ = "double", 123 string_ = "string", 124 File_ = "File", 125 Directory_ = "Directory", 126 } 127 128 alias type_ this; 129 130 string type_; 131 132 this(in Node node, in LoadingContext context = LoadingContext.init) @safe 133 { 134 type_ = node.as!string; 135 // enforce 136 } 137 138 bool opEquals(string s) const @nogc nothrow pure 139 { 140 return type_ == s; 141 } 142 } 143 144 class File 145 { 146 immutable class_ = "File"; 147 Optional!string location_; 148 Optional!string path_; 149 Optional!string basename_; 150 Optional!string dirname_; 151 Optional!string nameroot_; 152 Optional!string nameext_; 153 Optional!string checksum_; 154 Optional!int size_; 155 Optional!(Either!(File, Directory)[]) secondaryFiles_; 156 Optional!string format_; 157 Optional!string contents_; 158 159 mixin genCtor; 160 mixin genIdentifier; 161 } 162 163 class Directory 164 { 165 immutable class_ = "Directory"; 166 Optional!string location_; 167 Optional!string path_; 168 Optional!string basename_; 169 Optional!( 170 Either!(File, Directory)[] 171 ) listing_; 172 173 mixin genCtor; 174 mixin genIdentifier; 175 } 176 177 class CommandInputRecordSchema 178 { 179 immutable type_ = "record"; 180 @idMap("name", "type") 181 Optional!(CommandInputRecordField[]) fields_; 182 Optional!string label_; 183 Optional!string name_; 184 185 mixin genCtor; 186 mixin genIdentifier; 187 } 188 189 class CommandInputRecordField 190 { 191 string name_; 192 Either!( 193 CWLType, 194 CommandInputRecordSchema, 195 CommandInputEnumSchema, 196 CommandInputArraySchema, 197 string, 198 Either!( 199 CWLType, 200 CommandInputRecordSchema, 201 CommandInputEnumSchema, 202 CommandInputArraySchema, 203 string, 204 )[] 205 ) type_; 206 Optional!string doc_; 207 Optional!CommandLineBinding inputBinding_; 208 Optional!string label_; 209 210 mixin genCtor; 211 mixin genIdentifier; 212 } 213 214 class CommandInputEnumSchema 215 { 216 string[] symbols_; 217 immutable type_ = "enum"; 218 Optional!string label_; 219 Optional!string name_; 220 Optional!CommandLineBinding inputBinding_; 221 222 mixin genCtor; 223 mixin genIdentifier; 224 } 225 226 class CommandInputArraySchema 227 { 228 Either!( 229 CWLType, 230 CommandInputRecordSchema, 231 CommandInputEnumSchema, 232 CommandInputArraySchema, 233 string, 234 Either!( 235 CWLType, 236 CommandInputRecordSchema, 237 CommandInputEnumSchema, 238 CommandInputArraySchema, 239 string, 240 )[], 241 ) items_; 242 immutable type_ = "array"; 243 Optional!string label_; 244 Optional!CommandLineBinding inputBinding_; 245 246 mixin genCtor; 247 mixin genIdentifier; 248 } 249 250 class CommandOutputParameter 251 { 252 @id string id_; 253 Optional!string label_; 254 Optional!(string, string[]) secondaryFiles_; 255 Optional!bool streamable_; 256 Optional!(string, string[]) doc_; 257 Optional!CommandOutputBinding outputBinding_; 258 Optional!string format_; 259 Optional!( 260 CWLType, 261 stdout, 262 stderr, 263 CommandOutputRecordSchema, 264 CommandOutputEnumSchema, 265 CommandOutputArraySchema, 266 string, 267 Either!( 268 CWLType, 269 CommandOutputRecordSchema, 270 CommandOutputEnumSchema, 271 CommandOutputArraySchema, 272 string 273 )[], 274 ) type_; 275 276 mixin genCtor; 277 mixin genIdentifier; 278 } 279 280 class stdout 281 { 282 import dyaml : Node; 283 284 enum Types{ 285 stdout_ = "stdout", 286 } 287 288 alias type_ this; 289 290 string type_; 291 292 this(in Node node, in LoadingContext context = LoadingContext.init) @safe 293 { 294 type_ = node.as!string; 295 // enforce 296 } 297 } 298 299 class stderr 300 { 301 import dyaml : Node; 302 303 enum Types{ 304 stderr_ = "stderr", 305 } 306 307 alias type_ this; 308 309 string type_; 310 311 this(in Node node, in LoadingContext context = LoadingContext.init) @safe 312 { 313 type_ = node.as!string; 314 // enforce 315 } 316 } 317 318 class CommandOutputBinding 319 { 320 Optional!(string, string[]) glob_; 321 Optional!bool loadContents_; 322 Optional!string outputEval_; 323 324 mixin genCtor; 325 mixin genIdentifier; 326 } 327 328 class CommandOutputRecordSchema 329 { 330 immutable type_ = "record"; 331 @idMap("name", "type") 332 Optional!(CommandOutputRecordField[]) fields_; 333 Optional!string label_; 334 @id Optional!string name_; 335 336 mixin genCtor; 337 mixin genIdentifier; 338 } 339 340 class CommandOutputRecordField 341 { 342 string name_; 343 Either!( 344 CWLType, 345 CommandOutputRecordSchema, 346 CommandOutputEnumSchema, 347 CommandOutputArraySchema, 348 string, 349 Either!( 350 CWLType, 351 CommandOutputRecordSchema, 352 CommandOutputEnumSchema, 353 CommandOutputArraySchema, 354 string, 355 )[], 356 ) type_; 357 Optional!string doc_; 358 Optional!CommandOutputBinding outputBinding_; 359 360 mixin genCtor; 361 mixin genIdentifier; 362 } 363 364 class CommandOutputEnumSchema 365 { 366 string[] symbols_; 367 immutable type_ = "enum"; 368 Optional!string label_; 369 Optional!CommandOutputBinding outputBinding_; 370 371 mixin genCtor; 372 mixin genIdentifier; 373 } 374 375 class CommandOutputArraySchema 376 { 377 Either!( 378 CWLType, 379 CommandOutputRecordSchema, 380 CommandOutputEnumSchema, 381 CommandOutputArraySchema, 382 string, 383 Either!( 384 CWLType, 385 CommandOutputRecordSchema, 386 CommandOutputEnumSchema, 387 CommandOutputArraySchema, 388 string, 389 )[], 390 ) items_; 391 immutable type_ = "array"; 392 Optional!string label_; 393 Optional!CommandOutputBinding outputBinding_; 394 395 mixin genCtor; 396 mixin genIdentifier; 397 } 398 399 class InlineJavascriptRequirement 400 { 401 immutable class_ = "InlineJavascriptRequirement"; 402 Optional!(string[]) expressionLib_; 403 404 mixin genCtor; 405 mixin genIdentifier; 406 } 407 408 class SchemaDefRequirement 409 { 410 immutable class_ = "SchemaDefRequirement"; 411 Either!( 412 InputRecordSchema, 413 InputEnumSchema, 414 InputArraySchema, 415 )[] types_; 416 417 mixin genCtor; 418 mixin genIdentifier; 419 } 420 421 class InputRecordSchema 422 { 423 immutable type_ = "record"; 424 @idMap("name", "type") 425 Optional!( 426 InputRecordField[] 427 ) fields_; 428 Optional!string label_; 429 @id Optional!string name_; 430 431 mixin genCtor; 432 mixin genIdentifier; 433 } 434 435 class InputRecordField 436 { 437 string name_; 438 Either!( 439 CWLType, 440 InputRecordSchema, 441 InputEnumSchema, 442 InputArraySchema, 443 string, 444 Either!( 445 CWLType, 446 InputRecordSchema, 447 InputEnumSchema, 448 InputArraySchema, 449 string, 450 )[], 451 ) type_; 452 Optional!string doc_; 453 Optional!CommandLineBinding inputBinding_; 454 Optional!string label_; 455 456 mixin genCtor; 457 mixin genIdentifier; 458 } 459 460 class InputEnumSchema 461 { 462 string[] symbols_; 463 immutable type_ = "enum"; 464 Optional!string label_; 465 @id Optional!string name_; 466 Optional!CommandLineBinding inpuBinding_; 467 468 mixin genCtor; 469 mixin genIdentifier; 470 } 471 472 class InputArraySchema 473 { 474 Either!( 475 CWLType, 476 InputRecordSchema, 477 InputEnumSchema, 478 InputArraySchema, 479 string, 480 Either!( 481 CWLType, 482 InputRecordSchema, 483 InputEnumSchema, 484 InputArraySchema, 485 string, 486 )[], 487 ) items_; 488 immutable type_ = "array"; 489 Optional!string label_; 490 Optional!CommandLineBinding inputBinding_; 491 492 mixin genCtor; 493 mixin genIdentifier; 494 } 495 496 class DockerRequirement 497 { 498 immutable class_ = "DockerRequirement"; 499 Optional!string dockerPull_; 500 Optional!string dockerLoad_; 501 Optional!string dockerFile_; 502 Optional!string dockerImport_; 503 Optional!string dockerImageId_; 504 Optional!string dockerOutputDirectory_; 505 506 mixin genCtor; 507 mixin genIdentifier; 508 } 509 510 class SoftwareRequirement 511 { 512 immutable class_ = "SoftwareRequirement"; 513 @idMap("package", "specs") 514 SoftwarePackage[] packages_; 515 516 mixin genCtor; 517 mixin genIdentifier; 518 } 519 520 class SoftwarePackage 521 { 522 string package_; 523 Optional!(string[]) version_; 524 Optional!(string[]) specs_; 525 526 mixin genCtor; 527 mixin genIdentifier; 528 } 529 530 class InitialWorkDirRequirement 531 { 532 immutable class_ = "InitialWorkDirRequirement"; 533 Either!( 534 Either!( 535 File, 536 Directory, 537 Dirent, 538 string, 539 )[], 540 string, 541 ) listing_; 542 543 mixin genCtor; 544 mixin genIdentifier; 545 } 546 547 class Dirent 548 { 549 string entry_; 550 Optional!string entryname_; 551 Optional!bool writable_; 552 553 mixin genCtor; 554 mixin genIdentifier; 555 } 556 557 class EnvVarRequirement 558 { 559 immutable class_ = "EnvVarRequirement"; 560 @idMap("envName", "envValue") 561 EnvironmentDef[] envDef_; 562 563 mixin genCtor; 564 mixin genIdentifier; 565 } 566 567 class EnvironmentDef 568 { 569 string envName_; 570 string envValue_; 571 572 mixin genCtor; 573 mixin genIdentifier; 574 } 575 576 class ShellCommandRequirement 577 { 578 immutable class_ = "ShellCommandRequirement"; 579 580 mixin genCtor; 581 mixin genIdentifier; 582 } 583 584 class ResourceRequirement 585 { 586 immutable class_ = "ResourceRequirement"; 587 Optional!(long, string) coresMin_; 588 Optional!(int, string) coresMax_; 589 Optional!(long, string) ramMin_; 590 Optional!(long, string) ramMax_; 591 Optional!(long, string) tmpdirMin_; 592 Optional!(long, string) tmpdirMax_; 593 Optional!(long, string) outdirMin_; 594 Optional!(long, string) outdirMax_; 595 596 mixin genCtor; 597 mixin genIdentifier; 598 } 599 600 class CWLVersion 601 { 602 import dyaml : Node; 603 604 enum Types{ 605 draft_2 = "draft-2", 606 draft_3_dev1 = "draft-3.dev1", 607 draft_3_dev2 = "draft-3.dev2", 608 draft_3_dev3 = "draft-3.dev3", 609 draft_3_dev4 = "draft-3.dev4", 610 draft_3_dev5 = "draft-3.dev5", 611 draft_3 = "draft-3", 612 draft_4_dev1 = "draft-4.dev1", 613 draft_4_dev2 = "draft-4.dev2", 614 draft_4_dev3 = "draft-4.dev3", 615 v1_0_dev4 = "v1.0.dev4", 616 v1_0 = "v1.0", 617 } 618 619 alias type_ this; 620 621 string type_; 622 623 this(in Node node, in LoadingContext context = LoadingContext.init) @safe 624 { 625 type_ = node.as!string; 626 // enforce 627 } 628 629 bool opEquals(string s) const @nogc nothrow pure 630 { 631 return type_ == s; 632 } 633 } 634 635 unittest 636 { 637 import dyaml; 638 639 enum cwl = "examples/bwa-mem-tool.cwl"; 640 auto cmd = Loader.fromFile(cwl) 641 .load 642 .as!CommandLineTool; 643 assert(cmd.dig!"cwlVersion"("v1.2") == "v1.0"); 644 assert(cmd.dig!(["inputs", "reference", "type"], CWLType) == "File"); 645 assert(cmd.dig!("hints", Any[])[0] 646 .as!ResourceRequirement 647 .dig!("coresMin", long) == 2); 648 } 649 650 @documentRoot class Workflow 651 { 652 @idMap("id", "type") 653 InputParameter[] inputs_; 654 @idMap("id", "type") 655 WorkflowOutputParameter[] outputs_; 656 immutable class_ = "Workflow"; 657 @idMap("id") WorkflowStep[] steps_; 658 @id Optional!string id_; 659 @idMap("class") 660 Optional!( 661 Either!( 662 InlineJavascriptRequirement, 663 SchemaDefRequirement, 664 DockerRequirement, 665 SoftwareRequirement, 666 InitialWorkDirRequirement, 667 EnvVarRequirement, 668 ShellCommandRequirement, 669 ResourceRequirement, 670 SubworkflowFeatureRequirement, 671 ScatterFeatureRequirement, 672 MultipleInputFeatureRequirement, 673 StepInputExpressionRequirement, 674 )[] 675 ) requirements_; 676 @idMap("class") Optional!(Any[]) hints_; 677 Optional!string label_; 678 Optional!string doc_; 679 Optional!CWLVersion cwlVersion_; 680 681 mixin genCtor; 682 mixin genIdentifier; 683 } 684 685 class WorkflowOutputParameter 686 { 687 @id string id_; 688 Optional!string label_; 689 Optional!(string, string[]) secondaryFiles_; 690 Optional!bool streamable_; 691 Optional!(string, string[]) doc_; 692 Optional!CommandOutputBinding outputBinding_; 693 Optional!string format_; 694 Optional!(string, string[]) outputSource_; 695 Optional!LinkMergeMethod linkMerge_; 696 Optional!( 697 CWLType, 698 OutputRecordSchema, 699 OutputEnumSchema, 700 OutputArraySchema, 701 string, 702 Either!( 703 CWLType, 704 OutputRecordSchema, 705 OutputEnumSchema, 706 OutputArraySchema, 707 string, 708 )[], 709 ) type_; 710 711 mixin genCtor; 712 mixin genIdentifier; 713 } 714 715 class LinkMergeMethod 716 { 717 import dyaml : Node; 718 719 enum Types{ 720 merge_nested_ = "merge_nested", 721 merge_flattened_ = "merge_flattened", 722 } 723 724 alias type_ this; 725 726 string type_; 727 728 this(in Node node, in LoadingContext context = LoadingContext.init) @safe 729 { 730 type_ = node.as!string; 731 } 732 } 733 734 class OutputRecordSchema 735 { 736 immutable type_ = "record"; 737 @idMap("name", "type") 738 Optional!(OutputRecordField[]) fields_; 739 Optional!string label_; 740 741 mixin genCtor; 742 mixin genIdentifier; 743 } 744 745 class OutputRecordField 746 { 747 string name_; 748 Either!( 749 CWLType, 750 OutputRecordSchema, 751 OutputEnumSchema, 752 OutputArraySchema, 753 string, 754 Either!( 755 CWLType, 756 OutputRecordSchema, 757 OutputEnumSchema, 758 OutputArraySchema, 759 string, 760 )[], 761 ) type_; 762 Optional!string doc_; 763 Optional!CommandOutputBinding outputBinding_; 764 765 mixin genCtor; 766 mixin genIdentifier; 767 } 768 769 class OutputEnumSchema 770 { 771 string[] symbols_; 772 immutable type_ = "enum"; 773 Optional!string label_; 774 Optional!CommandOutputBinding outputBinding_; 775 776 mixin genCtor; 777 mixin genIdentifier; 778 } 779 780 class OutputArraySchema 781 { 782 Either!( 783 CWLType, 784 OutputRecordSchema, 785 OutputEnumSchema, 786 OutputArraySchema, 787 string, 788 Either!( 789 CWLType, 790 OutputRecordSchema, 791 OutputEnumSchema, 792 OutputArraySchema, 793 string, 794 )[], 795 ) items_; 796 immutable type_ = "array"; 797 Optional!string label_; 798 Optional!CommandOutputBinding outputBinding_; 799 800 mixin genCtor; 801 mixin genIdentifier; 802 } 803 804 class WorkflowStep 805 { 806 @id string id_; 807 @idMap("id", "source") 808 WorkflowStepInput[] in_; 809 Either!(string, WorkflowStepOutput)[] out_; 810 Either!(string, CommandLineTool, ExpressionTool, Workflow) run_; 811 @idMap("class") 812 Optional!( 813 Either!( 814 InlineJavascriptRequirement, 815 SchemaDefRequirement, 816 DockerRequirement, 817 SoftwareRequirement, 818 InitialWorkDirRequirement, 819 EnvVarRequirement, 820 ShellCommandRequirement, 821 ResourceRequirement, 822 SubworkflowFeatureRequirement, 823 ScatterFeatureRequirement, 824 MultipleInputFeatureRequirement, 825 StepInputExpressionRequirement, 826 )[] 827 ) requirements_; 828 @idMap("class") Optional!(Any[]) hints_; 829 Optional!string label_; 830 Optional!string doc_; 831 Optional!(string, string[]) scatter_; 832 Optional!ScatterMethod scatterMethod_; 833 834 mixin genCtor; 835 mixin genIdentifier; 836 } 837 838 class WorkflowStepInput 839 { 840 @id string id_; 841 Optional!(string, string[]) source_; 842 Optional!LinkMergeMethod linkMerge_; 843 Optional!Any default_; 844 Optional!string valueFrom_; 845 846 mixin genCtor; 847 mixin genIdentifier; 848 } 849 850 class WorkflowStepOutput 851 { 852 @id string id_; 853 854 mixin genCtor; 855 mixin genIdentifier; 856 } 857 858 class ScatterMethod 859 { 860 import dyaml : Node; 861 862 enum Types{ 863 dotproduct_ = "dotproduct", 864 nested_crossproduct_ = "nested_crossproduct", 865 flat_crossproduct_ = "flat_crossproduct_", 866 } 867 868 alias type_ this; 869 870 string type_; 871 872 this(in Node node, in LoadingContext context = LoadingContext.init) @safe 873 { 874 type_ = node.as!string; 875 // enforce 876 } 877 } 878 879 class SubworkflowFeatureRequirement 880 { 881 immutable class_ = "SubworkflowFeatureRequirement"; 882 883 mixin genCtor; 884 mixin genIdentifier; 885 } 886 887 class ScatterFeatureRequirement 888 { 889 immutable class_ = "ScatterFeatureRequirement"; 890 891 mixin genCtor; 892 mixin genIdentifier; 893 } 894 895 class MultipleInputFeatureRequirement 896 { 897 immutable class_ = "MultipleInputFeatureRequirement"; 898 899 mixin genCtor; 900 mixin genIdentifier; 901 } 902 903 class StepInputExpressionRequirement 904 { 905 immutable class_ = "StepInputExpressionRequirement"; 906 907 mixin genCtor; 908 mixin genIdentifier; 909 } 910 911 @documentRoot class ExpressionTool 912 { 913 @idMap("id", "type") 914 InputParameter[] inputs_; 915 @idMap("id", "type") 916 ExpressionToolOutputParameter[] outputs_; 917 immutable class_ = "Expression"; 918 string expression_; 919 @id Optional!string id_; 920 @idMap("class") 921 Optional!( 922 Either!( 923 InlineJavascriptRequirement, 924 SchemaDefRequirement, 925 DockerRequirement, 926 SoftwareRequirement, 927 InitialWorkDirRequirement, 928 EnvVarRequirement, 929 ShellCommandRequirement, 930 ResourceRequirement, 931 SubworkflowFeatureRequirement, 932 ScatterFeatureRequirement, 933 MultipleInputFeatureRequirement, 934 StepInputExpressionRequirement, 935 )[] 936 ) requirements_; 937 @idMap("class") Optional!(Any[]) hints_; 938 Optional!string label_; 939 Optional!string doc_; 940 Optional!CWLVersion cwlVersion_; 941 942 mixin genCtor; 943 mixin genIdentifier; 944 } 945 946 class InputParameter 947 { 948 @id string id_; 949 Optional!string label_; 950 Optional!(string, string[]) secondaryFiles_; 951 Optional!bool streamable_; 952 Optional!(string, string[]) doc_; 953 Optional!(string, string[]) format_; 954 Optional!CommandLineBinding inputBinding_; 955 Optional!Any default_; 956 Optional!( 957 CWLType, 958 InputRecordSchema, 959 InputEnumSchema, 960 InputArraySchema, 961 string, 962 Either!( 963 CWLType, 964 InputRecordSchema, 965 InputEnumSchema, 966 InputArraySchema, 967 string, 968 )[], 969 ) type_; 970 971 mixin genCtor; 972 mixin genIdentifier; 973 } 974 975 class ExpressionToolOutputParameter 976 { 977 @id string id_; 978 Optional!string label_; 979 Optional!(string, string[]) secondaryFiles_; 980 Optional!bool streamable_; 981 Optional!(string, string[]) doc_; 982 Optional!CommandOutputBinding outputBinding_; 983 Optional!string format_; 984 Optional!( 985 CWLType, 986 OutputRecordSchema, 987 OutputEnumSchema, 988 OutputArraySchema, 989 string, 990 Either!( 991 CWLType, 992 OutputRecordSchema, 993 OutputEnumSchema, 994 OutputArraySchema, 995 string, 996 )[], 997 ) type_; 998 999 mixin genCtor; 1000 mixin genIdentifier; 1001 } 1002 1003 unittest 1004 { 1005 import dyaml; 1006 1007 enum cwl = "examples/count-lines1-wf.cwl"; 1008 auto wf = Loader.fromFile(cwl) 1009 .load 1010 .as!Workflow; 1011 assert(wf.dig!"class"("Invalid") == "Workflow"); 1012 assert(wf.dig!"cwlVersion"("v1.2") == "v1.0"); 1013 assert(wf.dig!(["inputs", "file1", "type"], CWLType) == "File"); 1014 assert(wf.dig!(["outputs", "count_output", "outputSource"], string) == "step2/output"); 1015 }