| Crates.io | dog-core |
| lib.rs | dog-core |
| version | 0.1.4 |
| created_at | 2026-01-23 03:45:09.983203+00 |
| updated_at | 2026-01-25 03:33:56.38869+00 |
| description | Core traits and utilities for the DogRS ecosystem - a modular Rust framework for building scalable applications |
| homepage | |
| repository | https://github.com/Jitpomi/dogrs |
| max_upload_size | |
| id | 2063344 |
| size | 89,775 |
Core traits and utilities for the DogRS ecosystem - a modular Rust framework for building scalable applications
dog-core provides the foundational abstractions that power the DogRS framework: services, hooks, tenant contexts, and storage contracts. It's designed to keep your core logic clean and portable across different adapters and environments.
Add to your Cargo.toml:
[dependencies]
dog-core = "0.1.0"
use dog_core::{DogService, TenantContext, Result};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct CreateUserRequest {
name: String,
email: String,
}
#[derive(Serialize)]
struct User {
id: u32,
name: String,
email: String,
}
struct UserService;
#[async_trait]
impl DogService<CreateUserRequest, ()> for UserService {
type Output = User;
async fn create(&self, tenant: TenantContext, data: CreateUserRequest) -> Result<User> {
// Your business logic here
Ok(User {
id: 1,
name: data.name,
email: data.email,
})
}
}
Services implement your business logic through the DogService trait:
#[async_trait]
pub trait DogService<TData, TQuery> {
type Output;
async fn create(&self, tenant: TenantContext, data: TData) -> Result<Self::Output>;
async fn read(&self, tenant: TenantContext, query: TQuery) -> Result<Self::Output>;
async fn update(&self, tenant: TenantContext, data: TData) -> Result<Self::Output>;
async fn delete(&self, tenant: TenantContext, query: TQuery) -> Result<()>;
}
Multi-tenant applications get built-in tenant isolation:
let tenant = TenantContext::new("tenant-123")
.with_actor("user-456")
.with_trace_id("req-789");
let result = service.create(tenant, request_data).await?;
Pluggable storage without vendor lock-in:
use dog_core::{StorageAdapter, StorageResult};
#[async_trait]
impl StorageAdapter for MyDatabase {
async fn get(&self, tenant: &TenantContext, key: &str) -> StorageResult<Option<Vec<u8>>>;
async fn put(&self, tenant: &TenantContext, key: &str, value: Vec<u8>) -> StorageResult<()>;
async fn delete(&self, tenant: &TenantContext, key: &str) -> StorageResult<()>;
}
dog-core follows a clean separation of concerns:
┌─────────────────┐
│ Your App │ ← Business logic
└─────────────────┘
│
┌────┼────┐
│ │ │
▼ │ ▼
┌─────────┐ ┌─────────────┐
│dog-axum │ │dog-typedb │ ← Adapters
│(HTTP) │ │(DB) │
└─────────┘ └─────────────┘
│
▼
┌─────────────────┐
│ dog-blob │ ← Object storage
│ (Storage) │
└─────────────────┘
│
▼
┌─────────────────┐
│ dog-core │ ← Core abstractions
└─────────────────┘
dog-core works with these adapters:
See the dog-examples/ directory for complete applications:
MIT OR Apache-2.0
Made by Jitpomi