1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//! Type-name constants and header helpers for fiberseq base modifications.
//!
//! Storage type names are spec MM mod codes (`"a"` for m6A, `"m"` for 5mC);
//! display labels in TSV output and CLI aliases use the fibertools-friendly
//! names (`"m6a"`, `"5mC"`).
//!
//! BAM tag I/O is owned by `utils::ma_io`; this module is purely a
//! constants + header-formatting helper module.
/// Annotation type name for m6A calls (spec MM mod code).
pub const M6A_TYPE: &str = "a";
/// Annotation type name for 5mC calls (spec MM mod code).
pub const CPG_TYPE: &str = "m";
/// True for annotation types whose on-disk source of truth is MM/ML.
/// Used to gate MA-tag emission (ma_io) and MM/ML encoding flips.
/// Canonical MM group header for an m6a call landing on `base` (read in
/// forward-strand orientation): `A+a` on A, `T-a` on T. `None` for any other
/// (type, base) pair.
///
/// m6a only — cpg (5mC) is never producer-synthesized; it travels the
/// read→write passthrough, which preserves the input's MM group verbatim, so
/// no canonical cpg header is ever needed here.
/// Decomposed form of [`canonical_header`]: the `(skip_base, strand)` an m6a
/// call serializes under (`("A", Forward)` on A, `("T", Reverse)` on T).
///
/// Producers must store these on the annotation — `name` = skip-base,
/// `strand` = strand — NOT the full header string (e.g. `"T-a"`) in `name`
/// with a `Strand::Forward` placeholder. The MM/ML writer derives the group's
/// `+`/`-` sign from `strand`, not from `name`, so a `Strand::Forward`
/// placeholder silently turns a minus-strand call (`T-a`) into `T+a`. This
/// mirrors the parse path, which stores the skip-base in `name` and the strand
/// in `strand`.
///
/// m6a only — cpg is passthrough (see [`canonical_header`]).