| Crates.io | rs_ervice |
| lib.rs | rs_ervice |
| version | 0.1.6 |
| created_at | 2025-05-25 15:06:49.920447+00 |
| updated_at | 2025-05-27 21:41:18.129482+00 |
| description | A Rust service manager for vanilla or Tokio runtime |
| homepage | |
| repository | https://github.com/LuticaCANARD/rs-ervice |
| max_upload_size | |
| id | 1688436 |
| size | 47,697 |
intuitive & powerful library Service manager.
rs-ervice, a Service is a Rust struct that bundles related state with the methods (actions) that operate on that state.RSContext, which provides them as singleton instances for consistent and easy access.use std::any::Any;
#[derive(Debug, Clone)]
struct MyService {
pub state: String,
//...
}
trait Chant{
fn chanting(st:String) -> String;
}
impl MyService {
pub fn new() -> Self {
MyService{
state : "HELLO - ".to_string(),
}
}
pub fn doing_something(&self, something: String) -> String {
self.state.clone() + &something
}
}
impl Chant for MyService {
fn chanting(st: String) -> String {
st + "!!!!!"
}
}
impl RSContextService for MyService {
/// this hook is call on registering
fn on_register_crate_instance() -> Self {
MyService::new()
}
/// this hook is call after register
fn on_service_created(&mut self, service_builder: &RSContextBuilder) -> Result<(), RsServiceError> {
println!("Service {} registered successfully!", std::any::type_name::<Self>());
Ok(())
}
/// this hook is call after build
fn on_all_services_built(&self, context: &rs_ervice::RSContext) -> Result<(), RsServiceError> {
println!("All services built successfully in context: {:?}", context.type_id());
Ok(())
}
}
#[derive(Debug, Clone)]
struct AnotherService {
}
impl AnotherService {
pub fn new() -> Self {
AnotherService {}
}
}
impl RSContextService for AnotherService {
fn on_register_crate_instance() -> Self {
AnotherService::new()
}
fn on_service_created(&mut self, service_builder: &RSContextBuilder) -> Result<(), RsServiceError> {
print!("AnotherService registered!\n");
Ok(())
}
fn on_all_services_built(&self, context: &rs_ervice::RSContext) -> Result<(), RsServiceError> {
println!("All services built successfully in context: {:?}", context.type_id());
Ok(())
}
}
/// on use...
use rs_ervice::{RSContextBuilder, RSContextService, RsServiceError};
fn main(){
let service_context = RSContextBuilder::new()
.register::<MyService>()
.register::<AnotherService>()
.build()
.expect("Failed to build RSContext");
let do_service = service_context.call::<MyService>();
if do_service.is_none() {
panic!("MyService is not registered!");
}
let do_service = do_service.unwrap().lock().unwrap().doing_something("Hi!".to_string());
// Expected output: HELLO - Hi!
println!("{}", do_service);
// To call the Chanting method from the Chant trait implemented by MyService:
// Since Chanting does not take &self, it's called like a static method associated with the trait implementation.
let chanting_output = <MyService as Chant>::chanting("Hi!".to_string());
// Expected output: HELLO - Hi!!!!!!!!!! (Original was "Hi!!!!!!!", but it takes the result of do_something)
println!("{}", chanting_output)
}
use std::any::Any;
use rs_ervice_macro_lib::{r_service, r_service_struct};
#[r_service_struct]
#[derive(Debug, Clone)]
struct MyService {
pub state: String,
//...
}
trait Chant{
fn chanting(st:String) -> String;
}
#[r_service]
impl MyService {
pub fn new() -> Self {
MyService{
state : "HELLO - ".to_string(),
}
}
pub async fn doing_something(&self, something: String) -> String {
self.state.clone() + &something
}
}
impl Chant for MyService {
fn chanting(st: String) -> String {
st + "!!!!!"
}
}
impl RSContextService for MyService {
fn on_register_crate_instance() -> Self {
MyService::new()
}
fn on_service_created(&mut self, service_builder: &RSContextBuilder) -> Result<(), RsServiceError> {
// 서비스가 등록될 때 호출되는 메서드
println!("Service {} registered successfully!", std::any::type_name::<Self>());
Ok(())
}
fn on_all_services_built(&self, context: &rs_ervice::RSContext) -> Result<(), RsServiceError> {
// 모든 서비스가 빌드된 후 호출되는 메서드
println!("All services built successfully in context: {:?}", context.type_id());
Ok(())
}
}
#[r_service_struct]
#[derive(Debug, Clone)]
struct AnotherService {
}
#[r_service]
impl AnotherService {
pub fn new() -> Self {
AnotherService {}
}
}
impl RSContextService for AnotherService {
fn on_register_crate_instance() -> Self {
AnotherService::new()
}
fn on_service_created(&mut self, service_builder: &RSContextBuilder) -> Result<(), RsServiceError> {
print!("AnotherService registered!\n");
Ok(())
}
fn on_all_services_built(&self, context: &rs_ervice::RSContext) -> Result<(), RsServiceError> {
// 모든 서비스가 빌드된 후 호출되는 메서드
println!("All services built successfully in context: {:?}", context.type_id());
Ok(())
}
}
#[tokio::main]
async fn main() {
let service_context = RSContextBuilder::new()
.register::<MyService>()
.register::<AnotherService>()
.build()
.await
.expect("Failed to build RSContext");
let do_service = service_context.call::<MyService>();
if do_service.is_none() {
panic!("MyService is not registered!");
}
let do_service = do_service.unwrap().lock().await.doing_something("Hi!".to_string()).await;
// Expected output: HELLO - Hi!
println!("{}", do_service);
// To call the Chanting method from the Chant trait implemented by MyService:
let chanting_output = <MyService as Chant>::chanting("Hi!".to_string());
// Expected output: HELLO - Hi!!!!!!!!!! (Original was "Hi!!!!!!!", but it takes the result of do_something)
println!("{}", chanting_output);
}
intuitive.Service Context : Manages diverse service types within an isolated scope.This allows for clear separation of concerns in service management and enhances testability by providing distinct contexts.
Intuitive Macro System: Define services effortlessly using #[r_service_struct] and #[r_service] attributes, significantly reducing boilerplate code.Async Ready: Designed with asynchronous operations in mind, allowing service methods to be async and integrate seamlessly.Type-Safe Resolution: Retrieve service instances with call::<YourService>(), ensuring type safety at compile time.Composable Services: Services managed by rs-ervice are standard Rust structs and can implement any number of traits, allowing for rich composition of behaviors and integration with other parts of your application or ecosystem. (Our example demonstrates this with the Chant trait).Just use this command!
cargo add rs_ervice