Skip to content

Instantly share code, notes, and snippets.

@matthewjberger
Last active February 11, 2023 02:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewjberger/425f5ca468cdbc4a66efeb94b0653692 to your computer and use it in GitHub Desktop.
Save matthewjberger/425f5ca468cdbc4a66efeb94b0653692 to your computer and use it in GitHub Desktop.
layered architecture in rust
// Layer 1: Domain
#[derive(Clone)]
pub struct User {
pub id: i32,
pub name: String,
pub email: String,
}
// Layer 2: Data Access
pub trait UserRepository {
fn find_by_id(&self, id: i32) -> Option<User>;
fn save(&mut self, user: &User) -> Result<(), String>;
}
// Layer 3: Application
pub struct UserService<R: UserRepository> {
user_repository: R,
}
impl<R: UserRepository> UserService<R> {
pub fn new(user_repository: R) -> Self {
Self { user_repository }
}
pub fn find_user_by_id(&self, id: i32) -> Option<User> {
self.user_repository.find_by_id(id)
}
pub fn save_user(&mut self, user: &User) -> Result<(), String> {
self.user_repository.save(user)
}
}
// Layer 4: Infrastructure
#[derive(Default)]
pub struct InMemoryUserRepository {
users: Vec<User>,
}
impl UserRepository for InMemoryUserRepository {
fn find_by_id(&self, id: i32) -> Option<User> {
self.users.iter().find(|u| u.id == id).cloned()
}
fn save(&mut self, user: &User) -> Result<(), String> {
self.users.push(user.clone());
Ok(())
}
}
// Layer 5: Main
fn main() {
let user_repository = InMemoryUserRepository::default();
let mut user_service = UserService::new(user_repository);
let new_user = User {
id: 1,
name: "John Doe".to_string(),
email: "john.doe@example.com".to_string(),
};
match user_service.save_user(&new_user) {
Ok(_) => println!("User saved successfully"),
Err(err) => println!("Error saving user: {}", err),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment