uri_register/lib.rs
1// Copyright TELICENT LTD
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! # URI Register
16//!
17//! A URI to integer registration service with PostgreSQL backend.
18//!
19//! This library provides a bidirectional mapping between URIs (strings) and integer IDs,
20//! optimised for batch operations and designed for use in distributed systems where
21//! stateless compute nodes need fast access to a global identifier registry.
22//!
23//! **API:** Both async ([`PostgresUriRegister`]) and sync ([`SyncPostgresUriRegister`]) APIs available.
24//! It is designed to mirror the API and behaviour of the Python `py-json-register` library.
25//!
26//! ## Features
27//!
28//! - **Async-only** - Built on tokio/sqlx for high concurrency
29//! - **Batch operations** - Efficiently lookup or create thousands of mappings at once
30//! - **PostgreSQL backend** - Durable, scalable, with connection pooling
31//! - **Configurable caching** - W-TinyLFU (Moka) or LRU caching for frequently accessed URIs
32//! - **Flexible table types** - Support for both logged (durable) and unlogged (faster) tables
33//!
34//! ## Use Cases
35//!
36//! - String interning systems
37//! - URL/URI deduplication and ID assignment
38//! - Global identifier systems
39//! - Any system needing global, persistent string-to-ID mappings
40//!
41//! ## Example
42//!
43//! ```rust,no_run
44//! use uri_register::{PostgresUriRegister, UriService};
45//!
46//! #[tokio::main]
47//! async fn main() -> uri_register::Result<()> {
48//! // Connect to PostgreSQL (schema must be initialized first)
49//! let register = PostgresUriRegister::new(
50//! "postgres://localhost/mydb",
51//! "uri_register", // table name
52//! 20, // max connections
53//! 10_000 // cache size (uses Moka/W-TinyLFU by default)
54//! ).await?;
55//!
56//! // Register a single URI
57//! let id = register.register_uri("http://example.org/resource/1").await?;
58//! println!("URI registered with ID: {}", id);
59//!
60//! // Register multiple URIs in batch (much faster!)
61//! let uris = vec![
62//! "http://example.org/resource/2".to_string(),
63//! "http://example.org/resource/3".to_string(),
64//! "http://example.org/resource/4".to_string(),
65//! ];
66//! let ids = register.register_uri_batch(&uris).await?;
67//!
68//! // IDs maintain order: ids[i] corresponds to uris[i]
69//! for (uri, id) in uris.iter().zip(ids.iter()) {
70//! println!("{} -> {}", uri, id);
71//! }
72//!
73//! Ok(())
74//! }
75//! ```
76
77mod cache;
78mod error;
79mod postgres;
80mod service;
81mod sync;
82
83#[cfg(any(test, feature = "test-utils"))]
84mod memory;
85
86#[cfg(feature = "python")]
87mod python;
88
89pub use cache::{CacheStats, CacheStrategy};
90pub use error::{ConfigurationError, Error, Result};
91pub use postgres::{PoolStats, PostgresUriRegister, RegisterStats};
92pub use service::UriService;
93pub use sync::SyncPostgresUriRegister;
94
95#[cfg(any(test, feature = "test-utils"))]
96pub use memory::InMemoryUriRegister;