Provider-agnostic text translation: Translator trait, ordered fallback chain, content-addressed cache key (composes infrastructure-ai)
| Tier | infrastructure |
| Role | unclassified (baselined) |
| Path | crates/infrastructure/translate |
| Edition | 2021 |
| Targets | infrastructure_translate |
| Public items | 16 across 0 modules |
| Tests | 22 |
What it is for
infrastructure-translate — provider-agnostic text translation.
Sprint 0.65. A generic translation engine lifted up so application-cms, baloo, happydiving, and spanish-novels share one implementation instead of each re-authoring it. This crate owns the Translator trait, the ordered FallbackTranslator, is_garbage detection, normalize_source, and content-addressed cache_key derivation.
I/O-bound backends (AiTranslator over infrastructure-ai, MyMemoryTranslator HTTP) and the Postgres translation cache land in later tasks under the Gate 2.1 DB/IO exception — this slice is the pure, decidable core.
Capabilities
crate root
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
fn normalize_source(s : & str) -> String |
fn is_garbage(source : & str, output : & str) -> bool |
fn cache_key(req : & TranslateRequest, provider : & ProviderId, prompt_version : u32) -> String |
CacheScope
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
pub enum CacheScope |
FallbackTranslator
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
pub struct FallbackTranslator |
FallbackTranslator :: fn new(translators : Vec <Box <dyn Translator>>) -> Self |
FallbackTranslator :: fn id(& self) -> ProviderId |
FallbackTranslator :: async fn translate(& self, req : & TranslateRequest) -> Result <TranslateOutput, TranslateError> |
Provenance
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
pub struct Provenance |
ProviderId
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
pub struct ProviderId |
ProviderId :: fn new(family : impl Into <String>, model : impl Into <String>) -> Self |
Register
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
pub enum Register |
TranslateError
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
pub enum TranslateError |
TranslateOutput
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
pub struct TranslateOutput |
TranslateRequest
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
pub struct TranslateRequest |
Translator
infrastructure-translate — provider-agnostic text translation.
| Item |
|---|
pub trait Translator |
How to use it
No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.
Module structure
No public modules: the crate root is its whole surface.
Public surface
`crate root`
| Item | What it is |
|---|---|
pub enum Register | Formality/register of the requested translation |
pub enum CacheScope | Cache isolation boundary |
pub struct ProviderId | Provider family + exact model identity |
ProviderId :: fn new(family : impl Into <String>, model : impl Into <String>) -> Self | — |
pub struct Provenance | Provenance recorded with every translation output. |
pub struct TranslateRequest | A request to translate one block of text. |
pub struct TranslateOutput | A successful translation plus its provenance. |
pub enum TranslateError | Failure modes of a translation attempt. |
pub trait Translator | A translation backend. |
fn normalize_source(s : & str) -> String | Collapse internal whitespace runs to single spaces and trim the ends, so a cache key is stable across cosmetic whitespace differences in the source. |
fn is_garbage(source : & str, output : & str) -> bool | Detect unusable translator output: empty/whitespace, an echo of the source, or markdown code-fence leakage |
fn cache_key(req : & TranslateRequest, provider : & ProviderId, prompt_version : u32) -> String | Content-addressed cache key over every dimension that can change the output (Gate 1.5 Q2: scope, provider+model, prompt_version, lang pair, glossary, register, normalized source) |
pub struct FallbackTranslator | Tries each translator in order, skipping any that errors or returns garbage, returning the first usable output |
FallbackTranslator :: fn new(translators : Vec <Box <dyn Translator>>) -> Self | — |
FallbackTranslator :: fn id(& self) -> ProviderId | — |
FallbackTranslator :: async fn translate(& self, req : & TranslateRequest) -> Result <TranslateOutput, TranslateError> | — |
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
AiTranslator | ai::AiTranslator |
MyMemoryTranslator | mymemory::MyMemoryTranslator |
PgTranslationCache | cache::PgTranslationCache |
{CachingTranslator,TranslationCache} | cache::{CachingTranslator,TranslationCache} |
{is_stale,source_sha256,Origin} | origin::{is_stale,source_sha256,Origin} |
{mymemory_url,parse_mymemory_response} | mymemory::{mymemory_url,parse_mymemory_response} |
Boundary
Depends on no other workspace tier.
Shares tier infrastructure with 82 other crates: infrastructure-acquire, infrastructure-adapters-google-calendar, infrastructure-adapters-google-gmail, infrastructure-adapters-google-places, infrastructure-adapters-google-trends, infrastructure-adapters-shodan, infrastructure-adapters-yelp, infrastructure-agent, … (82 total).
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | infrastructure |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/infrastructure/translate |
| Vocabulary in force (lexicon) | current |
Dependencies
Runtime, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `infrastructure-ai` | infrastructure | no | always |
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
async-trait | ^0.1 | — | no | always |
hex | ^0.4 | — | no | always |
reqwest | ^0.12 | json | yes | always |
serde | ^1 | derive | no | always |
serde_json | ^1 | — | no | always |
sha2 | ^0.10 | — | no | always |
sqlx | ^0.8 | runtime-tokio, postgres, chrono, uuid, json | yes | always |
thiserror | ^2 | — | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
tokio | ^1 | full | no | always |
tokio-test | ^0.4 | — | no | always |
Build. None.
Depended on by. 1 workspace crate.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_application_cms["application-cms"] -->|uses| SELF SELF["infrastructure-translate"] SELF -->|runtime| n_infrastructure_ai["infrastructure-ai"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
| Feature | Enables | On by default |
|---|---|---|
default | — | yes |
http | dep:reqwest | no |
postgres | dep:sqlx | no |
flowchart LR n_default["default"] n_http["http"] --> n_dep_reqwest["dep:reqwest"] n_postgres["postgres"] --> n_dep_sqlx["dep:sqlx"]
Targets
| Kind | Name | Source |
|---|---|---|
| lib | infrastructure_translate | `src/lib.rs` |
Error model
| Error type | Named by |
|---|---|
TranslateError | declared, no public signature returns it |
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | yes |
| async runtime | none detected |
| database access | yes |
| network I/O | yes |
| unsafe code | none detected |
| environment variables | none detected |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.
Related capabilities
1 workspace crate depends on this one: application-cms.
Verification
| Kind | Count |
|---|---|
| Unit tests | 22 |
| Integration tests | 0 |
| Examples | 0 |
| Doctests | 0 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
crate root | 12 | 0 | 8 |
What the tests establish, by name:
build_request_includes_langs_register_and_source—src/ai.rsparse_strips_fences_and_labels—src/ai.rsprovider_error_maps_to_translate_error—src/ai.rstranslate_over_provider_yields_output_with_provenance—src/ai.rsdifferent_request_misses_and_calls_again—src/cache.rsrepeat_request_is_served_from_cache—src/cache.rscache_key_changes_with_every_dimension—src/lib.rscache_key_stable_across_whitespace—src/lib.rsfallback_all_fail_errors—src/lib.rsfallback_returns_first_good—src/lib.rsfallback_skips_error_then_succeeds—src/lib.rsfallback_skips_garbage_then_succeeds—src/lib.rsgarbage_detection—src/lib.rsnormalize_trims_and_collapses—src/lib.rsencode_query_percent_encodes_reserved—src/mymemory.rsparse_errors_on_empty_or_malformed—src/mymemory.rsparse_extracts_translated_text—src/mymemory.rsurl_has_query_and_langpair—src/mymemory.rsai_origin_always_overwritable—src/origin.rshuman_touched_only_overwritten_on_request—src/origin.rssource_hash_is_deterministic_hex—src/origin.rsstaleness_is_derived_from_hashes—src/origin.rs
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 12 | 16 |
Public modules with a //! block | 0 | 0 |
pie showData
title Public items with rustdoc
"Documented" : 12
"No rustdoc detected" : 4
Metrics
| Metric | Value |
|---|---|
| Rust source files | 5 |
| Source lines | 993 |
| Code lines | 797 |
| Public API items | 16 |
| Public modules | 0 |
| Tests | 22 |
| Examples | 0 |
| Cargo features | 3 |
| Direct runtime dependencies | 9 |
| Workspace reverse dependencies | 1 |
pie showData
title Public API by kind
"enum" : 3
"function" : 3
"method" : 4
"struct" : 5
"trait" : 1
pie showData
title Rust source composition
"Code" : 797
"Blank or comment" : 196
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.