PrefixRegistry

Struct PrefixRegistry 

Source
pub struct PrefixRegistry { /* private fields */ }
Expand description

Registry for namespace prefixes.

Provides async access to the namespaces table in PostgreSQL. Prefixes are stored with their corresponding URIs, following the rule that each URI can only have one prefix (first one wins).

The registry maintains an in-memory cache of all prefixes, which is populated on startup and updated as new prefixes are stored. This ensures fast CURIE expansion without database round-trips.

Implementations§

Source§

impl PrefixRegistry

Source

pub async fn new(database_url: &str, max_connections: usize) -> Result<Self>

Create a new prefix registry connected to the given PostgreSQL database.

The registry will connect to the database and pre-populate its in-memory cache with existing prefixes for fast CURIE expansion.

§Arguments
  • database_url - PostgreSQL connection URL (e.g., “postgres://user:pass@host:port/db”)
  • max_connections - Maximum number of connections in the pool
§Errors

Returns an error if the database connection cannot be established or if the namespaces table does not exist.

§Example
use prefix_register::PrefixRegistry;

let registry = PrefixRegistry::new(
    "postgres://localhost/mydb",
    10,
).await?;
Source

pub async fn new_with_retry( database_url: &str, max_connections: usize, retry_config: RetryConfig, ) -> Result<Self>

Create a new prefix registry with retry logic for transient failures.

This variant of new implements exponential backoff retry to handle transient database unavailability during startup (e.g., during container orchestration where the database may start after this service).

§Arguments
  • database_url - PostgreSQL connection URL
  • max_connections - Maximum number of connections in the pool
  • retry_config - Configuration for retry behaviour
§Example
use prefix_register::{PrefixRegistry, RetryConfig};
use std::time::Duration;

// Use default retry config (5 retries, 1s initial, 30s max)
let registry = PrefixRegistry::new_with_retry(
    "postgres://localhost/mydb",
    10,
    RetryConfig::default(),
).await?;

// Or customize retry behaviour
let registry = PrefixRegistry::new_with_retry(
    "postgres://localhost/mydb",
    10,
    RetryConfig::new(
        3,                           // max 3 retries
        Duration::from_millis(500),  // start at 500ms
        Duration::from_secs(10),     // cap at 10s
    ),
).await?;
Source

pub async fn get_uri_for_prefix(&self, prefix: &str) -> Result<Option<String>>

Get the URI for a given prefix.

First checks the in-memory cache, then falls back to the database. This is the primary method used for CURIE expansion.

§Arguments
  • prefix - The namespace prefix (e.g., “foaf”, “rdf”)
§Returns

The URI if the prefix is known, None otherwise.

§Example
if let Some(uri) = registry.get_uri_for_prefix("foaf").await? {
    println!("foaf = {}", uri);
}
Source

pub async fn get_prefix_for_uri(&self, uri: &str) -> Result<Option<String>>

Get the prefix for a given URI.

Used to check if a URI already has a registered prefix.

§Arguments
  • uri - The full namespace URI
§Returns

The prefix if the URI is registered, None otherwise.

§Example
if let Some(prefix) = registry.get_prefix_for_uri("http://xmlns.com/foaf/0.1/").await? {
    println!("URI has prefix: {}", prefix);
}
Source

pub async fn store_prefix_if_new(&self, prefix: &str, uri: &str) -> Result<bool>

Store a new prefix if the URI doesn’t already have one.

This follows the “first prefix wins” rule - if a URI already has a prefix registered, the new prefix is ignored.

§Arguments
  • prefix - The namespace prefix to store
  • uri - The full namespace URI
§Returns

true if the prefix was stored, false if the URI already had a prefix.

§Example
let stored = registry.store_prefix_if_new("schema", "https://schema.org/").await?;
if stored {
    println!("New prefix stored");
} else {
    println!("URI already has a prefix");
}
Source

pub async fn store_prefixes_if_new<'a, I>( &self, prefixes: I, ) -> Result<BatchStoreResult>
where I: IntoIterator<Item = (&'a str, &'a str)>,

Store multiple prefixes, skipping any where the URI already has a prefix.

More efficient than calling store_prefix_if_new repeatedly.

§Arguments
  • prefixes - Iterator of (prefix, uri) pairs to store
§Returns

A BatchStoreResult with counts of stored and skipped prefixes.

§Example
let prefixes = vec![
    ("foaf", "http://xmlns.com/foaf/0.1/"),
    ("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
    ("schema", "https://schema.org/"),
];
let result = registry.store_prefixes_if_new(prefixes).await?;
println!("Stored {}, skipped {}", result.stored, result.skipped);
Source

pub async fn expand_curie( &self, prefix: &str, local_name: &str, ) -> Result<Option<String>>

Expand a CURIE (Compact URI) to a full URI.

Given a prefix and local name, returns the expanded URI if the prefix is known.

§Arguments
  • prefix - The namespace prefix (e.g., “foaf”)
  • local_name - The local part (e.g., “Person”)
§Returns

The full URI (e.g., “http://xmlns.com/foaf/0.1/Person”) or None if the prefix is unknown.

§Example
if let Some(uri) = registry.expand_curie("foaf", "Person").await? {
    println!("foaf:Person = {}", uri);
    // Output: foaf:Person = http://xmlns.com/foaf/0.1/Person
}
Source

pub async fn get_all_prefixes(&self) -> HashMap<String, String>

Get all registered prefixes.

Returns a copy of the in-memory cache containing all prefix -> URI mappings.

§Example
let prefixes = registry.get_all_prefixes().await;
for (prefix, uri) in prefixes {
    println!("{}: {}", prefix, uri);
}
Source

pub async fn prefix_count(&self) -> usize

Get the number of registered prefixes.

§Example
let count = registry.prefix_count().await;
println!("Registered prefixes: {}", count);
Source

pub async fn shorten_uri(&self, uri: &str) -> Result<Option<(String, String)>>

Shorten a URI to a (prefix, local_name) tuple.

Uses longest-match semantics: if multiple namespaces match the URI, the longest one wins. For example, with namespaces:

  • A = http://a/
  • B = http://a/b#

The URI http://a/b#thing would shorten to ("B", "thing"), not ("A", "b#thing").

§Arguments
  • uri - The full URI to shorten
§Returns

Some((prefix, local_name)) if a matching namespace is found, None otherwise.

§Example
if let Some((prefix, local)) = registry.shorten_uri("http://xmlns.com/foaf/0.1/Person").await? {
    println!("{}:{}", prefix, local);
    // Output: foaf:Person
}
Source

pub async fn shorten_uri_or_full(&self, uri: &str) -> Result<String>

Shorten a URI to a CURIE string, or return the original URI if no match.

This is a convenience method that returns a ready-to-use string.

§Arguments
  • uri - The full URI to shorten
§Returns

A CURIE string like "prefix:local", or the original URI if no namespace matches.

§Example
let result = registry.shorten_uri_or_full("http://xmlns.com/foaf/0.1/Person").await?;
println!("{}", result);
// Output: foaf:Person (or the full URI if foaf is not registered)
Source

pub async fn shorten_uri_batch<'a, I>( &self, uris: I, ) -> Result<Vec<Option<(String, String)>>>
where I: IntoIterator<Item = &'a str>,

Shorten multiple URIs in batch.

Preserves order. Returns None for URIs that don’t match any namespace.

§Arguments
  • uris - Iterator of URIs to shorten
§Returns

A vector with Some((prefix, local_name)) for matched URIs, None for unmatched.

§Example
let uris = vec![
    "http://xmlns.com/foaf/0.1/Person",
    "http://unknown.org/thing",
    "https://schema.org/Organization",
];
let results = registry.shorten_uri_batch(uris).await?;
for (uri, result) in ["Person", "thing", "Organization"].iter().zip(results) {
    match result {
        Some((prefix, local)) => println!("{}:{}", prefix, local),
        None => println!("No match"),
    }
}
Source

pub async fn expand_curie_batch<'a, I>( &self, curies: I, ) -> Result<Vec<Option<String>>>
where I: IntoIterator<Item = (&'a str, &'a str)>,

Expand multiple CURIEs in batch.

Preserves order. Returns None for CURIEs with unknown prefixes.

§Arguments
  • curies - Iterator of (prefix, local_name) pairs
§Returns

A vector with Some(uri) for known prefixes, None for unknown.

§Example
let curies = vec![
    ("foaf", "Person"),
    ("unknown", "Thing"),
    ("schema", "Organization"),
];
let results = registry.expand_curie_batch(curies).await?;
for result in results {
    match result {
        Some(uri) => println!("{}", uri),
        None => println!("Unknown prefix"),
    }
}

Trait Implementations§

Source§

impl Clone for PrefixRegistry

Source§

fn clone(&self) -> PrefixRegistry

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more