Compare commits
	
		
			1 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4970e2570a | 
							
								
								
									
										5
									
								
								.env
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								.env
									
									
									
									
									
								
							@@ -1 +1,4 @@
 | 
			
		||||
DATABASE_URL=postgres://postgres:password@localhost/olh
 | 
			
		||||
APP_ENV=development
 | 
			
		||||
APP_LOKI_ENDPOINT=http://localhost:3100/loki/api/v1/push
 | 
			
		||||
APP_LOG_LEVEL=info
 | 
			
		||||
APP_PORT=3000
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,22 +1 @@
 | 
			
		||||
/target
 | 
			
		||||
/migration/target
 | 
			
		||||
 | 
			
		||||
# Added by cargo
 | 
			
		||||
#
 | 
			
		||||
# already existing elements were commented out
 | 
			
		||||
 | 
			
		||||
#/target
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Added by cargo
 | 
			
		||||
#
 | 
			
		||||
# already existing elements were commented out
 | 
			
		||||
 | 
			
		||||
#/target
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Added by cargo
 | 
			
		||||
#
 | 
			
		||||
# already existing elements were commented out
 | 
			
		||||
 | 
			
		||||
#/target
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1409
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1409
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										14
									
								
								Cargo.toml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Cargo.toml
									
									
									
									
									
								
							@@ -2,17 +2,11 @@
 | 
			
		||||
name = "openlayerhub"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
build = "build.rs"
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
anyhow = "1.0.95"
 | 
			
		||||
async-trait = "0.1.86"
 | 
			
		||||
axum = { version = "0.8.1", features = ["json"] }
 | 
			
		||||
diesel = { version = "2.2.7", features = ["postgres", "r2d2", "serde_json"] }
 | 
			
		||||
config = "0.15.7"
 | 
			
		||||
dotenvy = "0.15.7"
 | 
			
		||||
r2d2 = "0.8.10"
 | 
			
		||||
serde = { version = "1.0.217", features = ["derive"] }
 | 
			
		||||
serde_json = "1.0.138"
 | 
			
		||||
tokio = { version = "1.43.0", features = ["full"] }
 | 
			
		||||
tower = "0.5.2"
 | 
			
		||||
utoipa = { version = "5.3.1", features = ["axum_extras"] }
 | 
			
		||||
