Browse Source

Async traits

main
Julio Biason 3 years ago
parent
commit
2bec0c0fd0
  1. 12
      Cargo.lock
  2. 1
      lib/Cargo.toml
  3. 4
      lib/src/database.rs
  4. 13
      lib/src/domain/command.rs
  5. 8
      lib/src/domain/project/create.rs
  6. 8
      lib/src/domain/project/repository.rs

12
Cargo.lock generated

@ -28,6 +28,17 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "async-trait"
version = "0.1.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "atoi" name = "atoi"
version = "0.4.0" version = "0.4.0"
@ -455,6 +466,7 @@ dependencies = [
name = "lib" name = "lib"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-trait",
"directories", "directories",
"sqlx", "sqlx",
"tokio", "tokio",

1
lib/Cargo.toml

@ -7,3 +7,4 @@ edition = "2018"
directories = "3.0" directories = "3.0"
sqlx = { version = "0.5", default-features = false, features = [ "sqlite", "chrono", "macros", "migrate", "runtime-tokio-rustls"] } sqlx = { version = "0.5", default-features = false, features = [ "sqlite", "chrono", "macros", "migrate", "runtime-tokio-rustls"] }
tokio = { version = "1.6", features = [ "rt", "macros" ] } tokio = { version = "1.6", features = [ "rt", "macros" ] }
async-trait = "0.1"

4
lib/src/database.rs

@ -25,11 +25,11 @@ use sqlx::sqlite::SqliteConnectOptions;
use sqlx::sqlite::SqlitePoolOptions; use sqlx::sqlite::SqlitePoolOptions;
use sqlx::Pool; use sqlx::Pool;
async fn connect() -> Result<Pool<Sqlite>, sqlx::Error> { pub async fn connect() -> Result<Pool<Sqlite>, sqlx::Error> {
connect_with(&default_filename()).await connect_with(&default_filename()).await
} }
async fn connect_with(filename: &Path) -> Result<Pool<Sqlite>, sqlx::Error> { pub async fn connect_with(filename: &Path) -> Result<Pool<Sqlite>, sqlx::Error> {
let pool = SqlitePoolOptions::new() let pool = SqlitePoolOptions::new()
.connect_with( .connect_with(
SqliteConnectOptions::new() SqliteConnectOptions::new()

13
lib/src/domain/command.rs

@ -16,16 +16,27 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
use async_trait::async_trait;
/// Trait/tag for DTOs /// Trait/tag for DTOs
pub trait Dto {} pub trait Dto {}
/// Trait that all commands must implement. /// Trait that all commands must implement.
#[async_trait]
pub trait Command<T: Dto> { pub trait Command<T: Dto> {
async fn execute(self) -> Result<T, CommandError>; async fn execute(&self) -> Result<&T, CommandError>;
} }
/// Errors produced by invalid commands /// Errors produced by invalid commands
pub enum CommandError { pub enum CommandError {
/// The request identified used in the command is already used. /// The request identified used in the command is already used.
IdentifierAlreadyUsed(String), IdentifierAlreadyUsed(String),
/// Erro with the database
DatabaseError,
}
impl From<sqlx::Error> for CommandError {
fn from(_error: sqlx::Error) -> Self {
Self::DatabaseError
}
} }

8
lib/src/domain/project/create.rs

@ -16,6 +16,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
use async_trait::async_trait;
use super::dto::Project; use super::dto::Project;
use super::repository::Repository; use super::repository::Repository;
use crate::database; use crate::database;
@ -30,11 +32,13 @@ impl Create {
} }
} }
#[async_trait]
impl Command<Project> for Create { impl Command<Project> for Create {
async fn execute(self) -> Result<Project, CommandError> { async fn execute(&self) -> Result<&Project, CommandError> {
let pool = database::connect().await?; let pool = database::connect().await?;
let repo = Repository::new(&pool); let repo = Repository::new(&pool);
Ok(self.0) repo.save(&self.0).await?;
Ok(&self.0)
} }
} }

8
lib/src/domain/project/repository.rs

@ -21,21 +21,21 @@ use sqlx::Pool;
use super::dto::Project; use super::dto::Project;
struct Repository<'a> { pub struct Repository<'a> {
pool: &'a Pool<Sqlite>, pool: &'a Pool<Sqlite>,
} }
impl<'a> Repository<'a> { impl<'a> Repository<'a> {
fn new(pool: &'a Pool<Sqlite>) -> Self { pub fn new(pool: &'a Pool<Sqlite>) -> Self {
Self { pool } Self { pool }
} }
async fn save(&self, project: Project) -> Result<Project, sqlx::Error> { pub async fn save(&self, project: &Project) -> Result<(), sqlx::Error> {
sqlx::query(r#"INSERT INTO project (code, name) VALUES (?, ?)"#) sqlx::query(r#"INSERT INTO project (code, name) VALUES (?, ?)"#)
.bind(&project.code()) .bind(&project.code())
.bind(&project.name()) .bind(&project.name())
.execute(self.pool) .execute(self.pool)
.await?; .await?;
Ok(project) Ok(())
} }
} }

Loading…
Cancel
Save