Temporal modeling, idempotency keys, and decision tracking
| Tier | foundation |
| Role | unclassified (baselined) |
| Path | crates/foundation/decisioning |
| Edition | 2021 |
| Targets | foundation_decisioning, idempotency_store, idempotency_store_pg |
| Public items | 75 across 6 modules |
| Tests | 57 |
What it is for
# foundation-decisioning
Temporal modeling, idempotency keys, and audit-grade decision tracking.
Core Concepts
- Bi-temporal semantics:
effective_at(business time) vsrecorded_at(system time) - Idempotency keys: Prevent duplicate operations from retries
- Idempotency store: A fenced idempotency register with replay (see below)
- Decision records: Audit trail for who decided what, when, and why
- Effective dating: Model time-bounded validity periods
Idempotency: a fenced register, NOT exactly-once
IdempotencyStore atomically claims a key before an external effect and replays the first result on a duplicate, so a retry never double-fires and always returns the original outcome. It is honestly an idempotency register with fenced ownership + replay, NOT an exactly-once effect library crate: the crash gap (the effect commits, then the process dies before complete) is unclosable here. True exactly-once needs downstream idempotency, a transactional outbox, atomic mutation-plus-complete in one database, or external-operation-id reconciliation. See store for the full contract.
Example
use foundation_decisioning::{Decision, IdempotencyKey, IdempotencyState, actions};
use serde_json::json;
use uuid::Uuid;
// Idempotency key for deduplication
let mut key = IdempotencyKey::new("basket_commit", "basket-123");
key.start_processing();
// ... do work ...
key.mark_succeeded(json!({"order_id": "order-456"}));
// Decision record for audit trail
let decision = Decision::builder()
.actor(Uuid::new_v4())
.target("loans.Application", "app-789")
.action(actions::APPROVE)
.snapshot(json!({"credit_score": 750}))
.outcome(json!({"loan_id": "loan-101"}))
.build();
Capabilities
actions (other)
Standard decision action constants.
| Item |
|---|
pub const COMMIT: & str |
pub const APPROVE: & str |
pub const REJECT: & str |
pub const REVERSE: & str |
pub const CANCEL: & str |
pub const SUBMIT: & str |
pub const RETURN: & str |
pub const ESCALATE: & str |
pub const DELEGATE: & str |
pub const OVERRIDE: & str |
pub const WAIVE: & str |
pub const FINALIZE: & str |
Decision
Decision model for audit-grade decision tracking.
| Item |
|---|
pub struct Decision |
Decision :: fn builder() -> DecisionBuilder |
Decision :: fn effective_at(& self) -> DateTime <Utc> |
Decision :: fn recorded_at(& self) -> DateTime <Utc> |
Decision :: fn id(& self) -> Uuid |
DecisionBuilder
Decision model for audit-grade decision tracking.
| Item |
|---|
pub struct DecisionBuilder |
DecisionBuilder :: fn new() -> Self |
DecisionBuilder :: fn effective_at(mut self, timestamp : DateTime <Utc>) -> Self |
DecisionBuilder :: fn actor(mut self, id : Uuid) -> Self |
DecisionBuilder :: fn on_behalf_of(mut self, id : Uuid) -> Self |
DecisionBuilder :: fn authority_context(mut self, context : JsonValue) -> Self |
DecisionBuilder :: fn target(mut self, target_type : impl Into <String>, target_id : impl Into <String>) -> Self |
DecisionBuilder :: fn action(mut self, action : impl Into <String>) -> Self |
DecisionBuilder :: fn snapshot(mut self, snapshot : JsonValue) -> Self |
DecisionBuilder :: fn outcome(mut self, outcome : JsonValue) -> Self |
DecisionBuilder :: fn build(self) -> Decision |
DecisioningError
Error types for decisioning.
| Item |
|---|
pub enum DecisioningError |
IdempotencyKey:IdempotencyKey
Idempotency key for preventing duplicate operations.
| Item |
|---|
pub struct IdempotencyKey |
IdempotencyKey:cached
Idempotency key for preventing duplicate operations.
| Item |
|---|
IdempotencyKey :: fn cached_response(& self) -> Option <& JsonValue> |
IdempotencyKey:expires
Idempotency key for preventing duplicate operations.
| Item |
|---|
IdempotencyKey :: fn expires_in(mut self, duration : Duration) -> Self |
IdempotencyKey :: fn expires_at(mut self, timestamp : DateTime <Utc>) -> Self |
IdempotencyKey:id
Idempotency key for preventing duplicate operations.
| Item |
|---|
IdempotencyKey :: fn id(& self) -> Uuid |
IdempotencyKey:is
Idempotency key for preventing duplicate operations.
| Item |
|---|
IdempotencyKey :: fn is_stale_lock(& self, timeout : Duration) -> bool |
IdempotencyKey :: fn is_expired(& self) -> bool |
IdempotencyKey :: fn is_terminal_cached(& self) -> bool |
IdempotencyKey :: fn is_reclaimable_at(& self, timeout : Duration, now : DateTime <Utc>) -> bool |
IdempotencyKey:mark
Idempotency key for preventing duplicate operations.
| Item |
|---|
IdempotencyKey :: fn mark_succeeded(& mut self, response : JsonValue) |
IdempotencyKey :: fn mark_succeeded_with_result(& mut self, response : JsonValue, result_type : impl Into <String>, result_id : impl Into <String>,) |
IdempotencyKey :: fn mark_failed(& mut self, code : impl Into <String>, message : impl Into <String>) |
IdempotencyKey:new
Idempotency key for preventing duplicate operations.
| Item |
|---|
IdempotencyKey :: fn new(scope : impl Into <String>, key : impl Into <String>) -> Self |
IdempotencyKey:reset
Idempotency key for preventing duplicate operations.
| Item |
|---|
IdempotencyKey :: fn reset_for_retry(& mut self) |
IdempotencyKey:start
Idempotency key for preventing duplicate operations.
| Item |
|---|
IdempotencyKey :: fn start_processing(& mut self) |
IdempotencyKey:with
Idempotency key for preventing duplicate operations.
| Item |
|---|
IdempotencyKey :: fn with_request_hash(mut self, hash : impl Into <String>) -> Self |
IdempotencyState
Idempotency key for preventing duplicate operations.
| Item |
|---|
pub enum IdempotencyState |
IdempotencyState :: fn as_str(& self) -> & 'static str |
IdempotencyState :: fn parse(s : & str) -> Option <Self> |
IdempotencyState :: fn allows_retry(& self) -> bool |
IdempotencyState :: fn is_terminal(& self) -> bool |
IdempotencyState :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result |
OutcomeClass
Idempotency key for preventing duplicate operations.
| Item |
|---|
pub enum OutcomeClass |
OutcomeClass :: fn as_str(self) -> & 'static str |
OutcomeClass :: fn parse(s : & str) -> Option <Self> |
OutcomeClass :: fn is_cacheable(self) -> bool |
RecoveryPolicy
Idempotency key for preventing duplicate operations.
| Item |
|---|
pub enum RecoveryPolicy |
RecoveryPolicy :: fn as_str(self) -> & 'static str |
RecoveryPolicy :: fn parse(s : & str) -> Option <Self> |
store (other)
Fenced idempotency register with replay (harvest of the corpus-wide
| Item |
|---|
pub const DEFAULT_STALE_SECONDS: i64 |
ClaimOutcome
Fenced idempotency register with replay (harvest of the corpus-wide
| Item |
|---|
pub enum ClaimOutcome |
ClaimTicket
Fenced idempotency register with replay (harvest of the corpus-wide
| Item |
|---|
pub struct ClaimTicket |
ClaimTicket :: fn scope(& self) -> & str |
ClaimTicket :: fn key(& self) -> & str |
ClaimTicket :: fn claim_token(& self) -> Uuid |
ConflictDecision
Fenced idempotency register with replay (harvest of the corpus-wide
| Item |
|---|
pub enum ConflictDecision |
fn classify_conflict(existing : & IdempotencyKey, incoming_request_hash : Option <& str>, policy : RecoveryPolicy, timeout : Duration, now : DateTime <Utc>,) -> Result <ConflictDecision, DecisioningError> |
IdempotencyStore
Fenced idempotency register with replay (harvest of the corpus-wide
| Item |
|---|
pub struct IdempotencyStore |
IdempotencyStore :: fn new(pool : PgPool) -> Self |
IdempotencyStore :: fn with_stale_after(mut self, timeout : Duration) -> Self |
IdempotencyStore :: async fn claim(& self, scope : & str, key : & str, request_hash : Option <& str>, policy : RecoveryPolicy,) -> Result <ClaimOutcome, DecisioningError> |
IdempotencyStore :: async fn complete(& self, ticket : & ClaimTicket, outcome_class : OutcomeClass, response : Option <& JsonValue>,) -> Result <(), DecisioningError> |
IdempotencyStore :: async fn reclaim_stale(& self, scope : & str, timeout : Duration,) -> Result <ReclaimReport, DecisioningError> |
ReclaimReport
Fenced idempotency register with replay (harvest of the corpus-wide
| Item |
|---|
pub struct ReclaimReport |
EffectiveDated
Temporal modeling traits.
| Item |
|---|
pub trait EffectiveDated |
TimeSemantics
Temporal modeling traits.
| Item |
|---|
pub trait TimeSemantics |
How to use it
From this crate's own rustdoc:
use foundation_decisioning::{Decision, IdempotencyKey, IdempotencyState, actions};
use serde_json::json;
use uuid::Uuid;
// Idempotency key for deduplication
let mut key = IdempotencyKey::new("basket_commit", "basket-123");
key.start_processing();
// ... do work ...
key.mark_succeeded(json!({"order_id": "order-456"}));
// Decision record for audit trail
let decision = Decision::builder()
.actor(Uuid::new_v4())
.target("loans.Application", "app-789")
.action(actions::APPROVE)
.snapshot(json!({"credit_score": 750}))
.outcome(json!({"loan_id": "loan-101"}))
.build();
Module structure
foundation_decisioning
actionsdecisionerroridempotencystoretemporal
flowchart TD n_foundation_decisioning["foundation_decisioning"] n_foundation_decisioning --> n_actions["actions"] n_foundation_decisioning --> n_decision["decision"] n_foundation_decisioning --> n_error["error"] n_foundation_decisioning --> n_idempotency["idempotency"] n_foundation_decisioning --> n_store["store"] n_foundation_decisioning --> n_temporal["temporal"]
Public surface
`actions`
| Item | What it is |
|---|---|
pub const COMMIT: & str | Commit/finalize something. |
pub const APPROVE: & str | Approve a request. |
pub const REJECT: & str | Reject a request. |
pub const REVERSE: & str | Reverse a previous decision. |
pub const CANCEL: & str | Cancel something. |
pub const SUBMIT: & str | Submit for review. |
pub const RETURN: & str | Return for version. |
pub const ESCALATE: & str | Escalate to higher authority. |
pub const DELEGATE: & str | Delegate to another person. |
pub const OVERRIDE: & str | Override a rule or limit. |
pub const WAIVE: & str | Waive a requirement. |
pub const FINALIZE: & str | Finalize/close. |
`decision`
| Item | What it is |
|---|---|
pub struct Decision | An audit-grade decision record |
Decision :: fn builder() -> DecisionBuilder | Create a new decision builder. |
Decision :: fn effective_at(& self) -> DateTime <Utc> | — |
Decision :: fn recorded_at(& self) -> DateTime <Utc> | — |
Decision :: fn id(& self) -> Uuid | — |
pub struct DecisionBuilder | Builder for Decision. |
DecisionBuilder :: fn new() -> Self | Create a new builder. |
DecisionBuilder :: fn effective_at(mut self, timestamp : DateTime <Utc>) -> Self | Set when the decision was made (defaults to now). |
DecisionBuilder :: fn actor(mut self, id : Uuid) -> Self | Set the actor who made the decision. |
DecisionBuilder :: fn on_behalf_of(mut self, id : Uuid) -> Self | Set delegation (decision made on behalf of another user). |
DecisionBuilder :: fn authority_context(mut self, context : JsonValue) -> Self | Set authority context (role snapshot at decision time). |
DecisionBuilder :: fn target(mut self, target_type : impl Into <String>, target_id : impl Into <String>) -> Self | Set the target object. |
DecisionBuilder :: fn action(mut self, action : impl Into <String>) -> Self | Set the action. |
DecisionBuilder :: fn snapshot(mut self, snapshot : JsonValue) -> Self | Set the evidence snapshot. |
DecisionBuilder :: fn outcome(mut self, outcome : JsonValue) -> Self | Set the outcome/result. |
DecisionBuilder :: fn build(self) -> Decision | Build the decision |
`error`
| Item | What it is |
|---|---|
pub enum DecisioningError | Errors that can occur in decisioning operations. |
`idempotency`
| Item | What it is |
|---|---|
pub enum IdempotencyState | State of an idempotency key. |
IdempotencyState :: fn as_str(& self) -> & 'static str | Get the string representation. |
IdempotencyState :: fn parse(s : & str) -> Option <Self> | Parse from string. |
IdempotencyState :: fn allows_retry(& self) -> bool | Check if this state allows retry. |
IdempotencyState :: fn is_terminal(& self) -> bool | Check if this state indicates completion. |
IdempotencyState :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result | — |
pub enum RecoveryPolicy | How a stale or interrupted claim may be recovered |
RecoveryPolicy :: fn as_str(self) -> & 'static str | Database string form. |
RecoveryPolicy :: fn parse(s : & str) -> Option <Self> | Parse the database string form. |
pub enum OutcomeClass | Terminal outcome classification, recorded at completion |
OutcomeClass :: fn as_str(self) -> & 'static str | Database string form. |
OutcomeClass :: fn parse(s : & str) -> Option <Self> | Parse the database string form. |
OutcomeClass :: fn is_cacheable(self) -> bool | Whether this outcome may be cached and replayed on a duplicate claim |
pub struct IdempotencyKey | Idempotency key for preventing duplicate operations |
IdempotencyKey :: fn new(scope : impl Into <String>, key : impl Into <String>) -> Self | Create a new idempotency key. |
IdempotencyKey :: fn with_request_hash(mut self, hash : impl Into <String>) -> Self | Builder: set request hash. |
IdempotencyKey :: fn expires_in(mut self, duration : Duration) -> Self | Builder: set expiration. |
IdempotencyKey :: fn expires_at(mut self, timestamp : DateTime <Utc>) -> Self | Builder: set expiration timestamp. |
IdempotencyKey :: fn start_processing(& mut self) | Transition to Processing state. |
IdempotencyKey :: fn mark_succeeded(& mut self, response : JsonValue) | Mark as succeeded with cached result. |
IdempotencyKey :: fn mark_succeeded_with_result(& mut self, response : JsonValue, result_type : impl Into <String>, result_id : impl Into <String>,) | Mark as succeeded with result reference. |
IdempotencyKey :: fn mark_failed(& mut self, code : impl Into <String>, message : impl Into <String>) | Mark as failed with error info. |
IdempotencyKey :: fn reset_for_retry(& mut self) | Reset for retry (from Failed state). |
IdempotencyKey :: fn is_stale_lock(& self, timeout : Duration) -> bool | Check if the lock appears stale (processing for too long). |
IdempotencyKey :: fn is_expired(& self) -> bool | Check if this key has expired. |
IdempotencyKey :: fn cached_response(& self) -> Option <& JsonValue> | Get the cached response if succeeded. |
IdempotencyKey :: fn is_terminal_cached(& self) -> bool | Whether a terminal, cached outcome exists that must be replayed on a duplicate claim rather than re-fired |
IdempotencyKey :: fn is_reclaimable_at(& self, timeout : Duration, now : DateTime <Utc>) -> bool | Whether this row is eligible to be reclaimed at now: a stale processing lock, or a retryable failure |
IdempotencyKey :: fn id(& self) -> Uuid | — |
`store`
| Item | What it is |
|---|---|
pub const DEFAULT_STALE_SECONDS: i64 | Default stale-lock timeout: a processing claim older than this is a candidate for reclaim/adjudication (never before — a fresh lock has a live worker). |
pub enum ConflictDecision | The decision made when a claim collides with an existing row |
pub struct ClaimTicket | Proof that this worker owns this idempotency key at this claim epoch |
ClaimTicket :: fn scope(& self) -> & str | The operation scope. |
ClaimTicket :: fn key(& self) -> & str | The idempotency key. |
ClaimTicket :: fn claim_token(& self) -> Uuid | The ownership token this claim holds. |
pub enum ClaimOutcome | The result of an IdempotencyStore::claim attempt. |
pub struct ReclaimReport | The result of a IdempotencyStore::reclaim_stale sweep. |
fn classify_conflict(existing : & IdempotencyKey, incoming_request_hash : Option <& str>, policy : RecoveryPolicy, timeout : Duration, now : DateTime <Utc>,) -> Result <ConflictDecision, DecisioningError> | Decide what to do when a claim collides with an existing row |
pub struct IdempotencyStore | A Postgres-backed idempotency register with fenced ownership + replay. |
IdempotencyStore :: fn new(pool : PgPool) -> Self | Create a store with the default stale-lock timeout. |
IdempotencyStore :: fn with_stale_after(mut self, timeout : Duration) -> Self | Override how long a processing claim may be held before it is a candidate for reclaim/adjudication |
IdempotencyStore :: async fn claim(& self, scope : & str, key : & str, request_hash : Option <& str>, policy : RecoveryPolicy,) -> Result <ClaimOutcome, DecisioningError> | Atomically claim (scope, key) before firing an external effect |
IdempotencyStore :: async fn complete(& self, ticket : & ClaimTicket, outcome_class : OutcomeClass, response : Option <& JsonValue>,) -> Result <(), DecisioningError> | Complete the claimed operation, caching the result for replay |
IdempotencyStore :: async fn reclaim_stale(& self, scope : & str, timeout : Duration,) -> Result <ReclaimReport, DecisioningError> | Sweep stale processing rows in a scope and classify each by its snapshotted recovery policy |
`temporal`
| Item | What it is |
|---|---|
pub trait TimeSemantics | Trait for records with bi-temporal time semantics |
pub trait EffectiveDated | Trait for records with validity periods |
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
DecisioningError | error::DecisioningError |
HasId | foundation_basemodels::HasId |
{Decision,DecisionBuilder} | decision::{Decision,DecisionBuilder} |
{EffectiveDated,TimeSemantics} | temporal::{EffectiveDated,TimeSemantics} |
{IdempotencyKey,IdempotencyState,OutcomeClass,RecoveryPolicy} | idempotency::{IdempotencyKey,IdempotencyState,OutcomeClass,RecoveryPolicy} |
{classify_conflict,ClaimOutcome,ClaimTicket,ConflictDecision,IdempotencyStore,ReclaimReport,DEFAULT_STALE_SECONDS,} | store::{classify_conflict,ClaimOutcome,ClaimTicket,ConflictDecision,IdempotencyStore,ReclaimReport,DEFAULT_STALE_SECONDS,} |
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-encounter-vocabulary, foundation-fs-metadata, foundation-i18n, … (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/decisioning |
| Vocabulary in force (lexicon) | current |
Dependencies
Runtime, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `foundation-basemodels` | foundation | no | always |
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
chrono | ^0.4 | serde | no | always |
serde | ^1 | derive | no | always |
serde_json | ^1 | — | no | always |
sqlx | ^0.8 | runtime-tokio, postgres, chrono, uuid, json | no | always |
thiserror | ^2 | — | no | always |
tokio | ^1 | full | no | always |
uuid | ^1 | v4, v7, serde, js | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
tokio-test | ^0.4 | — | no | always |
Build. None.
Depended on by. Nothing in this workspace.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR SELF["foundation-decisioning"] SELF -->|runtime| n_foundation_basemodels["foundation-basemodels"] 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_decisioning | `src/lib.rs` |
| test | idempotency_store | `tests/idempotency_store.rs` |
| test | idempotency_store_pg | `tests/idempotency_store_pg.rs` |
Error model
| Error type | Named by |
|---|---|
DecisioningError | classify_conflict |
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | yes |
| async runtime | yes |
| database access | yes |
| 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
No workspace crate depends on this one.
Verification
| Kind | Count |
|---|---|
| Unit tests | 46 |
| Integration tests | 11 |
| Examples | 0 |
| Doctests | 1 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
actions | 12 | 0 | 0 |
decision | 2 | 0 | 0 |
error | 1 | 0 | 0 |
idempotency | 4 | 0 | 0 |
store | 7 | 0 | 0 |
temporal | 2 | 0 | 0 |
What the tests establish, by name:
a_different_request_hash_is_rejected_never_replayed—tests/idempotency_store.rsa_stale_non_idempotent_lock_parks_and_is_never_auto_stolen—tests/idempotency_store.rsa_succeeded_key_replays_and_never_refires—tests/idempotency_store.rsfresh_live_lock_is_reported_in_progress_never_reclaimed—tests/idempotency_store.rsonly_terminal_outcomes_are_cacheable_transient_failures_stay_retryable—tests/idempotency_store.rsa_completed_success_replays_its_snapshot—tests/idempotency_store_pg.rsa_reclaimed_worker_cannot_complete_over_its_replacement—tests/idempotency_store_pg.rsa_stale_non_idempotent_lock_parks_for_adjudication—tests/idempotency_store_pg.rsa_transient_failure_stays_retryable—tests/idempotency_store_pg.rsreclaim_stale_parks_non_idempotent_and_resets_retry_safe—tests/idempotency_store_pg.rstwo_concurrent_claims_yield_exactly_one_claimed—tests/idempotency_store_pg.rstest_authority_actions—src/actions.rstest_reversal_actions—src/actions.rstest_workflow_actions—src/actions.rstest_decision_builder_basic—src/decision.rstest_decision_builder_full—src/decision.rstest_decision_default_timestamps—src/decision.rstest_decision_defaults—src/decision.rstest_decision_has_id_trait—src/decision.rstest_decision_serialization—src/decision.rstest_decision_time_semantics—src/decision.rstest_backdate_too_far_error—src/error.rstest_duplicate_request_error—src/error.rstest_in_flight_error—src/error.rstest_invalid_validity_error—src/error.rstest_idempotency_key_cached_response—src/idempotency.rstest_idempotency_key_expires_in—src/idempotency.rstest_idempotency_key_has_id_trait—src/idempotency.rstest_idempotency_key_is_stale_lock—src/idempotency.rstest_idempotency_key_mark_failed—src/idempotency.rs- _… 27 more_
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 70 | 75 |
Public modules with a //! block | 6 | 6 |
pie showData
title Public items with rustdoc
"Documented" : 70
"No rustdoc detected" : 5
Metrics
| Metric | Value |
|---|---|
| Rust source files | 7 |
| Source lines | 2184 |
| Code lines | 1440 |
| Public API items | 75 |
| Public modules | 6 |
| Tests | 57 |
| Examples | 0 |
| Cargo features | 0 |
| Direct runtime dependencies | 8 |
| Workspace reverse dependencies | 0 |
pie showData
title Public API by kind
"constant" : 13
"enum" : 6
"function" : 1
"method" : 47
"struct" : 6
"trait" : 2
pie showData
title Rust source composition
"Code" : 1440
"Blank or comment" : 744
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.