utoipa-swagger-ui = { version = "9.0.0", features = ["axum"] }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								build.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								build.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::process::Command;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let is_production = env::var("APP_ENV")
 | 
			
		||||
        .map(|e| e == "production")
 | 
			
		||||
        .unwrap_or(false);
 | 
			
		||||
 | 
			
		||||
    let version = if is_production {
 | 
			
		||||
        get_latest_tag().unwrap_or_else(|| panic!("Production builds must have a GIT tag."))
 | 
			
		||||
    } else {
 | 
			
		||||
        get_commit_hash().unwrap_or_else(|| env!("CARGO_PKG_VERSION").to_string())
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    println!("cargo:rustc-env=GIT_VERSION={}", version)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_commit_hash() -> Option<String> {
 | 
			
		||||
    let output = Command::new("git")
 | 
			
		||||
        .args(&["rev-parse", "--short=8", "HEAD"])
 | 
			
		||||
        .output()
 | 
			
		||||
        .ok()?;
 | 
			
		||||
 | 
			
		||||
    if !output.status.success() {
 | 
			
		||||
        return None;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String::from_utf8(output.stdout)
 | 
			
		||||
        .ok()
 | 
			
		||||
        .map(|s| s.trim().to_string())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_latest_tag() -> Option<String> {
 | 
			
		||||
    let output = Command::new("git")
 | 
			
		||||
        .args(&["describe", "--tags",  "--match", "v*"])
 | 
			
		||||
        .output()
 | 
			
		||||
        .ok()?;
 | 
			
		||||
 | 
			
		||||
    if !output.status.success() {
 | 
			
		||||
        return None;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String::from_utf8(output.stdout)
 | 
			
		||||
        .ok()
 | 
			
		||||
        .map(|s| s.trim().to_string())
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
# For documentation on how to configure this file,
 | 
			
		||||
# see https://diesel.rs/guides/configuring-diesel-cli
 | 
			
		||||
 | 
			
		||||
[print_schema]
 | 
			
		||||
file = "src/schema.rs"
 | 
			
		||||
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
 | 
			
		||||
 | 
			
		||||
[migrations_directory]
 | 
			
		||||
dir = "migrations"
 | 
			
		||||
							
								
								
									
										516
									
								
								log
									
									
									
									
									
								
							
							
						
						
									
										516
									
								
								log
									
									
									
									
									
								
							@@ -1,516 +0,0 @@
 | 
			
		||||
   Compiling openlayerhub v0.1.0 (/home/nicolaivds/GIT/OpenLayerHub)
 | 
			
		||||
error[E0277]: the trait bound `InsertStatement<<T as HasTable>::Table, <T as diesel::Insertable<<T as HasTable>::Table>>::Values>: LoadQuery<'_, _, _>` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:60:25
 | 
			
		||||
     |
 | 
			
		||||
60   |             .get_result(&mut conn)
 | 
			
		||||
     |              ---------- ^^^^^^^^^ the trait `AsQuery` is not implemented for `InsertStatement<<T as HasTable>::Table, <T as diesel::Insertable<<T as HasTable>::Table>>::Values>`, which is required by `InsertStatement<<T as HasTable>::Table, <T as diesel::Insertable<<T as HasTable>::Table>>::Values>: LoadQuery<'_, _, _>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `InsertStatement<<T as HasTable>::Table, <T as diesel::Insertable<<T as HasTable>::Table>>::Values>` to implement `LoadQuery<'_, _, _>`
 | 
			
		||||
note: required by a bound in `get_result`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1722:15
 | 
			
		||||
     |
 | 
			
		||||
1720 |     fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>
 | 
			
		||||
     |        ---------- required by a bound in this associated function
 | 
			
		||||
1721 |     where
 | 
			
		||||
1722 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result`
 | 
			
		||||
help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
 | 
			
		||||
     |
 | 
			
		||||
54   |     i32: diesel::deserialize::FromSql<diesel::sql_types::Integer, Conn::Backend>, InsertStatement<<T as HasTable>::Table, <T as diesel::Insertable<<T as HasTable>::Table>>::Values>: AsQuery
 | 
			
		||||
     |                                                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `Conn: LoadConnection` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:60:25
 | 
			
		||||
     |
 | 
			
		||||
60   |             .get_result(&mut conn)
 | 
			
		||||
     |              ---------- ^^^^^^^^^ the trait `LoadConnection` is not implemented for `Conn`, which is required by `InsertStatement<<T as HasTable>::Table, <T as diesel::Insertable<<T as HasTable>::Table>>::Values>: LoadQuery<'_, _, _>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `PooledConnection<ConnectionManager<Conn>>` to implement `LoadConnection`
 | 
			
		||||
     = note: required for `InsertStatement<<T as HasTable>::Table, <T as diesel::Insertable<<T as HasTable>::Table>>::Values>` to implement `LoadQuery<'_, PooledConnection<ConnectionManager<Conn>>, _>`
 | 
			
		||||
note: required by a bound in `get_result`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1722:15
 | 
			
		||||
     |
 | 
			
		||||
1720 |     fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>
 | 
			
		||||
     |        ---------- required by a bound in this associated function
 | 
			
		||||
1721 |     where
 | 
			
		||||
1722 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result`
 | 
			
		||||
help: consider further restricting this bound
 | 
			
		||||
     |
 | 
			
		||||
50   |     Conn: diesel::Connection + R2D2Connection + 'static + diesel::connection::LoadConnection,
 | 
			
		||||
     |                                                         ++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as HasTable>::Table: SingleValue` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:60:25
 | 
			
		||||
     |
 | 
			
		||||
60   |             .get_result(&mut conn)
 | 
			
		||||
     |              ---------- ^^^^^^^^^ the trait `SingleValue` is not implemented for `<T as HasTable>::Table`, which is required by `InsertStatement<<T as HasTable>::Table, <T as diesel::Insertable<<T as HasTable>::Table>>::Values>: LoadQuery<'_, _, _>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `<T as HasTable>::Table` to implement `SqlTypeOrSelectable`
 | 
			
		||||
     = note: required for `T` to implement `FromSqlRow<<T as HasTable>::Table, <Conn as Connection>::Backend>`
 | 
			
		||||
     = note: required for `InsertStatement<<T as HasTable>::Table, <T as diesel::Insertable<<T as HasTable>::Table>>::Values>` to implement `LoadQuery<'_, PooledConnection<ConnectionManager<Conn>>, T>`
 | 
			
		||||
note: required by a bound in `get_result`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1722:15
 | 
			
		||||
     |
 | 
			
		||||
1720 |     fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>
 | 
			
		||||
     |        ---------- required by a bound in this associated function
 | 
			
		||||
1721 |     where
 | 
			
		||||
1722 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result`
 | 
			
		||||
 | 
			
		||||
error[E0275]: overflow evaluating the requirement `_: Sized`
 | 
			
		||||
  --> src/base/service.rs:67:14
 | 
			
		||||
   |
 | 
			
		||||
67 |             .filter(T::primary_key().eq(id))
 | 
			
		||||
   |              ^^^^^^
 | 
			
		||||
   |
 | 
			
		||||
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`openlayerhub`)
 | 
			
		||||
   = note: required for `<<T as HasTable>::Table as AsQuery>::Query` to implement `FilterDsl<_>`
 | 
			
		||||
 | 
			
		||||
error[E0277]: `<<T as HasTable>::Table as AsQuery>::Query` is no valid SQL fragment for the `_` backend
 | 
			
		||||
    --> src/base/service.rs:77:24
 | 
			
		||||
     |
 | 
			
		||||
77   |             .load::<T>(&mut conn)
 | 
			
		||||
     |              ----      ^^^^^^^^^ the trait `QueryFragment<_>` is not implemented for `<<T as HasTable>::Table as AsQuery>::Query`, which is required by `<T as HasTable>::Table: LoadQuery<'_, _, T>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: this usually means that the `_` database system does not support 
 | 
			
		||||
             this SQL syntax
 | 
			
		||||
     = help: the following other types implement trait `QueryFragment<DB, SP>`:
 | 
			
		||||
               `&T` implements `QueryFragment<DB>`
 | 
			
		||||
               `()` implements `QueryFragment<DB>`
 | 
			
		||||
               `(T0, T1)` implements `QueryFragment<__DB>`
 | 
			
		||||
               `(T0, T1, T2)` implements `QueryFragment<__DB>`
 | 
			
		||||
               `(T0, T1, T2, T3)` implements `QueryFragment<__DB>`
 | 
			
		||||
               `(T0, T1, T2, T3, T4)` implements `QueryFragment<__DB>`
 | 
			
		||||
               `(T0, T1, T2, T3, T4, T5)` implements `QueryFragment<__DB>`
 | 
			
		||||
               `(T0, T1, T2, T3, T4, T5, T6)` implements `QueryFragment<__DB>`
 | 
			
		||||
             and 278 others
 | 
			
		||||
     = note: required for `<T as HasTable>::Table` to implement `LoadQuery<'_, _, T>`
 | 
			
		||||
note: required by a bound in `diesel::RunQueryDsl::load`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1542:15
 | 
			
		||||
     |
 | 
			
		||||
1540 |     fn load<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>
 | 
			
		||||
     |        ---- required by a bound in this associated function
 | 
			
		||||
1541 |     where
 | 
			
		||||
1542 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<<T as HasTable>::Table as AsQuery>::Query: QueryId` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:77:24
 | 
			
		||||
     |
 | 
			
		||||
77   |             .load::<T>(&mut conn)
 | 
			
		||||
     |              ----      ^^^^^^^^^ the trait `QueryId` is not implemented for `<<T as HasTable>::Table as AsQuery>::Query`, which is required by `<T as HasTable>::Table: LoadQuery<'_, _, T>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `<T as HasTable>::Table` to implement `LoadQuery<'_, _, T>`
 | 
			
		||||
note: required by a bound in `diesel::RunQueryDsl::load`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1542:15
 | 
			
		||||
     |
 | 
			
		||||
1540 |     fn load<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>
 | 
			
		||||
     |        ---- required by a bound in this associated function
 | 
			
		||||
1541 |     where
 | 
			
		||||
1542 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<<T as HasTable>::Table as AsQuery>::SqlType: SingleValue` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:77:24
 | 
			
		||||
     |
 | 
			
		||||
77   |             .load::<T>(&mut conn)
 | 
			
		||||
     |              ----      ^^^^^^^^^ the trait `SingleValue` is not implemented for `<<T as HasTable>::Table as AsQuery>::SqlType`, which is required by `<T as HasTable>::Table: LoadQuery<'_, _, T>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `<<T as HasTable>::Table as AsQuery>::SqlType` to implement `load_dsl::private::CompatibleType<T, _>`
 | 
			
		||||
     = note: required for `<T as HasTable>::Table` to implement `LoadQuery<'_, _, T>`
 | 
			
		||||
note: required by a bound in `diesel::RunQueryDsl::load`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1542:15
 | 
			
		||||
     |
 | 
			
		||||
1540 |     fn load<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>
 | 
			
		||||
     |        ---- required by a bound in this associated function
 | 
			
		||||
1541 |     where
 | 
			
		||||
1542 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `T: diesel::Queryable<<<T as HasTable>::Table as AsQuery>::SqlType, _>` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:77:24
 | 
			
		||||
     |
 | 
			
		||||
77   |             .load::<T>(&mut conn)
 | 
			
		||||
     |              ----      ^^^^^^^^^ the trait `diesel::Queryable<<<T as HasTable>::Table as AsQuery>::SqlType, _>` is not implemented for `T`, which is required by `<T as HasTable>::Table: LoadQuery<'_, _, T>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = help: the following other types implement trait `diesel::Queryable<ST, DB>`:
 | 
			
		||||
               `(T0, T1)` implements `diesel::Queryable<(ST0, ST1), __DB>`
 | 
			
		||||
               `(T0, T1)` implements `diesel::Queryable<Record<(ST0, ST1)>, Pg>`
 | 
			
		||||
               `(T0, T1, T2)` implements `diesel::Queryable<(ST0, ST1, ST2), __DB>`
 | 
			
		||||
               `(T0, T1, T2)` implements `diesel::Queryable<Record<(ST0, ST1, ST2)>, Pg>`
 | 
			
		||||
               `(T0, T1, T2, T3)` implements `diesel::Queryable<(ST0, ST1, ST2, ST3), __DB>`
 | 
			
		||||
               `(T0, T1, T2, T3)` implements `diesel::Queryable<Record<(ST0, ST1, ST2, ST3)>, Pg>`
 | 
			
		||||
               `(T0, T1, T2, T3, T4)` implements `diesel::Queryable<(ST0, ST1, ST2, ST3, ST4), __DB>`
 | 
			
		||||
               `(T0, T1, T2, T3, T4)` implements `diesel::Queryable<Record<(ST0, ST1, ST2, ST3, ST4)>, Pg>`
 | 
			
		||||
             and 116 others
 | 
			
		||||
     = note: required for `T` to implement `FromSqlRow<<<T as HasTable>::Table as AsQuery>::SqlType, _>`
 | 
			
		||||
     = note: required for `<<T as HasTable>::Table as AsQuery>::SqlType` to implement `load_dsl::private::CompatibleType<T, _>`
 | 
			
		||||
     = note: required for `<T as HasTable>::Table` to implement `LoadQuery<'_, _, T>`
 | 
			
		||||
note: required by a bound in `diesel::RunQueryDsl::load`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1542:15
 | 
			
		||||
     |
 | 
			
		||||
1540 |     fn load<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>
 | 
			
		||||
     |        ---- required by a bound in this associated function
 | 
			
		||||
1541 |     where
 | 
			
		||||
1542 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `Conn: LoadConnection` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:77:24
 | 
			
		||||
     |
 | 
			
		||||
77   |             .load::<T>(&mut conn)
 | 
			
		||||
     |              ----      ^^^^^^^^^ the trait `LoadConnection` is not implemented for `Conn`, which is required by `<T as HasTable>::Table: LoadQuery<'_, _, T>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `PooledConnection<ConnectionManager<Conn>>` to implement `LoadConnection`
 | 
			
		||||
     = note: required for `<T as HasTable>::Table` to implement `LoadQuery<'_, PooledConnection<ConnectionManager<Conn>>, T>`
 | 
			
		||||
note: required by a bound in `diesel::RunQueryDsl::load`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1542:15
 | 
			
		||||
     |
 | 
			
		||||
1540 |     fn load<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>
 | 
			
		||||
     |        ---- required by a bound in this associated function
 | 
			
		||||
1541 |     where
 | 
			
		||||
1542 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load`
 | 
			
		||||
help: consider further restricting this bound
 | 
			
		||||
     |
 | 
			
		||||
50   |     Conn: diesel::Connection + R2D2Connection + 'static + diesel::connection::LoadConnection,
 | 
			
		||||
     |                                                         ++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<Conn as Connection>::Backend: QueryMetadata<<<T as HasTable>::Table as AsQuery>::SqlType>` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:77:24
 | 
			
		||||
     |
 | 
			
		||||
77   |             .load::<T>(&mut conn)
 | 
			
		||||
     |              ----      ^^^^^^^^^ the trait `HasSqlType<<<T as HasTable>::Table as AsQuery>::SqlType>` is not implemented for `<Conn as Connection>::Backend`, which is required by `<T as HasTable>::Table: LoadQuery<'_, _, T>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `<Conn as Connection>::Backend` to implement `QueryMetadata<<<T as HasTable>::Table as AsQuery>::SqlType>`
 | 
			
		||||
     = note: required for `<T as HasTable>::Table` to implement `LoadQuery<'_, PooledConnection<ConnectionManager<Conn>>, T>`
 | 
			
		||||
note: required by a bound in `diesel::RunQueryDsl::load`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1542:15
 | 
			
		||||
     |
 | 
			
		||||
1540 |     fn load<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>
 | 
			
		||||
     |        ---- required by a bound in this associated function
 | 
			
		||||
1541 |     where
 | 
			
		||||
1542 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as HasTable>::Table: IntoUpdateTarget` is not satisfied
 | 
			
		||||
  --> src/base/service.rs:83:24
 | 
			
		||||
   |
 | 
			
		||||
83 |         diesel::update(<T as HasTable>::table())
 | 
			
		||||
   |         -------------- ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::Identifiable` is not implemented for `<T as HasTable>::Table`, which is required by `<T as HasTable>::Table: IntoUpdateTarget`
 | 
			
		||||
   |         |
 | 
			
		||||
   |         required by a bound introduced by this call
 | 
			
		||||
   |
 | 
			
		||||
   = note: required for `<T as HasTable>::Table` to implement `IntoUpdateTarget`
 | 
			
		||||
note: required by a bound in `update`
 | 
			
		||||
  --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_builder/functions.rs:80:18
 | 
			
		||||
   |
 | 
			
		||||
80 | pub fn update<T: IntoUpdateTarget>(source: T) -> UpdateStatement<T::Table, T::WhereClause> {
 | 
			
		||||
   |                  ^^^^^^^^^^^^^^^^ required by this bound in `update`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as HasTable>::Table: HasTable` is not satisfied
 | 
			
		||||
  --> src/base/service.rs:83:9
 | 
			
		||||
   |
 | 
			
		||||
83 |         diesel::update(<T as HasTable>::table())
 | 
			
		||||
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasTable` is not implemented for `<T as HasTable>::Table`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as Model>::PrimaryKey: AppearsOnTable<_>` is not satisfied
 | 
			
		||||
  --> src/base/service.rs:84:14
 | 
			
		||||
   |
 | 
			
		||||
84 |             .filter(T::primary_key().eq(id))
 | 
			
		||||
   |              ^^^^^^ the trait `AppearsOnTable<_>` is not implemented for `<T as Model>::PrimaryKey`, which is required by `UpdateStatement<_, _>: FilterDsl<_>`
 | 
			
		||||
   |
 | 
			
		||||
   = help: the following other types implement trait `AppearsOnTable<QS>`:
 | 
			
		||||
             `&'a T` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4, T5)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4, T5, T6)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4, T5, T6, T7)` implements `AppearsOnTable<QS>`
 | 
			
		||||
           and 131 others
 | 
			
		||||
   = note: required for `diesel::expression::operators::Eq<<T as Model>::PrimaryKey, diesel::expression::bound::Bound<Integer, i32>>` to implement `AppearsOnTable<_>`
 | 
			
		||||
   = note: 1 redundant requirement hidden
 | 
			
		||||
   = note: required for `Grouped<Eq<<T as Model>::PrimaryKey, Bound<Integer, i32>>>` to implement `AppearsOnTable<_>`
 | 
			
		||||
   = note: required for `UpdateStatement<_, _>` to implement `FilterDsl<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<<T as Model>::PrimaryKey, diesel::expression::bound::Bound<Integer, i32>>>>`
 | 
			
		||||
   = note: the full name for the type has been written to '/home/nicolaivds/GIT/OpenLayerHub/target/debug/deps/openlayerhub-1f7d339452a03941.long-type-9065444121950834043.txt'
 | 
			
		||||
   = note: consider using `--verbose` to print the full type name to the console
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as Model>::PrimaryKey: AppearsOnTable<_>` is not satisfied
 | 
			
		||||
  --> src/base/service.rs:84:21
 | 
			
		||||
   |
 | 
			
		||||
84 |             .filter(T::primary_key().eq(id))
 | 
			
		||||
   |              ------ ^^^^^^^^^^^^^^^^^^^^^^^ the trait `AppearsOnTable<_>` is not implemented for `<T as Model>::PrimaryKey`, which is required by `UpdateStatement<_, _>: FilterDsl<_>`
 | 
			
		||||
   |              |
 | 
			
		||||
   |              required by a bound introduced by this call
 | 
			
		||||
   |
 | 
			
		||||
   = help: the following other types implement trait `AppearsOnTable<QS>`:
 | 
			
		||||
             `&'a T` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4, T5)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4, T5, T6)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4, T5, T6, T7)` implements `AppearsOnTable<QS>`
 | 
			
		||||
           and 131 others
 | 
			
		||||
   = note: required for `diesel::expression::operators::Eq<<T as Model>::PrimaryKey, diesel::expression::bound::Bound<Integer, i32>>` to implement `AppearsOnTable<_>`
 | 
			
		||||
   = note: 1 redundant requirement hidden
 | 
			
		||||
   = note: required for `Grouped<Eq<<T as Model>::PrimaryKey, Bound<Integer, i32>>>` to implement `AppearsOnTable<_>`
 | 
			
		||||
   = note: required for `UpdateStatement<_, _>` to implement `FilterDsl<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<<T as Model>::PrimaryKey, diesel::expression::bound::Bound<Integer, i32>>>>`
 | 
			
		||||
note: required by a bound in `UpdateStatement::<T, U, V, Ret>::filter`
 | 
			
		||||
  --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_builder/update_statement/mod.rs:98:15
 | 
			
		||||
   |
 | 
			
		||||
96 |     pub fn filter<Predicate>(self, predicate: Predicate) -> Filter<Self, Predicate>
 | 
			
		||||
   |            ------ required by a bound in this associated function
 | 
			
		||||
97 |     where
 | 
			
		||||
98 |         Self: FilterDsl<Predicate>,
 | 
			
		||||
   |               ^^^^^^^^^^^^^^^^^^^^ required by this bound in `UpdateStatement::<T, U, V, Ret>::filter`
 | 
			
		||||
   = note: the full name for the type has been written to '/home/nicolaivds/GIT/OpenLayerHub/target/debug/deps/openlayerhub-1f7d339452a03941.long-type-9065444121950834043.txt'
 | 
			
		||||
   = note: consider using `--verbose` to print the full type name to the console
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `&T: diesel::AsChangeset` is not satisfied
 | 
			
		||||
  --> src/base/service.rs:85:18
 | 
			
		||||
   |
 | 
			
		||||
85 |             .set(&entity)
 | 
			
		||||
   |              --- ^^^^^^^ the trait `diesel::AsChangeset` is not implemented for `&T`
 | 
			
		||||
   |              |
 | 
			
		||||
   |              required by a bound introduced by this call
 | 
			
		||||
   |
 | 
			
		||||
note: required by a bound in `UpdateStatement::<T, U>::set`
 | 
			
		||||
  --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_builder/update_statement/mod.rs:38:12
 | 
			
		||||
   |
 | 
			
		||||
35 |     pub fn set<V>(self, values: V) -> UpdateStatement<T, U, V::Changeset>
 | 
			
		||||
   |            --- required by a bound in this associated function
 | 
			
		||||
...
 | 
			
		||||
38 |         V: changeset::AsChangeset<Target = T>,
 | 
			
		||||
   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UpdateStatement::<T, U>::set`
 | 
			
		||||
help: consider removing the leading `&`-reference
 | 
			
		||||
   |
 | 
			
		||||
85 -             .set(&entity)
 | 
			
		||||
85 +             .set(entity)
 | 
			
		||||
   |
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<Conn as Connection>::Backend: DieselReserveSpecialization` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:86:25
 | 
			
		||||
     |
 | 
			
		||||
86   |             .get_result(&mut conn)
 | 
			
		||||
     |              ---------- ^^^^^^^^^ the trait `DieselReserveSpecialization` is not implemented for `<Conn as Connection>::Backend`, which is required by `UpdateStatement<_, _, _>: LoadQuery<'_, _, _>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `UpdateStatement<_, _, _, ReturningClause<_>>` to implement `QueryFragment<<Conn as Connection>::Backend>`
 | 
			
		||||
     = note: required for `UpdateStatement<_, _, _>` to implement `LoadQuery<'_, PooledConnection<ConnectionManager<Conn>>, _>`
 | 
			
		||||
note: required by a bound in `get_result`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1722:15
 | 
			
		||||
     |
 | 
			
		||||
1720 |     fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>
 | 
			
		||||
     |        ---------- required by a bound in this associated function
 | 
			
		||||
1721 |     where
 | 
			
		||||
1722 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result`
 | 
			
		||||
 | 
			
		||||
error[E0277]: `ReturningClause<_>` is no valid SQL fragment for the `<Conn as Connection>::Backend` backend
 | 
			
		||||
    --> src/base/service.rs:86:25
 | 
			
		||||
     |
 | 
			
		||||
86   |             .get_result(&mut conn)
 | 
			
		||||
     |              ---------- ^^^^^^^^^ the trait `QueryFragment<<Conn as Connection>::Backend, <<Conn as Connection>::Backend as SqlDialect>::ReturningClause>` is not implemented for `ReturningClause<_>`, which is required by `UpdateStatement<_, _, _>: LoadQuery<'_, _, _>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: this usually means that the `<Conn as Connection>::Backend` database system does not support 
 | 
			
		||||
             this SQL syntax
 | 
			
		||||
     = help: the following other types implement trait `QueryFragment<DB, SP>`:
 | 
			
		||||
               `ReturningClause<Expr>` implements `QueryFragment<DB, PgLikeReturningClause>`
 | 
			
		||||
               `ReturningClause<Expr>` implements `QueryFragment<DB>`
 | 
			
		||||
     = note: required for `ReturningClause<_>` to implement `QueryFragment<<Conn as Connection>::Backend>`
 | 
			
		||||
     = note: 1 redundant requirement hidden
 | 
			
		||||
     = note: required for `UpdateStatement<_, _, _, ReturningClause<_>>` to implement `QueryFragment<<Conn as Connection>::Backend>`
 | 
			
		||||
     = note: required for `UpdateStatement<_, _, _>` to implement `LoadQuery<'_, PooledConnection<ConnectionManager<Conn>>, _>`
 | 
			
		||||
note: required by a bound in `get_result`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1722:15
 | 
			
		||||
     |
 | 
			
		||||
1720 |     fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>
 | 
			
		||||
     |        ---------- required by a bound in this associated function
 | 
			
		||||
1721 |     where
 | 
			
		||||
1722 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `Conn: LoadConnection` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:86:25
 | 
			
		||||
     |
 | 
			
		||||
86   |             .get_result(&mut conn)
 | 
			
		||||
     |              ---------- ^^^^^^^^^ the trait `LoadConnection` is not implemented for `Conn`, which is required by `UpdateStatement<_, _, _>: LoadQuery<'_, _, _>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `PooledConnection<ConnectionManager<Conn>>` to implement `LoadConnection`
 | 
			
		||||
     = note: required for `UpdateStatement<_, _, _>` to implement `LoadQuery<'_, PooledConnection<ConnectionManager<Conn>>, _>`
 | 
			
		||||
note: required by a bound in `get_result`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1722:15
 | 
			
		||||
     |
 | 
			
		||||
1720 |     fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>
 | 
			
		||||
     |        ---------- required by a bound in this associated function
 | 
			
		||||
1721 |     where
 | 
			
		||||
1722 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result`
 | 
			
		||||
help: consider further restricting this bound
 | 
			
		||||
     |
 | 
			
		||||
50   |     Conn: diesel::Connection + R2D2Connection + 'static + diesel::connection::LoadConnection,
 | 
			
		||||
     |                                                         ++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as HasTable>::Table: SingleValue` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:86:25
 | 
			
		||||
     |
 | 
			
		||||
86   |             .get_result(&mut conn)
 | 
			
		||||
     |              ---------- ^^^^^^^^^ the trait `SingleValue` is not implemented for `<T as HasTable>::Table`, which is required by `UpdateStatement<_, _, _>: LoadQuery<'_, _, _>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `<T as HasTable>::Table` to implement `SqlTypeOrSelectable`
 | 
			
		||||
     = note: required for `T` to implement `FromSqlRow<<T as HasTable>::Table, <Conn as Connection>::Backend>`
 | 
			
		||||
     = note: required for `UpdateStatement<_, _, _>` to implement `LoadQuery<'_, PooledConnection<ConnectionManager<Conn>>, T>`
 | 
			
		||||
note: required by a bound in `get_result`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1722:15
 | 
			
		||||
     |
 | 
			
		||||
1720 |     fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>
 | 
			
		||||
     |        ---------- required by a bound in this associated function
 | 
			
		||||
1721 |     where
 | 
			
		||||
1722 |         Self: LoadQuery<'query, Conn, U>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::get_result`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as HasTable>::Table: diesel::Identifiable` is not satisfied
 | 
			
		||||
  --> src/base/service.rs:83:9
 | 
			
		||||
   |
 | 
			
		||||
83 |         diesel::update(<T as HasTable>::table())
 | 
			
		||||
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::Identifiable` is not implemented for `<T as HasTable>::Table`, which is required by `<T as HasTable>::Table: IntoUpdateTarget`
 | 
			
		||||
   |
 | 
			
		||||
   = note: required for `<T as HasTable>::Table` to implement `IntoUpdateTarget`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as HasTable>::Table: IntoUpdateTarget` is not satisfied
 | 
			
		||||
   --> src/base/service.rs:92:24
 | 
			
		||||
    |
 | 
			
		||||
92  |         diesel::delete(<T as HasTable>::table())
 | 
			
		||||
    |         -------------- ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::Identifiable` is not implemented for `<T as HasTable>::Table`, which is required by `<T as HasTable>::Table: IntoUpdateTarget`
 | 
			
		||||
    |         |
 | 
			
		||||
    |         required by a bound introduced by this call
 | 
			
		||||
    |
 | 
			
		||||
    = note: required for `<T as HasTable>::Table` to implement `IntoUpdateTarget`
 | 
			
		||||
note: required by a bound in `delete`
 | 
			
		||||
   --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_builder/functions.rs:132:18
 | 
			
		||||
    |
 | 
			
		||||
132 | pub fn delete<T: IntoUpdateTarget>(source: T) -> DeleteStatement<T::Table, T::WhereClause> {
 | 
			
		||||
    |                  ^^^^^^^^^^^^^^^^ required by this bound in `delete`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as HasTable>::Table: HasTable` is not satisfied
 | 
			
		||||
  --> src/base/service.rs:92:9
 | 
			
		||||
   |
 | 
			
		||||
92 |         diesel::delete(<T as HasTable>::table())
 | 
			
		||||
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasTable` is not implemented for `<T as HasTable>::Table`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as Model>::PrimaryKey: AppearsOnTable<_>` is not satisfied
 | 
			
		||||
  --> src/base/service.rs:93:14
 | 
			
		||||
   |
 | 
			
		||||
93 |             .filter(T::primary_key().eq(id))
 | 
			
		||||
   |              ^^^^^^ the trait `AppearsOnTable<_>` is not implemented for `<T as Model>::PrimaryKey`, which is required by `DeleteStatement<_, _>: FilterDsl<_>`
 | 
			
		||||
   |
 | 
			
		||||
   = help: the following other types implement trait `AppearsOnTable<QS>`:
 | 
			
		||||
             `&'a T` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4, T5)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4, T5, T6)` implements `AppearsOnTable<QS>`
 | 
			
		||||
             `(T0, T1, T2, T3, T4, T5, T6, T7)` implements `AppearsOnTable<QS>`
 | 
			
		||||
           and 131 others
 | 
			
		||||
   = note: required for `diesel::expression::operators::Eq<<T as Model>::PrimaryKey, diesel::expression::bound::Bound<Integer, i32>>` to implement `AppearsOnTable<_>`
 | 
			
		||||
   = note: 1 redundant requirement hidden
 | 
			
		||||
   = note: required for `Grouped<Eq<<T as Model>::PrimaryKey, Bound<Integer, i32>>>` to implement `AppearsOnTable<_>`
 | 
			
		||||
   = note: required for `DeleteStatement<_, _>` to implement `FilterDsl<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<<T as Model>::PrimaryKey, diesel::expression::bound::Bound<Integer, i32>>>>`
 | 
			
		||||
   = note: the full name for the type has been written to '/home/nicolaivds/GIT/OpenLayerHub/target/debug/deps/openlayerhub-1f7d339452a03941.long-type-9065444121950834043.txt'
 | 
			
		||||
   = note: consider using `--verbose` to print the full type name to the console
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as Model>::PrimaryKey: AppearsOnTable<_>` is not satisfied
 | 
			
		||||
   --> src/base/service.rs:93:21
 | 
			
		||||
    |
 | 
			
		||||
93  |             .filter(T::primary_key().eq(id))
 | 
			
		||||
    |              ------ ^^^^^^^^^^^^^^^^^^^^^^^ the trait `AppearsOnTable<_>` is not implemented for `<T as Model>::PrimaryKey`, which is required by `DeleteStatement<_, _>: FilterDsl<_>`
 | 
			
		||||
    |              |
 | 
			
		||||
    |              required by a bound introduced by this call
 | 
			
		||||
    |
 | 
			
		||||
    = help: the following other types implement trait `AppearsOnTable<QS>`:
 | 
			
		||||
              `&'a T` implements `AppearsOnTable<QS>`
 | 
			
		||||
              `(T0, T1)` implements `AppearsOnTable<QS>`
 | 
			
		||||
              `(T0, T1, T2)` implements `AppearsOnTable<QS>`
 | 
			
		||||
              `(T0, T1, T2, T3)` implements `AppearsOnTable<QS>`
 | 
			
		||||
              `(T0, T1, T2, T3, T4)` implements `AppearsOnTable<QS>`
 | 
			
		||||
              `(T0, T1, T2, T3, T4, T5)` implements `AppearsOnTable<QS>`
 | 
			
		||||
              `(T0, T1, T2, T3, T4, T5, T6)` implements `AppearsOnTable<QS>`
 | 
			
		||||
              `(T0, T1, T2, T3, T4, T5, T6, T7)` implements `AppearsOnTable<QS>`
 | 
			
		||||
            and 131 others
 | 
			
		||||
    = note: required for `diesel::expression::operators::Eq<<T as Model>::PrimaryKey, diesel::expression::bound::Bound<Integer, i32>>` to implement `AppearsOnTable<_>`
 | 
			
		||||
    = note: 1 redundant requirement hidden
 | 
			
		||||
    = note: required for `Grouped<Eq<<T as Model>::PrimaryKey, Bound<Integer, i32>>>` to implement `AppearsOnTable<_>`
 | 
			
		||||
    = note: required for `DeleteStatement<_, _>` to implement `FilterDsl<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<<T as Model>::PrimaryKey, diesel::expression::bound::Bound<Integer, i32>>>>`
 | 
			
		||||
note: required by a bound in `DeleteStatement::<T, U>::filter`
 | 
			
		||||
   --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_builder/delete_statement/mod.rs:113:15
 | 
			
		||||
    |
 | 
			
		||||
111 |     pub fn filter<Predicate>(self, predicate: Predicate) -> Filter<Self, Predicate>
 | 
			
		||||
    |            ------ required by a bound in this associated function
 | 
			
		||||
112 |     where
 | 
			
		||||
113 |         Self: FilterDsl<Predicate>,
 | 
			
		||||
    |               ^^^^^^^^^^^^^^^^^^^^ required by this bound in `DeleteStatement::<T, U>::filter`
 | 
			
		||||
    = note: the full name for the type has been written to '/home/nicolaivds/GIT/OpenLayerHub/target/debug/deps/openlayerhub-1f7d339452a03941.long-type-9065444121950834043.txt'
 | 
			
		||||
    = note: consider using `--verbose` to print the full type name to the console
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<Conn as Connection>::Backend: DieselReserveSpecialization` is not satisfied
 | 
			
		||||
    --> src/base/service.rs:94:22
 | 
			
		||||
     |
 | 
			
		||||
94   |             .execute(&mut conn)
 | 
			
		||||
     |              ------- ^^^^^^^^^ the trait `DieselReserveSpecialization` is not implemented for `<Conn as Connection>::Backend`, which is required by `DeleteStatement<_, _>: ExecuteDsl<_, _>`
 | 
			
		||||
     |              |
 | 
			
		||||
     |              required by a bound introduced by this call
 | 
			
		||||
     |
 | 
			
		||||
     = note: required for `DeleteStatement<_, _>` to implement `QueryFragment<<Conn as Connection>::Backend>`
 | 
			
		||||
     = note: required for `DeleteStatement<_, _>` to implement `ExecuteDsl<PooledConnection<ConnectionManager<Conn>>, <Conn as Connection>::Backend>`
 | 
			
		||||
note: required by a bound in `diesel::RunQueryDsl::execute`
 | 
			
		||||
    --> /home/nicolaivds/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.2.7/src/query_dsl/mod.rs:1431:15
 | 
			
		||||
     |
 | 
			
		||||
1428 |     fn execute(self, conn: &mut Conn) -> QueryResult<usize>
 | 
			
		||||
     |        ------- required by a bound in this associated function
 | 
			
		||||
...
 | 
			
		||||
1431 |         Self: methods::ExecuteDsl<Conn>,
 | 
			
		||||
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::execute`
 | 
			
		||||
 | 
			
		||||
error[E0277]: the trait bound `<T as HasTable>::Table: diesel::Identifiable` is not satisfied
 | 
			
		||||
  --> src/base/service.rs:92:9
 | 
			
		||||
   |
 | 
			
		||||
92 |         diesel::delete(<T as HasTable>::table())
 | 
			
		||||
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::Identifiable` is not implemented for `<T as HasTable>::Table`, which is required by `<T as HasTable>::Table: IntoUpdateTarget`
 | 
			
		||||
   |
 | 
			
		||||
   = note: required for `<T as HasTable>::Table` to implement `IntoUpdateTarget`
 | 
			
		||||
 | 
			
		||||
Some errors have detailed explanations: E0275, E0277.
 | 
			
		||||
For more information about an error, try `rustc --explain E0275`.
 | 
			
		||||
error: could not compile `openlayerhub` (bin "openlayerhub") due to 26 previous errors
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
-- This file was automatically created by Diesel to setup helper functions
 | 
			
		||||
-- and other internal bookkeeping. This file is safe to edit, any future
 | 
			
		||||
-- changes will be added to existing projects as new migrations.
 | 
			
		||||
 | 
			
		||||
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
 | 
			
		||||
DROP FUNCTION IF EXISTS diesel_set_updated_at();
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
-- This file was automatically created by Diesel to setup helper functions
 | 
			
		||||
-- and other internal bookkeeping. This file is safe to edit, any future
 | 
			
		||||
-- changes will be added to existing projects as new migrations.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- Sets up a trigger for the given table to automatically set a column called
 | 
			
		||||
-- `updated_at` whenever the row is modified (unless `updated_at` was included
 | 
			
		||||
-- in the modified columns)
 | 
			
		||||
--
 | 
			
		||||
-- # Example
 | 
			
		||||
--
 | 
			
		||||
-- ```sql
 | 
			
		||||
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
 | 
			
		||||
--
 | 
			
		||||
-- SELECT diesel_manage_updated_at('users');
 | 
			
		||||
-- ```
 | 
			
		||||
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
 | 
			
		||||
BEGIN
 | 
			
		||||
    EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
 | 
			
		||||
                    FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
 | 
			
		||||
END;
 | 
			
		||||
$$ LANGUAGE plpgsql;
 | 
			
		||||
 | 
			
		||||
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
 | 
			
		||||
BEGIN
 | 
			
		||||
    IF (
 | 
			
		||||
        NEW IS DISTINCT FROM OLD AND
 | 
			
		||||
        NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
 | 
			
		||||
    ) THEN
 | 
			
		||||
        NEW.updated_at := current_timestamp;
 | 
			
		||||
    END IF;
 | 
			
		||||
    RETURN NEW;
 | 
			
		||||
END;
 | 
			
		||||
$$ LANGUAGE plpgsql;
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
DROP TABLE users;
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
CREATE TABLE users (
 | 
			
		||||
    id SERIAL PRIMARY KEY,
 | 
			
		||||
    name VARCHAR NOT NULL,
 | 
			
		||||
    email VARCHAR NOT NULL UNIQUE
 | 
			
		||||
);
 | 
			
		||||
@@ -1,78 +0,0 @@
 | 
			
		||||
use crate::base::{entity::BaseEntity, i_service::IBaseService};
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use axum::{extract::{Path, State}, http::StatusCode, response::IntoResponse, routing::get, Json, Router};
 | 
			
		||||
use diesel::Identifiable;
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
use std::{marker::PhantomData, ops::Deref, sync::Arc};
 | 
			
		||||
 | 
			
		||||
pub struct BaseController<T, S>
 | 
			
		||||
where
 | 
			
		||||
    T: BaseEntity + Identifiable<Id = i32> + Serialize + Send + Sync + 'static,
 | 
			
		||||
    S: IBaseService<T> + Send + Sync + 'static,
 | 
			
		||||
{
 | 
			
		||||
    service: S,
 | 
			
		||||
    _marker: PhantomData<T>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T, S> BaseController<T, S>
 | 
			
		||||
where
 | 
			
		||||
    T: BaseEntity + Identifiable<Id = i32> + Serialize + Send + Sync + 'static,
 | 
			
		||||
    S: IBaseService<T> + Send + Sync + 'static,
 | 
			
		||||
{
 | 
			
		||||
    pub fn new(service: S) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            service,
 | 
			
		||||
            _marker: PhantomData,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn get_all(&self) -> Result<impl IntoResponse, String> {
 | 
			
		||||
        let entities = self
 | 
			
		||||
            .service
 | 
			
		||||
            .get_all()
 | 
			
		||||
            .await
 | 
			
		||||
            .map_err(|err| err.to_string())?;
 | 
			
		||||
        Ok((StatusCode::OK, Json(entities)))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn get_by_id(&self, id: i32) -> Result<impl IntoResponse, String> {
 | 
			
		||||
        let entity = self
 | 
			
		||||
            .service
 | 
			
		||||
            .get_by_id(id)
 | 
			
		||||
            .await
 | 
			
		||||
            .map_err(|err| err.to_string())?;
 | 
			
		||||
 | 
			
		||||
        match entity {
 | 
			
		||||
            Some(entity) => Ok((StatusCode::OK, Json(entity))),
 | 
			
		||||
            None => Err(format!("Entity with id {} not found.", id))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn default_routes<C>(controller: Arc<C>, base_path: &str) -> Router
 | 
			
		||||
    where
 | 
			
		||||
        C: Deref<Target = Self> + Send + Sync + 'static,
 | 
			
		||||
    {
 | 
			
		||||
        Router::new()
 | 
			
		||||
            .route(
 | 
			
		||||
                &format!("{}", base_path),
 | 
			
		||||
                get(|State(controller): State<Arc<C>>| async move {
 | 
			
		||||
                    controller
 | 
			
		||||
                        .get_all()
 | 
			
		||||
                        .await
 | 
			
		||||
                        .map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, Json(err)))
 | 
			
		||||
                }),
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            .route(
 | 
			
		||||
                // Add route for getting by ID (e.g., /:id)
 | 
			
		||||
                &format!("{}/{{id}}", base_path),
 | 
			
		||||
                get(|State(controller): State<Arc<C>>, Path(id): Path<i32>| async move {
 | 
			
		||||
                    controller
 | 
			
		||||
                        .get_by_id(id)
 | 
			
		||||
                        .await
 | 
			
		||||
                        .map_err(|err| (StatusCode::NOT_FOUND, Json(err)))
 | 
			
		||||
                }),
 | 
			
		||||
            )
 | 
			
		||||
            .with_state(controller)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
pub trait BaseEntity {
 | 
			
		||||
    fn id(&self) -> i32;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Deserialize, Clone, Debug)]
 | 
			
		||||
pub struct Entity {
 | 
			
		||||
    pub id: i32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl BaseEntity for Entity {
 | 
			
		||||
    fn id(&self) -> i32 {
 | 
			
		||||
        self.id
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
use anyhow::{Error, Result};
 | 
			
		||||
use async_trait::async_trait;
 | 
			
		||||
 | 
			
		||||
#[async_trait]
 | 
			
		||||
pub trait IBaseService<T> {
 | 
			
		||||
    async fn get_all(&self) -> Result<Vec<T>, Error>;
 | 
			
		||||
    async fn get_by_id(&self, id: i32) -> Result<Option<T>, Error>;
 | 
			
		||||
    async fn update(&self, entity: T) -> Result<T, Error>;
 | 
			
		||||
    //async fn create(&self, entity: T) -> Result<i32, Error>;
 | 
			
		||||
    async fn delete(&self, id: i32) -> Result<bool, Error>;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
pub mod i_service;
 | 
			
		||||
pub mod service;
 | 
			
		||||
pub mod controller;
 | 
			
		||||
pub mod entity;
 | 
			
		||||
@@ -1,89 +0,0 @@
 | 
			
		||||
use std::marker::PhantomData;
 | 
			
		||||
use anyhow::Error;
 | 
			
		||||
use async_trait::async_trait;
 | 
			
		||||
use diesel::prelude::*;
 | 
			
		||||
use diesel::associations::HasTable;
 | 
			
		||||
use diesel::query_dsl::methods::{FindDsl, LoadQuery};
 | 
			
		||||
 | 
			
		||||
use crate::config::db::{get_connection, DbPool};
 | 
			
		||||
use super::i_service::IBaseService;
 | 
			
		||||
 | 
			
		||||
pub struct BaseService<T, U>
 | 
			
		||||
where
 | 
			
		||||
    T: Identifiable<Id = i32> + Queryable<U::SqlType, diesel::pg::Pg> + Send + Sync + 'static,
 | 
			
		||||
    U: Table + HasTable<Table = U> + LoadQuery<'static, PgConnection, T> + Send + Sync + 'static,
 | 
			
		||||
{
 | 
			
		||||
    pool: DbPool,
 | 
			
		||||
    _marker: PhantomData<(T, U)>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T, U> BaseService<T, U>
 | 
			
		||||
where
 | 
			
		||||
    T: Identifiable<Id = i32> + Queryable<U::SqlType, diesel::pg::Pg> + Send + Sync + 'static,
 | 
			
		||||
    U: Table 
 | 
			
		||||
        + HasTable<Table = U> 
 | 
			
		||||
        + LoadQuery<'static, PgConnection, T>
 | 
			
		||||
        + Send 
 | 
			
		||||
        + Sync 
 | 
			
		||||
        + 'static,
 | 
			
		||||
{
 | 
			
		||||
    pub fn new(pool: DbPool) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            pool,
 | 
			
		||||
            _marker: PhantomData,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[async_trait]
 | 
			
		||||
impl<T, U> IBaseService<T> for BaseService<T, U>
 | 
			
		||||
where
 | 
			
		||||
    T: Identifiable<Id = i32> + Queryable<U::SqlType, diesel::pg::Pg> + Send + Sync + 'static,
 | 
			
		||||
    U: Table 
 | 
			
		||||
        + HasTable<Table = U> 
 | 
			
		||||
        + LoadQuery<'static, PgConnection, T>
 | 
			
		||||
        + FindDsl<i32>
 | 
			
		||||
        + Send 
 | 
			
		||||
        + Sync 
 | 
			
		||||
        + 'static,
 | 
			
		||||
    <U as FindDsl<i32>>::Output: LoadQuery<'static, PgConnection, T>,
 | 
			
		||||
{
 | 
			
		||||
    async fn get_all(&self) -> Result<Vec<T>, Error> {
 | 
			
		||||
        let pool = self.pool.clone();
 | 
			
		||||
 | 
			
		||||
        let result = tokio::task::spawn_blocking(move || {
 | 
			
		||||
            let mut conn = get_connection(&pool).expect("Failed to get DB connection");
 | 
			
		||||
            U::table().load::<T>(&mut conn)
 | 
			
		||||
        })
 | 
			
		||||
        .await??;
 | 
			
		||||
 | 
			
		||||
        Ok(result)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn get_by_id(&self, id: i32) -> Result<Option<T>, Error> {
 | 
			
		||||
        let pool = self.pool.clone();
 | 
			
		||||
 | 
			
		||||
        let result = tokio::task::spawn_blocking(move || {
 | 
			
		||||
            let mut conn = get_connection(&pool).expect("Failed to get DB connection");
 | 
			
		||||
            U::table()
 | 
			
		||||
                .find(id)
 | 
			
		||||
                .get_result::<T>(&mut conn)
 | 
			
		||||
                .optional()
 | 
			
		||||
        })
 | 
			
		||||
        .await??;
 | 
			
		||||
 | 
			
		||||
        Ok(result)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn update(&self, entity: T) -> Result<T, Error> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // async fn create(&self, entity: T) -> Result<T, Error> { 
 | 
			
		||||
    //     todo!()
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    async fn delete(&self, id: i32) -> Result<bool, Error> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
use diesel::pg::PgConnection;
 | 
			
		||||
use diesel::r2d2::{self, ConnectionManager, Pool, PoolError};
 | 
			
		||||
 | 
			
		||||
use std::env;
 | 
			
		||||
 | 
			
		||||
pub type DbPool = Pool<ConnectionManager<PgConnection>>;
 | 
			
		||||
 | 
			
		||||
pub fn establish_connection_pool() -> Result<DbPool, PoolError> {
 | 
			
		||||
    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
 | 
			
		||||
 | 
			
		||||
    let manager = ConnectionManager::<PgConnection>::new(database_url);
 | 
			
		||||
    Pool::builder().build(manager)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn get_connection(
 | 
			
		||||
    pool: &DbPool,
 | 
			
		||||
) -> Result<r2d2::PooledConnection<ConnectionManager<PgConnection>>, PoolError> {
 | 
			
		||||
    pool.get()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn init_db() -> DbPool {
 | 
			
		||||
    establish_connection_pool().expect("Failed to create connection pool")
 | 
			
		||||
}
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
pub mod db;
 | 
			
		||||
pub mod parameter;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										63
									
								
								src/config/parameter.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/config/parameter.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
use config::{Config, ConfigError, Environment, File};
 | 
			
		||||
use dotenvy::dotenv;
 | 
			
		||||
use serde::Deserialize;
 | 
			
		||||
use std::env;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Deserialize, Clone)]
 | 
			
		||||
pub struct AppConfig {
 | 
			
		||||
    pub loki_endpoint: String,
 | 
			
		||||
    pub service_name: String,
 | 
			
		||||
    pub service_version: String,
 | 
			
		||||
    pub log_level: String,
 | 
			
		||||
    pub port: u16,
 | 
			
		||||
    pub environment: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl AppConfig {
 | 
			
		||||
    pub fn new() -> Result<Self, ConfigError> {
 | 
			
		||||
        let _ = dotenv().ok();
 | 
			
		||||
 | 
			
		||||
        let environment = env::var("APP_ENV").unwrap_or_else(|_| "development".into());
 | 
			
		||||
 | 
			
		||||
        let config = Config::builder()
 | 
			
		||||
            // Start with default values
 | 
			
		||||
            .set_default("environment", &*environment)?
 | 
			
		||||
            .set_default("service_name", "OpenLayersHub")?
 | 
			
		||||
            .set_default("service_version", env!("GIT_VERSION"))?
 | 
			
		||||
            .set_default("log_level", "info")?
 | 
			
		||||
            .set_default("port", 3000)?
 | 
			
		||||
            // Add environment-specific config file
 | 
			
		||||
            .add_source(File::with_name(&format!("config/{}", environment)).required(false))
 | 
			
		||||
            .add_source(File::with_name(".env").required(false))
 | 
			
		||||
            .add_source(
 | 
			
		||||
                Environment::with_prefix("APP")
 | 
			
		||||
                    .prefix_separator("_")
 | 
			
		||||
                    .separator("__"),
 | 
			
		||||
            )
 | 
			
		||||
            .build()?;
 | 
			
		||||
 | 
			
		||||
        config.try_deserialize()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn validate(&self) -> Result<(), Vec<String>> {
 | 
			
		||||
        let mut errors = Vec::new();
 | 
			
		||||
 | 
			
		||||
        if self.loki_endpoint.is_empty() {
 | 
			
		||||
            errors.push("Loki endpoint must be set".to_string());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Validate environment value
 | 
			
		||||
        if !["development", "staging", "production"].contains(&self.environment.as_str()) {
 | 
			
		||||
            errors.push(format!(
 | 
			
		||||
                "Invalid environment '{}'. Must be one of: development, staging, production",
 | 
			
		||||
                self.environment
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if errors.is_empty() {
 | 
			
		||||
            Ok(())
 | 
			
		||||
        } else {
 | 
			
		||||
            Err(errors)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -1,51 +1,24 @@
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use crate::config::parameter::AppConfig;
 | 
			
		||||
 | 
			
		||||
use crate::routes::user::controller::UserController;
 | 
			
		||||
use crate::routes::user::model::{User, UserResponse};
 | 
			
		||||
use crate::routes::user::service::UserService;
 | 
			
		||||
use axum::http::StatusCode;
 | 
			
		||||
use axum::routing::get;
 | 
			
		||||
use axum::{serve, Router};
 | 
			
		||||
use config::db::init_db;
 | 
			
		||||
use dotenvy::dotenv;
 | 
			
		||||
use tokio::net::TcpListener;
 | 
			
		||||
use utoipa::OpenApi;
 | 
			
		||||
use utoipa_swagger_ui::SwaggerUi;
 | 
			
		||||
 | 
			
		||||
mod base;
 | 
			
		||||
mod config;
 | 
			
		||||
mod routes;
 | 
			
		||||
 | 
			
		||||
#[tokio::main]
 | 
			
		||||
async fn main() {
 | 
			
		||||
    dotenv().ok();
 | 
			
		||||
    let pool = init_db();
 | 
			
		||||
fn main() {
 | 
			
		||||
    let config = AppConfig::new()
 | 
			
		||||
        .map_err(|e| {
 | 
			
		||||
            eprintln!("Configuration error: {}", e);
 | 
			
		||||
            std::process::exit(1);
 | 
			
		||||
        })
 | 
			
		||||
        .and_then(|cfg| {
 | 
			
		||||
            cfg.validate().map_err(|errors| {
 | 
			
		||||
                eprintln!(
 | 
			
		||||
                    "Configuration validation errors:\n\t{}",
 | 
			
		||||
                    errors.join("\n\t")
 | 
			
		||||
                );
 | 
			
		||||
                std::process::exit(1);
 | 
			
		||||
            })?;
 | 
			
		||||
            Ok(cfg)
 | 
			
		||||
        })
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
    let hc_router = Router::new().route("/", get(health_check));
 | 
			
		||||
 | 
			
		||||
    let user_service = UserService::new(pool);
 | 
			
		||||
    let user_controller = Arc::new(UserController::new(user_service));
 | 
			
		||||
 | 
			
		||||
    let app = Router::new()
 | 
			
		||||
        .merge(UserController::routes(user_controller.clone()))
 | 
			
		||||
        .merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi()))
 | 
			
		||||
        .nest("/hc", hc_router);
 | 
			
		||||
 | 
			
		||||
    let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
 | 
			
		||||
    serve(listener, app).await.unwrap();
 | 
			
		||||
 | 
			
		||||
    async fn health_check() -> StatusCode {
 | 
			
		||||
        StatusCode::OK
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[derive(OpenApi)]
 | 
			
		||||
    #[openapi(
 | 
			
		||||
        components(
 | 
			
		||||
            schemas(User, UserResponse)
 | 
			
		||||
        ),
 | 
			
		||||
        tags(
 | 
			
		||||
            (name = "users", description = "User management endpoints")
 | 
			
		||||
        )
 | 
			
		||||
    )]
 | 
			
		||||
    struct ApiDoc;
 | 
			
		||||
    println!("Hello, world! {}", config.service_version);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
pub mod user;
 | 
			
		||||
@@ -1,44 +0,0 @@
 | 
			
		||||
use std::ops::Deref;
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
 | 
			
		||||
use crate::base::controller::BaseController;
 | 
			
		||||
use axum::Router;
 | 
			
		||||
 | 
			
		||||
use super::model::User;
 | 
			
		||||
use super::service::UserService;
 | 
			
		||||
 | 
			
		||||
pub struct UserController {
 | 
			
		||||
    base_controller: BaseController<User, UserService>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Deref for UserController {
 | 
			
		||||
    type Target = BaseController<User, UserService>;
 | 
			
		||||
 | 
			
		||||
    fn deref(&self) -> &Self::Target {
 | 
			
		||||
        &self.base_controller
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl UserController {
 | 
			
		||||
    pub fn new(service: UserService) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            base_controller: BaseController::new(service),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn routes(controller: Arc<Self>) -> Router {
 | 
			
		||||
        BaseController::default_routes(controller, "/users")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    async fn get_users(
 | 
			
		||||
        State(controller): State<Arc<UserController>>,
 | 
			
		||||
    ) -> Result<impl IntoResponse, (StatusCode, Json<String>)> {
 | 
			
		||||
        controller
 | 
			
		||||
            .base_controller
 | 
			
		||||
            .get_all()
 | 
			
		||||
            .await
 | 
			
		||||
            .map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, Json(err)))
 | 
			
		||||
    }
 | 
			
		||||
    */
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
pub mod model;
 | 
			
		||||
pub mod schema;
 | 
			
		||||
pub mod service;
 | 
			
		||||
pub mod controller;
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
use super::schema::users;
 | 
			
		||||
use crate::base::entity::BaseEntity;
 | 
			
		||||
use diesel::prelude::*;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
use utoipa::ToSchema;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Serialize, Deserialize, Queryable, Identifiable, ToSchema)]
 | 
			
		||||
#[diesel(table_name = users, primary_key(id))]
 | 
			
		||||
pub struct User {
 | 
			
		||||
    pub id: i32,
 | 
			
		||||
    pub name: String,
 | 
			
		||||
    pub email: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, ToSchema)]
 | 
			
		||||
pub struct UserResponse {
 | 
			
		||||
    pub id: i32,
 | 
			
		||||
    pub name: String,
 | 
			
		||||
    pub email: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl BaseEntity for User {
 | 
			
		||||
    fn id(&self) -> i32 {
 | 
			
		||||
        self.id
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Identifiable for User {
 | 
			
		||||
    type Id = i32;
 | 
			
		||||
 | 
			
		||||
    fn id(self) -> Self::Id {
 | 
			
		||||
        self.id
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
use diesel::table;
 | 
			
		||||
 | 
			
		||||
table! {
 | 
			
		||||
    users (id) {
 | 
			
		||||
        id -> Integer,
 | 
			
		||||
        name -> Varchar,
 | 
			
		||||
        email -> Varchar,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
use crate::base::service::BaseService;
 | 
			
		||||
use super::model::User;
 | 
			
		||||
use super::schema::users;
 | 
			
		||||
 | 
			
		||||
pub type UserService = BaseService<User, users::table>;
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
// @generated automatically by Diesel CLI.
 | 
			
		||||
 | 
			
		||||
diesel::table! {
 | 
			
		||||
    users (id) {
 | 
			
		||||
        id -> Int4,
 | 
			
		||||
        name -> Varchar,
 | 
			
		||||
        email -> Varchar,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user