rtemis-a3
Rust implementation of the Amino Acid Annotation (A3) format — a structured JSON format for amino acid sequences with site, region, PTM, processing, and variant annotations.
Part of the rtemis-org/a3 monorepo, which provides A3 implementations in Python, TypeScript, R, Julia, and Rust.
[!NOTE] The Rust code contains extensive comments and documentation as an educational tool to help learn Rust.
Installation
Add to your Cargo.toml:
[]
= "0.1"
CLI
The a3 binary validates an A3 JSON file and prints a summary.
Install:
Usage:
Pass - as <FILE> to read from stdin.
Options:
| Flag | Description |
|---|---|
-l, --limit <N> |
Max sequence residues to display (default: 20) |
-q, --quiet |
Suppress all output; use exit code only |
-j, --json |
Output results in JSON format |
-D, --diagnose |
Full step-by-step diagnostic validation (all errors) |
-h, --help |
Print help |
-V, --version |
Print version |
Example — valid file:
$ a3 tau.json
✓ valid A3 1.0.0 https://schema.rtemis.org/a3/v1/schema.json
Sequence MAEPRQEFEVMEDHAGTYGL… (length = 441)
Annotations
├── site 2
├── region 1
├── ptm 3
├── processing —
└── variant 5
Metadata
├── UniProt ID P10636
├── Description Microtubule-associated protein tau
├── Reference —
└── Organism Homo sapiens
Example — invalid file:
$ a3 bad.json
✗ invalid
├── annotations.site.foo: position 999 is out of bounds for sequence of length 6 (must be 1–6)
└── annotations.region: annotation name must not be empty
Sequence MAEPRQ (length = 6)
...
Exit codes:
| Code | Meaning |
|---|---|
0 |
Valid |
1 |
Invalid (A3 validation errors) |
2 |
Error (bad arguments, file not found, JSON parse failure) |
Use --quiet for scripting:
if ; then
fi
Quick Start
use ;
let json = r#"{
"$schema": "https://schema.rtemis.org/a3/v1/schema.json",
"a3_version": "1.0.0",
"sequence": "MKTAYIAKQR",
"annotations": {
"site": { "Active site": { "index": [3, 5], "type": "activeSite" } },
"region": { "Repeat 1": { "index": [[1, 4]], "type": "" } },
"ptm": { "Phospho": { "index": [7], "type": "" } },
"processing": {},
"variant": [{ "position": 3, "from": "K", "to": "R" }]
},
"metadata": {
"uniprot_id": "P12345",
"description": "Example protein",
"reference": "",
"organism": "Homo sapiens"
}
}"#;
let a3 = a3_from_json.unwrap;
println!; // 10
println!; // compact JSON
println!; // pretty-printed
Parsing JSON
use ;
match a3_from_json
Querying
use ;
// 1-based position; returns Option<char>
if let Some = residue_at
// All variant records at a position
let vars = variants_at;
Wire Format
All five annotation families are always present in output. Each annotation
entry is { index, type } — bare arrays are rejected. Positions are
1-based, sorted, and deduplicated. Ranges are [start, end] pairs
(start < end), sorted by start; overlapping ranges are rejected.
API
Parsing and serialization
| Function | Description |
|---|---|
a3_from_json(text: &str) |
Parse a JSON string into a validated A3 |
a3_to_json(a3: &A3, indent: Option<usize>) |
Serialize to JSON; None = compact, Some(n) = n-space indent |
Queries
| Function | Description |
|---|---|
residue_at(a3: &A3, position: u32) |
Residue at a 1-based position; None if out of bounds |
variants_at<'a>(a3: &'a A3, position: u32) |
All variant records at a 1-based position |
Type hierarchy
A3
├── sequence: String
├── annotations: Annotations
│ ├── site: HashMap<String, SiteEntry> (position index)
│ ├── region: HashMap<String, RegionEntry> (range index)
│ ├── ptm: HashMap<String, FlexEntry> (position or range index)
│ ├── processing: HashMap<String, FlexEntry> (position or range index)
│ └── variant: Vec<VariantRecord>
└── metadata: Metadata
├── uniprot_id, description, reference, organism: String
A3Index is an enum that holds either Positions(Vec<u32>) or Ranges(Vec<[u32; 2]>),
used as the index type inside FlexEntry.
Errors
All violations are collected before returning — you see every problem at once, not just the first one.