// Copyright ยฉ 2024 StaticWeaver. All rights reserved. // SPDX-License-Identifier: Apache-2.0 OR MIT //! # StaticWeaver Cache Examples //! //! This program demonstrates the usage of various features of the Cache struct //! in the StaticWeaver library, including creation, insertion, retrieval, and expiration. use staticweaver::cache::Cache; use std::thread::sleep; use std::time::Duration; pub(crate) fn main() -> Result<(), Box> { println!("\n๐Ÿงช StaticWeaver Cache Examples\n"); basic_cache_operations()?; cache_expiration()?; cache_capacity()?; cache_refresh_and_update()?; cache_iteration()?; println!("\n๐ŸŽ‰ All cache examples completed successfully!"); Ok(()) } /// Demonstrates basic cache operations like insertion, retrieval, and removal. fn basic_cache_operations() -> Result<(), Box> { println!("๐Ÿฆ€ Basic Cache Operations"); println!("---------------------------------------------"); let mut cache: Cache = Cache::new(Duration::from_secs(60)); let _ = cache.insert("key1".to_string(), 42); println!(" โœ… Inserted 'key1' with value 42"); match cache.get(&"key1".to_string()) { Some(&value) => println!(" โœ… Retrieved 'key1': {}", value), None => println!(" โŒ Failed to retrieve 'key1'"), } println!( " โœ… 'key1' exists: {}", cache.contains_key(&"key1".to_string()) ); println!( " โœ… 'key2' exists: {}", cache.contains_key(&"key2".to_string()) ); match cache.remove(&"key1".to_string()) { Some(value) => { println!(" โœ… Removed 'key1' with value: {}", value) } None => println!(" โŒ Failed to remove 'key1'"), } println!(" โœ… Cache size: {}", cache.len()); println!(" โœ… Is cache empty? {}", cache.is_empty()); Ok(()) } /// Demonstrates cache expiration behavior. fn cache_expiration() -> Result<(), Box> { println!("\n๐Ÿฆ€ Cache Expiration"); println!("---------------------------------------------"); let mut cache = Cache::new(Duration::from_millis(100)); let _ = cache.insert( "short_lived".to_string(), "I'll expire soon".to_string(), ); println!(" โœ… Inserted 'short_lived' key"); sleep(Duration::from_millis(50)); match cache.ttl(&"short_lived".to_string()) { Some(ttl) => { println!(" โœ… Time-to-live for 'short_lived': {:?}", ttl) } None => println!(" โŒ Failed to get TTL for 'short_lived'"), } sleep(Duration::from_millis(60)); match cache.get(&"short_lived".to_string()) { Some(_) => println!( " โŒ Unexpected: 'short_lived' key still exists" ), None => println!(" โœ… 'short_lived' key has expired"), } cache.remove_expired(); println!( " โœ… Removed expired entries. Cache size: {}", cache.len() ); Ok(()) } /// Demonstrates cache behavior with capacity limits. fn cache_capacity() -> Result<(), Box> { println!("\n๐Ÿฆ€ Cache Capacity"); println!("---------------------------------------------"); let mut cache: Cache = Cache::with_capacity(Duration::from_secs(60), 2); let _ = cache.insert("key1".to_string(), "value1".to_string()); let _ = cache.insert("key2".to_string(), "value2".to_string()); println!(" โœ… Inserted 'key1' and 'key2'"); let _ = cache.insert("key3".to_string(), "value3".to_string()); println!(" โœ… Attempted to insert 'key3'"); println!(" โœ… Cache contents:"); for (key, value) in cache.iter() { println!(" {}: {}", key, value); } Ok(()) } /// Demonstrates refreshing and updating cache entries. fn cache_refresh_and_update() -> Result<(), Box> { println!("\n๐Ÿฆ€ Cache Refresh and Update"); println!("---------------------------------------------"); let mut cache = Cache::new(Duration::from_millis(200)); let _ = cache .insert("refresh_me".to_string(), "original value".to_string()); println!(" โœ… Inserted 'refresh_me'"); sleep(Duration::from_millis(150)); match cache.refresh(&"refresh_me".to_string()) { true => println!(" โœ… Refreshed 'refresh_me'"), false => println!(" โŒ Failed to refresh 'refresh_me'"), } match cache .update(&"refresh_me".to_string(), "updated value".to_string()) { true => println!(" โœ… Updated 'refresh_me'"), false => println!(" โŒ Failed to update 'refresh_me'"), } match cache.get(&"refresh_me".to_string()) { Some(value) => { println!(" โœ… Current value of 'refresh_me': {}", value) } None => println!(" โŒ Failed to get 'refresh_me'"), } Ok(()) } /// Demonstrates iterating over cache entries. fn cache_iteration() -> Result<(), Box> { println!("\n๐Ÿฆ€ Cache Iteration"); println!("---------------------------------------------"); let mut cache = Cache::new(Duration::from_secs(60)); for i in 1..=5 { let _ = cache.insert(format!("key{}", i), format!("value{}", i)); } println!(" โœ… Iterating over cache entries:"); for (key, value) in cache.iter() { println!(" {}: {}", key, value); } println!("\n โœ… Converting cache to a vector:"); let vec: Vec<(String, String)> = cache.into_iter().collect(); for (key, value) in &vec { println!(" {}: {}", key, value); } Ok(()) }