{"id":30450101,"url":"https://github.com/dominikj111/resourcely","last_synced_at":"2026-05-09T03:37:25.978Z","repository":{"id":310777892,"uuid":"1041177841","full_name":"dominikj111/resourcely","owner":"dominikj111","description":"A high-performance Rust library for managing both local and remote state with built-in caching, observation, and synchronization. Supports REST and non-REST API interaction to create, update, delete, or fetch remote resources (JSON, YAML, TOML, or plain text). Features async support, configurable caching, and event-driven architecture.","archived":false,"fork":false,"pushed_at":"2025-08-20T05:26:20.000Z","size":20,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-20T07:22:39.135Z","etag":null,"topics":["caching","json","local-state","remote-state","resource-handling","rest-client","rust","rust-crate","state-management","thread-safe","yaml"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dominikj111.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-20T05:20:00.000Z","updated_at":"2025-08-20T05:26:24.000Z","dependencies_parsed_at":"2025-08-20T07:22:41.750Z","dependency_job_id":null,"html_url":"https://github.com/dominikj111/resourcely","commit_stats":null,"previous_names":["dominikj111/resourcely"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dominikj111/resourcely","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominikj111%2Fresourcely","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominikj111%2Fresourcely/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominikj111%2Fresourcely/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominikj111%2Fresourcely/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dominikj111","download_url":"https://codeload.github.com/dominikj111/resourcely/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominikj111%2Fresourcely/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271749048,"owners_count":24814115,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-23T02:00:09.327Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caching","json","local-state","remote-state","resource-handling","rest-client","rust","rust-crate","state-management","thread-safe","yaml"],"created_at":"2025-08-23T13:24:30.488Z","updated_at":"2026-05-09T03:37:25.972Z","avatar_url":"https://github.com/dominikj111.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable MD033 --\u003e\n\n# Resourcely 🦀\n\n[![Crates.io](https://img.shields.io/crates/v/resourcely)](https://crates.io/crates/resourcely)\n[![Documentation](https://docs.rs/resourcely/badge.svg)](https://docs.rs/resourcely)\n[![License: BSD-3](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\n[![Dependency Status](https://deps.rs/repo/github/dominikj111/resourcely/status.svg)](https://deps.rs/repo/github/dominikj111/resourcely)\n[![Made with Rust](https://img.shields.io/badge/Made%20with-Rust-1f425f.svg?logo=rust)](https://www.rust-lang.org/)\n\nResourcely is a library that provides a convenient way to manage and access resources from both local and remote sources. It offers a unified interface for reading and writing structured data with built-in caching and staleness control.\n\n## Features ✨\n\n- **Unified Resource Access**: Consistent API for both local and remote resources\n- **Multiple Formats**: Support for JSON and YAML \u003cspan style=\"color:gray\"\u003e_(TOML and plain text in development)_\u003c/span\u003e\n- **Caching**: Configurable caching with time-based expiration\n- **Staleness Control**: Fine-grained control over when to use cached data\n- **Thread-Safe**: Designed for concurrent access using `Arc\u003cT\u003e` for zero-cost sharing across threads\n\n## Installation 📦\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nresourcely = \"0.1.0\"\n```\n\n## Quick Start 🚀\n\n```rust\nuse resourcely::{Local, Remote, ResourceFileType};\nuse serde::{Deserialize, Serialize};\nuse std::path::PathBuf;\n\n#[derive(Debug, Serialize, Deserialize, Default, Clone)]\nstruct Config {\n    api_key: String,\n    timeout: u32,\n}\n\n// Local file resource\nlet local = Local::new(\n    \"config.json\".to_string(),\n    ResourceFileType::Json,\n    PathBuf::from(\"./config\"),\n    None, // No cache timeout\n);\n\n// Remote resource\nlet remote = Remote::new(\n    \"data.json\".to_string(),\n    ResourceFileType::Json,\n    \"https://api.example.com/data\".to_string(),\n    PathBuf::from(\"/tmp/resourcely/cache\"),\n    Some(std::time::Duration::from_secs(300)), // 5 minute cache\n);\n```\n\n## Usage\n\n### Reading Data\n\n```rust\nuse resourcely::{DataResult, ResourceReader};\n\n// Get data or return error\nmatch local.get_data_or_error(false).await {\n    Ok(DataResult::Fresh(data)) =\u003e println!(\"Fresh data: {:?}\", data),\n    Ok(DataResult::Stale(data)) =\u003e println!(\"Stale data: {:?}\", data),\n    Err(e) =\u003e eprintln!(\"Error: {}\", e),\n}\n\n// Get data or default\nlet data = remote.get_data_or_default(false).await;\nprintln!(\"Data: {:?}\", data);\n\n// Get data or none\nif let Some(data) = local.get_data_or_none(true).await {\n    println!(\"Got data: {:?}\", data);\n}\n```\n\n### Marking Data as Stale\n\n```rust\n// Force refresh on next read\nlocal.mark_as_stale()?;\n\n// Check if data is marked as stale\nif local.is_marked_stale()? {\n    println!(\"Data is marked as stale\");\n}\n\n// Check if data is fresh (considering cache timeouts and stale marker)\nif local.is_fresh()? {\n    println!(\"Data is fresh\");\n}\n```\n\n## Advanced Features\n\n### Custom Parsing\n\nThe library provides support for JSON and YAML formats out of the box. TOML and plain text formats are defined in the `ResourceFileType` enum but not yet implemented. You can extend functionality by implementing the `ResourceReader` trait for your custom types.\n\n### Resource State Management\n\nThe `ResourceReader` trait provides several methods for managing resource state:\n\n```rust\n// Check if data is fresh (not stale and within cache timeout)\nlet is_fresh = resource.is_fresh()?;\n\n// Check if data is marked as stale\nlet is_stale = resource.is_marked_stale()?;\n\n// Mark data as stale to force refresh\nresource.mark_as_stale()?;\n```\n\n### Builder Pattern (Incomplete)\n\nA builder pattern is partially implemented but currently incomplete:\n\n```rust\n// Note: Builder implementation is currently incomplete\n// and references undefined traits (LocalResource, RemoteResource)\n// Use the direct state_manager API for now\n```\n\n### Error Handling\n\nAll operations return `Result` types with descriptive error messages for better error handling.\n\n## Design Decisions 🏗️\n\n### Thread-Safe Architecture 🧵\n\nResourcely uses `Arc\u003cT\u003e` to enable zero-cost sharing of data across multiple threads. This means multiple readers can access the same cached data simultaneously without cloning, making it ideal for web servers, concurrent applications, and multi-threaded data processing.\n\n### Dual-Layer Result Pattern 🎯\n\nThe library returns `Result\u003cDataResult\u003cArc\u003cT\u003e\u003e, CommonError\u003e` which cleanly separates:\n\n- **Operational errors** (`CommonError`): File not found, network failures, parsing errors\n- **Cache semantics** (`DataResult`): Whether data is fresh or stale, enabling intelligent cache management\n\nThis pattern allows you to handle errors appropriately while still making informed decisions about data freshness.\n\n### Generic Type Requirements ⚡\n\nThe trait bounds `T: Send + Sync + DeserializeOwned + Serialize + Default` ensure:\n\n- **Send + Sync**: Thread safety for concurrent access across multiple threads\n- **DeserializeOwned + Serialize**: Support for multiple data formats (JSON, YAML, etc.)\n- **Default**: Graceful fallback when data is unavailable or parsing fails\n\nThese constraints represent the minimal requirements for a thread-safe, generic resource management system.\n\n## Contributing 🤝\n\n**Note**: This library is currently in pre-release development. The first public release is planned once local CRUD operations are implemented, as this represents a complete MVP for practical use cases.\n\nThe library follows a philosophy of minimalism with maximum flexibility. We maintain a clean development roadmap and can accommodate new requirements as they arise, but all contributions must align with the library's core principles.\n\nFor detailed contribution guidelines, please see [CONTRIBUTING.md](CONTRIBUTING.md).\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License 📄\n\nThis project is licensed under the BSD 3-Clause License - see the [LICENSE](LICENSE) file for details.\n\n## TODO 📋\n\n### Completed Achievements ✅\n\n- ✅ **Core Resource Management System** - Unified interface for local and remote resource access\n- ✅ **Advanced Error Handling** - Comprehensive error types with descriptive messages using `thiserror`\n- ✅ **Multi-format Support** - JSON and YAML parsing with extensible format system\n- ✅ **Intelligent Caching** - Time-based cache expiration with staleness control and state management\n- ✅ **Thread-safe Architecture** - Concurrent access support with proper synchronization\n- ✅ **Flexible Resource State Management** - Mark as stale, freshness checking, and cache state inspection\n\n### High Priority Improvements\n\n- 🚀 **Comprehensive Test Suite** - Unit and integration tests for all core functionality\n- 🚀 **Code Documentation** - Add comment docs to functions/enums/trais/modules/...\n- 🚀 **Code Consolidation** - Extract and eliminate duplicate code across modules; repeated logic between local and remote resource readers (e.g., cache checks)\n- ⬜️ **Local File CRUD Operations** - Create, update, and delete capabilities for local resources\n- 🟧 **Builder Pattern Completion** - Finalize and export the fluent resource creation API with examples\n- ⬜️ **CI/CD** - Set CI for linting, formatting, and running tests\n- ⬜️ **Sync implementation** - Sync Implementations where relevant (`./src/local.rs`)\n- ⬜️ **HTTP Request Timeouts** - Configurable timeout handling for remote resource fetching\n- ⬜️ **Reactive Resource Management** - Observable pattern with file system watching for real-time updates\n\n### Medium Priority Features\n\n- 🟧 **Resource Factory Patterns** - Convenient creation utilities (skeleton exists but needs implementation)\n- ⬜️ **Enhanced Documentation** - Comprehensive examples and API reference guides\n- ⬜️ **Logging/Tracing** - Add logging or tracing for debugging or production diagnostics\n- 🤔 **Advanced Caching Strategies** - Redis, distributed caching, and cloud-based cache services\n- 🤔 **Performance Benchmarking** - Automated benchmarks for performance-critical operations\n\n### New Features Pipeline\n\n- ⬜️ **Replace Deprecated serde_yaml**\n- ⬜️ **Extended Format Support** - TOML, XML, and plain text parsing\n- ⬜️ **RESTful API Integration** - Full CRUD support for REST endpoints and generic HTTP services\n- ⬜️ **Authentication Framework** - API keys, OAuth, and other security mechanisms for remote resources\n- ⬜️ **Secure Protocol Support** - FTP, SFTP, and SSH-based file access\n- ⬜️ **Large File Optimization** - ⬇️ Zero-copy processing/parsing and reference-based handling for big files\n- ⬜️ **Stream Processing** - ⬆️ Memory-efficient processing for very large files\n\n### Future Enhancements\n\n- ⬜️ **Large File Downloads** - Efficient handling of multi-gigabyte file transfers\n- ⬜️ **Compression Support** - Built-in compression and decompression capabilities\n- ⬜️ **Binary File Processing** - Native support for binary data formats\n- 🤔 **Alternative Storage Backends** - Database integration and cloud storage support\n- 🤔 **Advanced Hash Algorithms** - SHA-2, SHA-3, and other cryptographic hash support\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdominikj111%2Fresourcely","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdominikj111%2Fresourcely","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdominikj111%2Fresourcely/lists"}