qubit-value 0.13.1

Type-safe containers for single, multi-valued, and named runtime values
Documentation
// =============================================================================
//    Copyright (c) 2025 - 2026 Haixing Hu.
//
//    SPDX-License-Identifier: Apache-2.0
//
//    Licensed under the Apache License, Version 2.0.
// =============================================================================

//! Canonical Serde adapter for string maps.

use std::collections::HashMap;

use serde::Deserialize;
use serde::Deserializer;
use serde::Serializer;
use serde::ser::SerializeMap;

use super::internal::StrictStringMap;

/// Serializes one string map with lexicographically ordered keys.
///
/// Borrows the entries without cloning their strings and allocates a temporary
/// vector of entry references for sorting. The source map remains unchanged.
///
/// # Type Parameters
///
/// * `S` - Destination serializer type.
///
/// # Parameters
///
/// * `value` - String map to serialize canonically.
/// * `serializer` - Destination serializer.
///
/// # Returns
///
/// The destination serializer's map result.
///
/// # Errors
///
/// Returns `S::Error` when map serialization fails.
pub(crate) fn serialize<S>(
    value: &HashMap<String, String>,
    serializer: S,
) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    let mut map = serializer.serialize_map(Some(value.len()))?;
    let mut entries: Vec<_> = value.iter().collect();
    entries.sort_unstable_by_key(|(left, _)| *left);

    for (key, value) in entries {
        map.serialize_entry(key, value)?;
    }
    map.end()
}

/// Deserializes one string map from any Serde map representation.
///
/// Produces owned keys and values and rejects duplicate keys rather than
/// overwriting an earlier entry.
///
/// # Type Parameters
///
/// * `D` - Source deserializer type.
///
/// # Parameters
///
/// * `deserializer` - Source deserializer.
///
/// # Returns
///
/// The decoded string map after duplicate-key validation.
///
/// # Errors
///
/// Returns `D::Error` when decoding fails or the map repeats a key.
#[inline]
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<HashMap<String, String>, D::Error>
where
    D: Deserializer<'de>,
{
    StrictStringMap::<String>::deserialize(deserializer).map(StrictStringMap::into_inner)
}