fn main() -> hexser::HexResult<()> {
println!("=== Simple TODO Application ===\n");
let mut repo = InMemoryTodoRepository::new();
let todo = Todo {
id: String::from("1"),
title: String::from("Learn hexagonal architecture"),
completed: false,
};
println!("Creating todo: {}", todo.title);
<InMemoryTodoRepository as hexser::ports::Repository<Todo>>::save(&mut repo, todo)?;
let all = <InMemoryTodoRepository as hexser::ports::repository::QueryRepository<Todo>>::find(
&repo,
&TodoFilter::All,
hexser::ports::repository::FindOptions::default(),
)?;
println!("Total todos: {}", all.len());
if let Some(found) = <InMemoryTodoRepository as hexser::ports::repository::QueryRepository<
Todo,
>>::find_one(&repo, &TodoFilter::ById(String::from("1")))?
{
println!(
"Found todo: {} (completed: {})",
found.title, found.completed
);
}
if let Some(mut todo) = <InMemoryTodoRepository as hexser::ports::repository::QueryRepository<
Todo,
>>::find_one(&repo, &TodoFilter::ById(String::from("1")))?
{
todo.completed = true;
<InMemoryTodoRepository as hexser::ports::Repository<Todo>>::save(&mut repo, todo)?;
println!("Todo marked as completed");
}
let _removed =
<InMemoryTodoRepository as hexser::ports::repository::QueryRepository<Todo>>::delete_where(
&mut repo,
&TodoFilter::ById(String::from("1")),
)?;
println!("Todo deleted");
println!("\n✅ Example completed successfully!");
Ok(())
}
#[derive(Clone)]
struct Todo {
id: String,
title: String,
completed: bool,
}
impl hexser::domain::HexEntity for Todo {
type Id = String;
}
struct InMemoryTodoRepository {
todos: Vec<Todo>,
}
impl InMemoryTodoRepository {
fn new() -> Self {
Self { todos: Vec::new() }
}
}
impl hexser::adapters::Adapter for InMemoryTodoRepository {}
impl hexser::ports::Repository<Todo> for InMemoryTodoRepository {
fn save(&mut self, todo: Todo) -> hexser::HexResult<()> {
if let Some(existing) = self.todos.iter_mut().find(|t| t.id == todo.id) {
*existing = todo;
} else {
self.todos.push(todo);
}
Ok(())
}
}
#[derive(Clone)]
enum TodoFilter {
All,
ById(String),
}
#[derive(Clone, Copy)]
enum TodoSortKey {
Id,
}
impl hexser::ports::repository::QueryRepository<Todo> for InMemoryTodoRepository {
type Filter = TodoFilter;
type SortKey = TodoSortKey;
fn find_one(&self, filter: &TodoFilter) -> hexser::HexResult<Option<Todo>> {
let found = match filter {
TodoFilter::All => self.todos.first().cloned(),
TodoFilter::ById(id) => self.todos.iter().find(|t| &t.id == id).cloned(),
};
Ok(found)
}
fn find(
&self,
filter: &TodoFilter,
_opts: hexser::ports::repository::FindOptions<TodoSortKey>,
) -> hexser::HexResult<Vec<Todo>> {
let items: Vec<Todo> = match filter {
TodoFilter::All => self.todos.clone(),
TodoFilter::ById(id) => self.todos.iter().filter(|t| &t.id == id).cloned().collect(),
};
Ok(items)
}
fn delete_where(&mut self, filter: &TodoFilter) -> hexser::HexResult<u64> {
let before = self.todos.len();
match filter {
TodoFilter::All => self.todos.clear(),
TodoFilter::ById(id) => self.todos.retain(|t| &t.id != id),
}
Ok((before.saturating_sub(self.todos.len())) as u64)
}
}