olai-store
Generic, TAO-inspired resource store for typed objects and associations.
olai-store provides the async storage abstractions used by services built with the
Trestle framework. It defines the core
traits and types for a graph-based resource store: objects (nodes), associations
(edges), field-role enforcement, and secret management.
Add to your project
[]
= "0.1"
# Enable sqlx::FromRow derives on Object<L>:
# olai-store = { version = "0.1", features = ["sqlx"] }
Key concepts
Label
A Label is a type-safe discriminant for resource types — typically an enum generated
by olai-codegen from google.api.resource proto annotations:
Object<L> and Association<L>
Object<L> is the untyped interchange format between your store backend and typed
resource structs: a UUID, a label (resource type), a hierarchical ResourceName, and
a JSON properties blob.
Association<L> is a directed edge between two objects — a UUID, source from_id,
edge label string, target to_id, and optional JSON properties.
ResourceName
A slash-separated hierarchical identifier, e.g. "catalogs/my-catalog/schemas/my-schema".
The store uses ResourceName as the stable human-readable key for each object.
Store traits
The crate exposes read/write split interfaces:
// Read-only
— get, get_by_name, list
— list
// Read-write (extends the reader traits)
— create, update, delete
— add, remove
A minimal in-memory implementation:
use ;
use async_trait;
use Uuid;
ManagedObjectStore — field-role enforcement
ManagedObjectStore<L, S, M> wraps any ObjectStore<S> and enforces field roles
derived from proto annotations:
FieldRole |
Source annotation | Behaviour |
|---|---|---|
Data |
(default) | Stored in properties JSON, returned as-is |
Identifier |
field_behavior = IDENTIFIER |
Stripped on write; mapped to Object.id |
Managed |
OUTPUT_ONLY + known name |
Stripped on write; injected on read (created_at, updated_at, etc.) |
Sensitive |
debug_redact = true |
Routed to SecretManager on write; redacted on read |
use ;
let registry = from_static;
let store = new;
// With secret management:
let store = with_secrets;
ResourceRegistry and FieldRole
ResourceRegistry<L> is a runtime map from label → ResourceTypeDescriptor, holding
the field roles for every resource type. It is typically constructed from a
RESOURCE_DESCRIPTORS static generated by olai-codegen:
let registry = from_static;
let descriptor = registry.descriptor.unwrap;
for field in descriptor.fields
SecretManager
SecretManager is a trait for encrypted storage of sensitive fields. Implement it to
route Sensitive-role field values to a key management service or vault:
use SecretManager;
use async_trait;
use Uuid;
Use NoSecrets (the default) when you do not need secret management — sensitive fields
are stripped from properties but not stored anywhere.
Optional sqlx feature
= { = "0.1", = ["sqlx"] }
Enables sqlx::FromRow on Object<L>, making it straightforward to read rows from a
SQL database directly into the store's interchange type.
Integration with olai-codegen
In a typical Trestle project, olai-codegen (the proto-gen CLI) generates:
- An
ObjectLabelenum that implementsLabel - A
RESOURCE_DESCRIPTORSstatic slice ofResourceTypeDescriptor<ObjectLabel>
Feed these directly into ResourceRegistry::from_static and you get full field-role
enforcement with zero boilerplate.
See the olai-codegen crate for the full
code-generation pipeline.
License
Apache-2.0