AlignmentCli.bend
bend-edit-distance@0.1.0.0 · 93 lines · 0 definitions
1import Base
2import bend-edit-distance@0.1.0.0/Cli.bend as CLI
3import bend-edit-distance@0.1.0.0/EdlibTypes.bend as E
4
5def read_mode(value: String) -> Maybe<&2, E.Mode>:
6 match value:
7 case "NW":
8 Some{E.NW{}}
9 case "SHW":
10 Some{E.SHW{}}
11 case "HW":
12 Some{E.HW{}}
13 case _:
14 None{}
15
16def read_task(value: String) -> Maybe<&2, E.Task>:
17 match value:
18 case "DISTANCE":
19 Some{E.Distance{}}
20 case "LOC":
21 Some{E.Locations{}}
22 case "PATH":
23 Some{E.Path{}}
24 case _:
25 None{}
26
27def read_format(value: String) -> Maybe<&2, E.CigarFormat>:
28 match value:
29 case "STANDARD":
30 Some{E.Standard{}}
31 case "EXTENDED":
32 Some{E.Extended{}}
33 case _:
34 None{}
35
36def bounded_threshold(value: Nat, valid: Bool) -> Maybe<&2, E.Threshold>:
37 match valid:
38 case True{}:
39 Some{E.MaxDistance{value}}
40 case False{}:
41 None{}
42
43def read_threshold(value: String) -> Maybe<&2, E.Threshold>:
44 match value:
45 case "-1":
46 Some{E.Unlimited{}}
47 case _:
48 do Maybe<&2, E.Threshold>:
49 +maximum : Nat <- Nat.read(value)
50 bounded_threshold(maximum, Nat.is_le(maximum, 2147483647n))
51
52def read_pairs(value: String) -> Maybe<&2, List<&2, E.EqualityPair>>:
53 match value:
54 case SNil{}:
55 Some{Nil{}}
56 case SCon{_, SNil{}}:
57 None{}
58 case SCon{first, SCon{second, tail}}:
59 do Maybe<&2, List<&2, E.EqualityPair>>:
60 pairs : List<&2, E.EqualityPair> <- read_pairs(tail)
61 return E.EqualityPair{first, second} <> pairs
62
63def parse(mode: String, task: String, threshold: String, pairs: String,
64 format: String) -> Maybe<&2, E.AlignConfig>:
65 do Maybe<&2, E.AlignConfig>:
66 m : E.Mode <- read_mode(mode)
67 t : E.Task <- read_task(task)
68 k : E.Threshold <- read_threshold(threshold)
69 eq : List<&2, E.EqualityPair> <- read_pairs(pairs)
70 c : E.CigarFormat <- read_format(format)
71 return E.AlignConfig{m, t, k, eq, c}
72
73def respond(~align: String -> String -> E.AlignConfig -> E.AlignResult,
74 query: String, target: String, config: Maybe<&2, E.AlignConfig>,
75 status: CLI.InputStatus) -> IO(Unit):
76 match config status:
77 case None{} _:
78 IO.die(Unit, 2, "Invalid alignment configuration")
79 case Some{value} CLI.Supported{}:
80 IO.print(E.result_show(align(query, target, value)))
81 case _ CLI.NonAscii{}:
82 IO.die(Unit, 2, "Sequences and equality pairs must contain only non-NUL ASCII characters")
83 case _ CLI.TooLong{}:
84 IO.die(Unit, 2, "Sequence or equality-pair length exceeds maximum of 4096 ASCII characters")
85
86def run(~align: String -> String -> E.AlignConfig -> E.AlignResult,
87 args: List<String>) -> IO(Unit):
88 match args:
89 case _ <> "--config" <> mode <> task <> threshold <> +pairs <> format <> +query <> +target <> Nil{}:
90 respond(~align, query, target, parse(mode, task, threshold, pairs, format),
91 CLI.combine(CLI.validate(query, target), CLI.scan(pairs, CLI.max_sequence_length())))
92 case _:
93 IO.die(Unit, 2, "Expected QUERY TARGET or --config MODE TASK K PAIRS CIGAR QUERY TARGET")