Shared host/port/TLS-mode/credentials -> lettre AsyncSmtpTransport<Tokio1Executor> builder, used by infrastructure-smtp and infrastructure-communication
| Tier | foundation |
| Role | unclassified (baselined) |
| Path | crates/foundation/smtp-transport |
| Edition | 2021 |
| Targets | foundation_smtp_transport |
| Public items | 2 across 0 modules |
| Tests | 6 |
What it is for
# foundation-smtp-transport
One function: host/port/TLS-mode/credentials -> a lettre AsyncSmtpTransport<Tokio1Executor>. Extracted (Gate 4 review finding, Sprint 3.45 follow-up) because infrastructure-smtp::SmtpSender::new (crates/infrastructure/smtp/src/sender.rs) and infrastructure-communication::smtp::SmtpOutboundSender::new (crates/infrastructure/communication/src/smtp.rs) had independently reimplemented the identical lettre 0.11 transport-builder logic (tokio1-native-tls, same version in both crates already) — two copies meant a TLS/timeout fix to one would not propagate to the other.
Why this crate, not a direct dependency between the two
Both infrastructure-smtp and infrastructure-communication are infrastructure-layer (docs/architecture/layers.toml). This workspace's layer rule (tools-xtask/src/main.rs::allowed_deps) is stricter than "depend only on a lower layer" — a non-tools library crate may depend on foundation ONLY, full stop, even same-layer imports are a violation with no exception list entry available for a new edge. So neither infrastructure crate may depend on the other; the only legal shared home for logic both need is a foundation-layer crate. Hence this crate, not (for example) infrastructure-communication depending on infrastructure-smtp directly.
No I/O happens in build_smtp_transport itself — lettre's SMTP transport connects lazily per send. The one exception is that AsyncSmtpTransportBuilder::build() spawns the connection pool's background task (the pool feature lettre defaults to), which needs a live Tokio reactor even though no network I/O happens yet — same reason both call sites' own construction tests are #tokio::test, not plain #test.
Capabilities
TlsMode
# foundation-smtp-transport
| Item |
|---|
pub enum TlsMode |
fn build_smtp_transport(host : & str, port : u16, tls_mode : TlsMode, credentials : Option <Credentials>,) -> Result <AsyncSmtpTransport <Tokio1Executor>, lettre::transport::smtp::Error> |
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 TlsMode | How to establish transport security for the SMTP connection |
fn build_smtp_transport(host : & str, port : u16, tls_mode : TlsMode, credentials : Option <Credentials>,) -> Result <AsyncSmtpTransport <Tokio1Executor>, lettre::transport::smtp::Error> | Build an AsyncSmtpTransport from host/port/TLS-mode/credentials |
No pub use re-exports: every item above is declared in this crate.
Boundary
Depends on no other workspace tier.
Shares tier foundation with 27 other crates: foundation-audit-log, foundation-basemodels, foundation-bounded-io, foundation-conversation-closure, foundation-crypto-sign, foundation-decisioning, foundation-encounter-vocabulary, foundation-fs-metadata, … (27 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) | foundation |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/foundation/smtp-transport |
| Vocabulary in force (lexicon) | current |
Dependencies
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
lettre | ^0.11 | tokio1-native-tls | no | always |
serde | ^1 | derive | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
serde_json | ^1 | — | no | always |
tokio | ^1 | full | no | always |
tokio-test | ^0.4 | — | no | always |
Build. None.
Depended on by. 2 workspace crates.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_infrastructure_communication["infrastructure-communication"] -->|uses| SELF n_infrastructure_smtp["infrastructure-smtp"] -->|uses| SELF SELF["foundation-smtp-transport"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.
Targets
| Kind | Name | Source |
|---|---|---|
| lib | foundation_smtp_transport | `src/lib.rs` |
Error model
No public error type was detected: no public item declares a type named *Error, and no public signature returns one.
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | none detected |
| async runtime | none detected |
| database access | none detected |
| network I/O | none detected |
| 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
2 workspace crates depend on this one: infrastructure-communication, infrastructure-smtp.
Verification
| Kind | Count |
|---|---|
| Unit tests | 6 |
| 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 | 2 | 0 | 4 |
What the tests establish, by name:
builds_for_tls_mode_implicit_with_credentials_ses_shaped—src/lib.rsbuilds_for_tls_mode_none_no_credentials_local_relay—src/lib.rsbuilds_for_tls_mode_start_tls_with_credentials—src/lib.rstls_mode_defaults_to_start_tls—src/lib.rstls_mode_none_still_accepts_credentials—src/lib.rstls_mode_serializes_snake_case_and_round_trips—src/lib.rs
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 2 | 2 |
Public modules with a //! block | 0 | 0 |
pie showData
title Public items with rustdoc
"Documented" : 2
"No rustdoc detected" : 0
Metrics
| Metric | Value |
|---|---|
| Rust source files | 1 |
| Source lines | 166 |
| Code lines | 86 |
| Public API items | 2 |
| Public modules | 0 |
| Tests | 6 |
| Examples | 0 |
| Cargo features | 0 |
| Direct runtime dependencies | 2 |
| Workspace reverse dependencies | 2 |
pie showData
title Public API by kind
"enum" : 1
"function" : 1
pie showData
title Rust source composition
"Code" : 86
"Blank or comment" : 80
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.