Skip to main content

Module singleton_map_with

Module singleton_map_with 

Expand description

Serialize enums as single-entry maps with custom key transformation.

This module extends singleton_map by allowing custom transformation of variant names during serialization. This is useful for cases where you want the YAML keys to differ from the Rust enum variant names (e.g., converting to snake_case, lowercase, or custom mappings).

§Usage

Unlike singleton_map, this module requires you to define your own serialize/deserialize functions that call the provided helpers with a transformation function.

§Example: Snake Case Transformation

use noyalib::with::singleton_map_with;
use serde::{Deserialize, Serialize};

// Define custom serialize/deserialize functions
mod snake_case {
    use serde::{Deserializer, Serializer};

    pub fn serialize<T, S>(
        value: &T,
        serializer: S,
    ) -> Result<S::Ok, S::Error>
    where
        T: serde::Serialize,
        S: Serializer,
    {
        noyalib::with::singleton_map_with::serialize_with(
            value,
            serializer,
            to_snake_case,
        )
    }

    pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    where
        T: serde::de::DeserializeOwned + 'static,
        D: Deserializer<'de>,
    {
        noyalib::with::singleton_map_with::deserialize_with(
            deserializer,
            from_snake_case,
        )
    }

    fn to_snake_case(s: &str) -> String {
        let mut result = String::new();
        for (i, c) in s.chars().enumerate() {
            if c.is_uppercase() && i > 0 {
                result.push('_');
            }
            result.push(c.to_lowercase().next().unwrap());
        }
        result
    }

    fn from_snake_case(s: &str) -> String {
        s.split('_')
            .map(|word| {
                let mut chars = word.chars();
                match chars.next() {
                    Some(first) => {
                        first.to_uppercase().chain(chars).collect()
                    },
                    None => String::new(),
                }
            })
            .collect()
    }
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
enum HttpMethod {
    GetRequest,
    PostData,
    DeleteItem,
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct ApiCall {
    #[serde(with = "snake_case")]
    method: HttpMethod,
}

let call = ApiCall {
    method: HttpMethod::GetRequest,
};
let yaml = noyalib::to_string(&call).unwrap();
// The YAML will contain "get_request" instead of "GetRequest"

Functions§

deserialize_with
Deserialize a value from a singleton map with custom key transformation.
from_kebab_case
Common key transformation: convert kebab-case to PascalCase.
serialize_with
Serialize a value as a singleton map with custom key transformation.
to_kebab_case
Common key transformation: convert to kebab-case.
to_lowercase
Common key transformation: convert to lowercase.
to_pascal_case
Common key transformation: convert snake_case to PascalCase.
to_snake_case
Common key transformation: convert PascalCase to snake_case.
to_uppercase
Common key transformation: convert to UPPERCASE.