Skip to main content

qubit_value/
lib.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! # Value Processing Framework
9//!
10//! Provides type-safe value storage and access functionality, supporting single
11//! values, collections, explicit scalar-or-collection shape, and named values.
12//!
13//! # Public API Overview
14//!
15//! - [`Value`] stores one typed scalar, including an explicit `Unset(DataType)`
16//!   state.
17//! - [`MultiValues`] stores one homogeneous typed collection.
18//! - [`ValueRef`] and [`MultiValuesRef`] expose borrowed semantic views while
19//!   keeping runtime storage private.
20//! - [`ValueContainer`] preserves whether storage is scalar or collection.
21//! - [`NamedValue`] and [`NamedMultiValues`] provide name wrappers.
22//! - [`ValueWireV1`] and [`ValueWirePayloadV1`] name explicit Serde DTOs.
23//! - [`ValueWireRefV1`] and [`ValueWirePayloadRefV1`] serialize borrowed
24//!   values.
25//!
26//! # Core behavior
27//!
28//! - [`Value::get`] and [`MultiValues::get`] perform strict typed reads.
29//! - [`ValueContainer`] preserves whether the source supplied a scalar or an
30//!   explicit collection, even when the collection contains one item.
31//! - `to` methods use `qubit-datatype` conversion rules and options.
32//! - Optional type families and conversion methods are available only when the
33//!   corresponding crate features are enabled; all-features documentation shows
34//!   the superset of those APIs.
35//! - [`Value::is_unset`] and [`ValueContainer::is_unset`] indicate that no
36//!   concrete value is stored.
37//! - [`MultiValues::is_unset`] distinguishes no collection from a concrete
38//!   collection; [`MultiValues::is_empty`] reports only that its length is
39//!   zero.
40//! - Generic `set` replaces a value infallibly; [`MultiValues::add`] remains
41//!   fallible because appended values must have the same data type.
42//! - Serde uses the strict, type-preserving [`ValueWireV1`] envelope. Its
43//!   canonical JSON representation is byte-stable for the same value under the
44//!   supported `serde_json` version and configuration. String-map keys and
45//!   nested JSON object keys are emitted in lexicographic order. Other Serde
46//!   formats are supported as representations, but are outside this byte-level
47//!   stability contract. With both `converter` and `json`, `to_json_value`
48//!   provides a separate natural JSON projection with the same ordering.
49//! - Version one rejects the pre-0.10 externally tagged representation.
50//! - Non-finite floats may exist in memory, but V1 Serde and natural JSON
51//!   reject them because JSON has no `NaN` or infinity number literals.
52//! - V1 JSON payloads reject objects containing serde_json's private
53//!   `"$serde_json::private::Number"` key because arbitrary-precision number
54//!   decoding uses that same Serde marker.
55//!
56//! # Usage Examples
57//!
58//! ## Single Value Operations
59//!
60//! ```rust
61//! use qubit_value::Value;
62//!
63//! // Create and access a single value
64//! let value = Value::Int32(42);
65//! assert_eq!(value.get_int32().unwrap(), 42);
66//!
67//! // Strict generic access
68//! let number: i32 = value.get().unwrap();
69//! assert_eq!(number, 42);
70//! ```
71//!
72//! ## Multiple Values Operations
73//!
74//! ```rust
75//! use qubit_value::MultiValues;
76//!
77//! // Create and access multiple values
78//! let mut values = MultiValues::Int32(vec![1, 2, 3]);
79//! assert_eq!(values.len(), 3);
80//!
81//! // Add values
82//! values.add(4).unwrap();
83//! assert_eq!(values.get_int32s().unwrap(), &[1, 2, 3, 4]);
84//! ```
85//!
86//! ## Named Value Operations
87//!
88//! ```rust
89//! use qubit_value::{NamedValue, Value};
90//!
91//! // Create a named value
92//! let config = NamedValue::new("port", Value::Int32(8080));
93//! assert_eq!(config.name(), "port");
94//! assert_eq!(config.value().get_int32().unwrap(), 8080);
95//! ```
96//!
97//! ## Explicit Shape Operations
98//!
99//! ```rust
100//! use qubit_value::ValueContainer;
101//!
102//! let scalar = ValueContainer::from(42_i32);
103//! let collection = ValueContainer::from(vec![42_i32]);
104//! assert!(scalar.is_scalar());
105//! assert!(collection.is_collection());
106//! ```
107
108// Sub-modules
109mod finite_float;
110mod identity;
111mod into_value_default;
112#[macro_use]
113mod value_type_table;
114#[cfg(all(feature = "converter", feature = "json"))]
115mod json;
116mod multi_values;
117mod named_multi_values;
118mod named_value;
119mod numeric_comparison_error;
120#[cfg(all(feature = "converter", feature = "json"))]
121mod strict_json;
122mod strict_value_read;
123mod value;
124mod value_container;
125mod value_error;
126mod value_missing;
127mod value_wire;
128mod wide_integer;
129mod wire;
130
131// Public exports
132pub use into_value_default::IntoValueDefault;
133pub use multi_values::{
134    MultiValues,
135    MultiValuesRef,
136};
137pub use named_multi_values::NamedMultiValues;
138pub use named_value::NamedValue;
139pub use numeric_comparison_error::NumericComparisonError;
140pub use strict_value_read::StrictValueRead;
141pub use value::{
142    Value,
143    ValueRef,
144};
145pub use value_container::ValueContainer;
146pub use value_error::{
147    ValueError,
148    ValueResult,
149};
150pub use value_missing::ValueMissing;
151#[cfg(feature = "json")]
152pub use value_wire::{
153    ValueWireDecodeError,
154    ValueWireLimitKind,
155    WireBudget,
156    WireLimits,
157};
158pub use value_wire::{
159    ValueWireEncodeError,
160    ValueWirePayloadRefV1,
161    ValueWirePayloadV1,
162    ValueWireRefV1,
163    ValueWireV1,
164};