1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! Generic, TAO-inspired resource store for typed objects and associations — the
//! async storage layer for services built with the [Trestle] framework.
//!
//! Core abstractions for a graph-based store, generic over `L: [Label]` (a
//! type-safe resource-type discriminant, typically generated from
//! `google.api.resource` annotations):
//!
//! - [`Object<L>`][Object] — a resource node: UUID, label, hierarchical
//! [`ResourceName`], and a JSON properties blob.
//! - [`Association<L>`][Association] — a directed edge between two objects.
//! - [`ObjectStore<L>`][ObjectStore] / [`AssociationStore<L>`][AssociationStore]
//! — the async read/write storage traits (with `*Reader` read-only
//! counterparts). The bundled [`InMemoryStore`] and `SqlStore` backends
//! implement them; they are a **taxonomy-blind blob layer** — they persist
//! already-shaped properties plus an opaque sensitive blob and know nothing of
//! field roles.
//! - [`ManagedObjectStore`] — **the store you reach for.** It wraps a backend and
//! a [`ResourceRegistry`] to enforce field roles (data / identifier / managed /
//! sensitive): stripping store-owned fields, injecting them back on read, and
//! sealing/redacting sensitive fields. Encryption is optional — build it with
//! [`new`](ManagedObjectStore::new) for a store with no sensitive fields, or
//! `with_encryptor` (the `encryption`
//! feature) to seal them. Writing a resource that *has* sensitive fields through
//! a store with no encryptor is a hard error, never a silent drop.
//!
//! Most callers construct a `ManagedObjectStore` and use it through the
//! `ObjectStore` trait; the raw backends are the pluggable layer underneath.
//!
//! **Note:** this store favours simplicity over features and performance. It's a
//! good default for bootstrapping Trestle projects, prototypes, and demos, but is
//! not intended for serious production workloads — back these traits with your
//! own production-grade engine for those.
//!
//! # Examples
//!
//! Define a resource taxonomy by implementing [`Label`] for an enum. The store
//! traits are generic over this type:
//!
//! ```
//! use std::fmt;
//! use std::str::FromStr;
//!
//! use olai_store::Label;
//!
//! #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
//! enum Kind {
//! Catalog,
//! Schema,
//! Table,
//! }
//!
//! impl Kind {
//! fn as_str(&self) -> &'static str {
//! match self {
//! Kind::Catalog => "catalog",
//! Kind::Schema => "schema",
//! Kind::Table => "table",
//! }
//! }
//! }
//!
//! impl fmt::Display for Kind {
//! fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
//! f.write_str(self.as_str())
//! }
//! }
//!
//! impl FromStr for Kind {
//! type Err = String;
//!
//! fn from_str(s: &str) -> Result<Self, Self::Err> {
//! match s {
//! "catalog" => Ok(Kind::Catalog),
//! "schema" => Ok(Kind::Schema),
//! "table" => Ok(Kind::Table),
//! other => Err(format!("unknown kind: {other}")),
//! }
//! }
//! }
//!
//! impl Label for Kind {
//! fn as_str(&self) -> &str {
//! Kind::as_str(self)
//! }
//! }
//!
//! assert_eq!(Kind::Table.as_str(), "table");
//! assert_eq!("schema".parse::<Kind>(), Ok(Kind::Schema));
//! ```
//!
//! [Trestle]: https://github.com/open-lakehouse/trestle
// Re-exports for convenience.
pub use InMemoryStore;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use Label;
pub use ManagedObjectStore;
pub use ;
pub use ;
pub use ResourceRef;
pub use ;
pub use ;