Skip to content

Commit

Permalink
feat: setup links service (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
kentSarmiento authored Dec 18, 2023
1 parent a9d2396 commit 3cd10c9
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 76 deletions.
32 changes: 17 additions & 15 deletions src/controller/links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ use axum::{
};
use serde_json::json;

use crate::repository::DynLinksRepo;
use crate::types::state::Router as RouterState;

const LINKS_ROUTE: &str = "/v1/links";
const LINKS_ID_ROUTE: &str = "/v1/links/:id";

pub fn router() -> Router<DynLinksRepo> {
pub fn router() -> Router<RouterState> {
Router::new()
.route(LINKS_ROUTE, routing::get(list))
.route(LINKS_ROUTE, routing::post(post))
Expand All @@ -20,8 +20,9 @@ pub fn router() -> Router<DynLinksRepo> {
.route(LINKS_ID_ROUTE, routing::delete(delete))
}

async fn list(State(links_repo): State<DynLinksRepo>) -> impl IntoResponse {
match links_repo.list().await {
async fn list(State(app_state): State<RouterState>) -> impl IntoResponse {
let links_service = app_state.get_links_service();
match links_service.list(&app_state).await {
Ok(list) => Json(list).into_response(),
Err(e) => {
tracing::error!("Error: {}", e);
Expand All @@ -34,8 +35,9 @@ async fn list(State(links_repo): State<DynLinksRepo>) -> impl IntoResponse {
}
}

async fn post(State(links_repo): State<DynLinksRepo>) -> impl IntoResponse {
match links_repo.post().await {
async fn post(State(app_state): State<RouterState>) -> impl IntoResponse {
let links_service = app_state.get_links_service();
match links_service.post(&app_state).await {
Ok(link) => Json(link).into_response(),
Err(e) => {
tracing::error!("Error: {}", e);
Expand All @@ -48,8 +50,9 @@ async fn post(State(links_repo): State<DynLinksRepo>) -> impl IntoResponse {
}
}

async fn get(Path(id): Path<String>, State(links_repo): State<DynLinksRepo>) -> impl IntoResponse {
match links_repo.get(&id).await {
async fn get(Path(id): Path<String>, State(app_state): State<RouterState>) -> impl IntoResponse {
let links_service = app_state.get_links_service();
match links_service.get(&id, &app_state).await {
Ok(link) => Json(link).into_response(),
Err(e) => {
tracing::error!("Error: {}", e);
Expand All @@ -62,8 +65,9 @@ async fn get(Path(id): Path<String>, State(links_repo): State<DynLinksRepo>) ->
}
}

async fn put(Path(id): Path<String>, State(links_repo): State<DynLinksRepo>) -> impl IntoResponse {
match links_repo.put(&id).await {
async fn put(Path(id): Path<String>, State(app_state): State<RouterState>) -> impl IntoResponse {
let links_service = app_state.get_links_service();
match links_service.put(&id, &app_state).await {
Ok(link) => Json(link).into_response(),
Err(e) => {
tracing::error!("Error: {}", e);
Expand All @@ -76,11 +80,9 @@ async fn put(Path(id): Path<String>, State(links_repo): State<DynLinksRepo>) ->
}
}

async fn delete(
Path(id): Path<String>,
State(links_repo): State<DynLinksRepo>,
) -> impl IntoResponse {
match links_repo.delete(&id).await {
async fn delete(Path(id): Path<String>, State(app_state): State<RouterState>) -> impl IntoResponse {
let links_service = app_state.get_links_service();
match links_service.delete(&id, &app_state).await {
Ok(()) => StatusCode::NO_CONTENT.into_response(),
Err(e) => {
tracing::error!("Error: {}", e);
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ pub mod router;

mod controller;
mod repository;
mod service;
mod types;
44 changes: 1 addition & 43 deletions src/repository.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1 @@
use std::sync::Arc;

use axum::async_trait;
use serde::{Deserialize, Serialize};

pub mod sample;

pub type DynLinksRepo = Arc<dyn LinksRepo + Send + Sync>;
type RepoResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;

#[async_trait]
pub trait LinksRepo {
async fn list(&self) -> RepoResult<Vec<ListItem>> {
Err("Not implemented".into())
}

async fn post(&self) -> RepoResult<ListItem> {
Err("Not implemented".into())
}

async fn get(&self, _id: &str) -> RepoResult<ListItem> {
Err("Not implemented".into())
}

async fn put(&self, _id: &str) -> RepoResult<ListItem> {
Err("Not implemented".into())
}

async fn delete(&self, _id: &str) -> RepoResult<()> {
Err("Not implemented".into())
}
}

#[derive(Debug, Default, Serialize, Deserialize)]
pub struct ListItem {
id: String,
owner: String,
url: String,
title: String,
description: String,
created_at: String,
updated_at: String,
}
pub mod links;
15 changes: 15 additions & 0 deletions src/repository/links.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use axum::async_trait;

use crate::types::{
links::LinkItem,
repository::{Links, Result},
};

pub struct Repository {}

#[async_trait]
impl Links for Repository {
async fn list(&self) -> Result<Vec<LinkItem>> {
Ok(vec![])
}
}
12 changes: 0 additions & 12 deletions src/repository/sample.rs

This file was deleted.

17 changes: 11 additions & 6 deletions src/router.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use std::sync::Arc;

use axum::Router;
use crate::{
controller, repository, service,
types::{repository::DynLinks as DynLinksRepo, service::DynLinks as DynLinksService, state},
};

use crate::controller::links;
use crate::repository::{sample, DynLinksRepo};
pub fn new() -> axum::Router {
let links_repo = Arc::new(repository::links::Repository {}) as DynLinksRepo;
let links_service = Arc::new(service::links::Service {}) as DynLinksService;

pub fn new() -> Router {
let list_repo = Arc::new(sample::Repo {}) as DynLinksRepo;
Router::new().merge(links::router()).with_state(list_repo)
let state = state::Router::new(links_repo, links_service);
axum::Router::new()
.merge(controller::links::router())
.with_state(state)
}
1 change: 1 addition & 0 deletions src/service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod links;
37 changes: 37 additions & 0 deletions src/service/links.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use axum::async_trait;

use crate::types::{
links::LinkItem,
service::{Links, Result},
state,
};

pub struct Service {}

#[async_trait]
impl Links for Service {
async fn list<'a>(&self, app_state: &'a state::Router) -> Result<Vec<LinkItem>> {
let links_repo = app_state.get_links_repo();
links_repo.list().await
}

async fn post<'a>(&self, app_state: &'a state::Router) -> Result<LinkItem> {
let links_repo = app_state.get_links_repo();
links_repo.post().await
}

async fn get<'a>(&self, id: &str, app_state: &'a state::Router) -> Result<LinkItem> {
let links_repo = app_state.get_links_repo();
links_repo.get(id).await
}

async fn put<'a>(&self, id: &str, app_state: &'a state::Router) -> Result<LinkItem> {
let links_repo = app_state.get_links_repo();
links_repo.put(id).await
}

async fn delete<'a>(&self, id: &str, app_state: &'a state::Router) -> Result<()> {
let links_repo = app_state.get_links_repo();
links_repo.delete(id).await
}
}
4 changes: 4 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod links;
pub mod repository;
pub mod service;
pub mod state;
12 changes: 12 additions & 0 deletions src/types/links.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Default, Serialize, Deserialize)]
pub struct LinkItem {
id: String,
owner: String,
url: String,
title: String,
description: String,
created_at: String,
updated_at: String,
}
31 changes: 31 additions & 0 deletions src/types/repository.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use std::sync::Arc;

use axum::async_trait;

use super::links::LinkItem;

pub type DynLinks = Arc<dyn Links + Send + Sync>;
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

#[async_trait]
pub trait Links {
async fn list(&self) -> Result<Vec<LinkItem>> {
Err("Not implemented".into())
}

async fn post(&self) -> Result<LinkItem> {
Err("Not implemented".into())
}

async fn get(&self, _id: &str) -> Result<LinkItem> {
Err("Not implemented".into())
}

async fn put(&self, _id: &str) -> Result<LinkItem> {
Err("Not implemented".into())
}

async fn delete(&self, _id: &str) -> Result<()> {
Err("Not implemented".into())
}
}
31 changes: 31 additions & 0 deletions src/types/service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use std::sync::Arc;

use axum::async_trait;

use super::{links::LinkItem, state};

pub type DynLinks = Arc<dyn Links + Send + Sync>;
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

#[async_trait]
pub trait Links {
async fn list<'a>(&self, _app_state: &'a state::Router) -> Result<Vec<LinkItem>> {
Err("Not implemented".into())
}

async fn post<'a>(&self, _app_state: &'a state::Router) -> Result<LinkItem> {
Err("Not implemented".into())
}

async fn get<'a>(&self, _id: &str, _app_state: &'a state::Router) -> Result<LinkItem> {
Err("Not implemented".into())
}

async fn put<'a>(&self, _id: &str, _app_state: &'a state::Router) -> Result<LinkItem> {
Err("Not implemented".into())
}

async fn delete<'a>(&self, _id: &str, _app_state: &'a state::Router) -> Result<()> {
Err("Not implemented".into())
}
}
24 changes: 24 additions & 0 deletions src/types/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use super::{repository::DynLinks as DynLinksRepo, service::DynLinks as DynLinksService};

#[derive(Clone)]
pub struct Router {
links_repo: DynLinksRepo,
links_service: DynLinksService,
}

impl Router {
pub fn new(links_repo: DynLinksRepo, links_service: DynLinksService) -> Self {
Self {
links_repo,
links_service,
}
}

pub fn get_links_repo(&self) -> &DynLinksRepo {
&self.links_repo
}

pub fn get_links_service(&self) -> &DynLinksService {
&self.links_service
}
}

0 comments on commit 3cd10c9

Please sign in to comment.