Skip to main content

qubit_codec/value/value_codec_registry/
value_string_codec_registry.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9//! Process-wide registry for string-wire value codecs.
10
11use std::sync::OnceLock;
12
13use inventory::iter;
14
15use crate::ValueCodecRegistry;
16use crate::ValueCodecRegistryError;
17use crate::ValueStringCodecDescriptor;
18use crate::ValueStringCodecRegistrationFactory;
19
20/// An immutable string-wire value-codec registry sorted by stable ID.
21///
22/// # Examples
23///
24/// ```
25/// use qubit_codec::ValueStringCodecRegistry;
26///
27/// let registry = ValueStringCodecRegistry::empty();
28/// assert!(registry.get("missing.example").is_none());
29/// ```
30pub type ValueStringCodecRegistry = ValueCodecRegistry<ValueStringCodecDescriptor>;
31
32impl ValueStringCodecRegistry {
33    /// Initializes and returns the process-wide linked string registry.
34    ///
35    /// Initialization is synchronized and cached, including construction
36    /// failures.
37    ///
38    /// # Returns
39    ///
40    /// A shared static registry containing all linked string registrations.
41    ///
42    /// # Errors
43    ///
44    /// Returns the cached construction error when linked registrations
45    /// conflict. The error identifies the lexically first duplicate ID and
46    /// all declarations for that ID in source-field order.
47    pub fn try_global() -> Result<&'static Self, ValueCodecRegistryError> {
48        // Caches both successful construction and duplicate-ID failures.
49        static REGISTRY: OnceLock<Result<ValueStringCodecRegistry, ValueCodecRegistryError>> = OnceLock::new();
50        match REGISTRY.get_or_init(|| {
51            let registrations = iter::<ValueStringCodecRegistrationFactory>
52                .into_iter()
53                .map(|factory| (factory.0)())
54                .collect();
55            ValueCodecRegistry::build(registrations)
56        }) {
57            Ok(registry) => Ok(registry),
58            Err(error) => Err(error.clone()),
59        }
60    }
61
62    /// Returns the process-wide string registry or panics with a stable
63    /// diagnostic.
64    ///
65    /// # Returns
66    ///
67    /// A shared static registry, initialized at most once by `try_global`.
68    ///
69    /// # Panics
70    ///
71    /// Panics when linked registrations conflict.
72    #[must_use]
73    #[inline]
74    pub fn global() -> &'static Self {
75        Self::try_global().unwrap_or_else(|error| panic!("invalid global value string codec registry: {error}"))
76    }
77}