cdumay_context/
lib.rs

1//! [![License: BSD-3-Clause](https://img.shields.io/badge/license-BSD--3--Clause-blue)](./LICENSE)
2//! [![cdumay_context on crates.io](https://img.shields.io/crates/v/cdumay_context)](https://crates.io/crates/cdumay_context)
3//! [![cdumay_context on docs.rs](https://docs.rs/cdumay_context/badge.svg)](https://docs.rs/cdumay_context)
4//! [![Source Code Repository](https://img.shields.io/badge/Code-On%20GitHub-blue?logo=GitHub)](https://github.com/cdumay/cdumay_context)
5//!
6//! A flexible context management library that provides a trait-based approach for handling
7//! key-value data with support for multiple serialization formats.
8//!
9//! # Features
10//!
11//! - Generic context management through the `Contextualize` trait and a `Context` struct
12//! - Support for multiple serialization formats (with feature flags):
13//!   - JSON (feature: "json")
14//!   - TOML (feature: "toml")
15//!   - YAML (feature: "yaml")
16//! - Allow to dump context into `reqwest` headers using feature "http-headers"
17//! - Type-safe error handling with the `Error` enum
18//!
19//! # Example Usage
20//!
21//! ```rust
22//! use std::collections::BTreeMap;
23//! use serde::{Serialize, Deserialize};
24//! use cdumay_context::{Contextualize, Error, Context};
25//!
26//! // Basic usage
27//! let mut ctx = Context::new();
28//! ctx.insert("name".to_string(), serde_value::Value::String("Alice".to_string()));
29//!
30//! // JSON serialization (requires "json" feature)
31//! #[cfg(feature = "json")]
32//! {
33//!     let json = ctx.to_json(true).unwrap();
34//!     let ctx_from_json = Context::from_json(&json).unwrap();
35//!     assert_eq!(ctx.get("name"), ctx_from_json.get("name"));
36//! }
37//!
38//! // TOML serialization (requires "toml" feature)
39//! #[cfg(feature = "toml")]
40//! {
41//!     let toml = ctx.to_toml(true).unwrap();
42//!     let ctx_from_toml = Context::from_toml(&toml).unwrap();
43//!     assert_eq!(ctx.get("name"), ctx_from_toml.get("name"));
44//! }
45//! ```
46//!
47//! # Error Handling
48//!
49//! The library provides a comprehensive error handling system through the `Error` enum:
50//!
51//! ```rust
52//! use std::collections::BTreeMap;
53//! use serde::{Serialize, Deserialize};
54//! use cdumay_context::{Context, Contextualize, Error};
55//! use rand::Rng;
56//!
57//! fn example_error_handling() -> Result<(), Error> {
58//!     let mut rng = rand::rng();
59//!     let dice_roll: u8 = rng.random_range(1..=6);
60//!
61//!     // Generic error
62//!     if dice_roll == 7 {
63//!         return Err(Error::Generic("Something went wrong".to_string()));
64//!     }
65//!
66//!     // JSON error (with "json" feature)
67//!     #[cfg(feature = "json")]
68//!     {
69//!         let invalid_json = "{ invalid: json }";
70//!         let result = Context::from_json(invalid_json);
71//!         assert!(matches!(result, Err(Error::Json(_))));
72//!     }
73//!     Ok(())
74//! }
75//! ```
76
77mod error;
78pub use error::Error;
79
80mod context;
81pub use context::{Context, Contextualize};
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86    use std::collections::BTreeMap;
87    
88    #[test]
89    fn test_basic_operations() {
90        let mut ctx = Context::new();
91        
92        // Test insert and get
93        ctx.insert("key1".to_string(), serde_value::Value::String("value1".to_string()));
94        assert_eq!(
95            ctx.get("key1").unwrap(),
96            &serde_value::Value::String("value1".to_string())
97        );
98
99        // Test extend
100        let mut data = BTreeMap::new();
101        data.insert("key2".to_string(), serde_value::Value::U64(42));
102        ctx.extend(data);
103
104        assert_eq!(ctx.get("key2").unwrap(), &serde_value::Value::U64(42));
105    }
106
107    #[test]
108    #[cfg(feature = "json")]
109    fn test_json_serialization() {
110        let mut ctx = Context::new();
111        ctx.insert("name".to_string(), serde_value::Value::String("Alice".to_string()));
112        ctx.insert("age".to_string(), serde_value::Value::U64(30));
113
114        // Test JSON serialization/deserialization
115        let json = ctx.to_json(true).unwrap();
116        let ctx_from_json = Context::from_json(&json).unwrap();
117        
118        assert_eq!(ctx.get("name"), ctx_from_json.get("name"));
119        assert_eq!(ctx.get("age"), ctx_from_json.get("age"));
120    }
121
122    #[test]
123    #[cfg(feature = "toml")]
124    fn test_toml_serialization() {
125        let mut ctx = Context::new();
126        ctx.insert("name".to_string(), serde_value::Value::String("Bob".to_string()));
127        ctx.insert("age".to_string(), serde_value::Value::I64(25));
128
129        // Test TOML serialization/deserialization
130        let toml = ctx.to_toml(true).unwrap();
131        let ctx_from_toml = Context::from_toml(&toml).unwrap();
132        
133        assert_eq!(ctx.get("name"), ctx_from_toml.get("name"));
134        assert_eq!(ctx.get("age"), ctx_from_toml.get("age"));
135    }
136
137    #[test]
138    #[cfg(feature = "yaml")]
139    fn test_yaml_serialization() {
140        let mut ctx = Context::new();
141        ctx.insert("name".to_string(), serde_value::Value::String("Charlie".to_string()));
142        ctx.insert("age".to_string(), serde_value::Value::U64(35));
143
144        // Test YAML serialization/deserialization
145        let yaml = ctx.to_yaml().unwrap();
146        let ctx_from_yaml = Context::from_yaml(&yaml).unwrap();
147        
148        assert_eq!(ctx.get("name"), ctx_from_yaml.get("name"));
149        assert_eq!(ctx.get("age"), ctx_from_yaml.get("age"));
150    }
151}