diff --git a/.github/workflows/react.yml b/.github/workflows/react.yml deleted file mode 100644 index adcacb2..0000000 --- a/.github/workflows/react.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: React - -on: - push: - branches: ["main", "develop"] - pull_request: - branches: ["main", "develop"] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Install - run: cd movies-db-ui && npm install - - name: Build - run: cd movies-db-ui && npm run build diff --git a/.github/workflows/react_test.yml b/.github/workflows/react_test.yml new file mode 100644 index 0000000..ce1aba0 --- /dev/null +++ b/.github/workflows/react_test.yml @@ -0,0 +1,35 @@ +name: "ReactTest" + +on: + pull_request: + +env: + working-directory: "./movies-db-ui" + +jobs: + build: + name: "Build React" + runs-on: ubuntu-latest + + steps: + - name: "Check out the repo" + uses: actions/checkout@v3 + + - name: Install Node.js + uses: actions/setup-node@v1 + with: + node-version: "12.x" + + - name: Install dependencies + run: npm install + working-directory: ${{ env.working-directory }} + + # Deactivate tests for now as there seems to be an issue with jest and css-tools + # - name: Run the tests + # run: npm test + # working-directory: ${{ env.working-directory }} + + - name: Build React App + run: npm run build + working-directory: ${{ env.working-directory }} + diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index 736c3f0..0000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Rust - -on: - push: - branches: ["main", "develop"] - pull_request: - branches: ["main", "develop"] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Build - run: cd movies-db-service && cargo build --verbose - - name: Run tests - run: cd movies-db-service && cargo test --verbose diff --git a/.github/workflows/rust_test.yml b/.github/workflows/rust_test.yml new file mode 100644 index 0000000..4ad7904 --- /dev/null +++ b/.github/workflows/rust_test.yml @@ -0,0 +1,84 @@ +name: "RustTest" + +on: + pull_request: + +env: + working-directory: "./movies-db-service" + +jobs: + check: + name: "Cargo check" + runs-on: "ubuntu-latest" + steps: + - name: "Check out the repo" + uses: actions/checkout@v3 + + - uses: "actions-rs/toolchain@v1" + with: + profile: "minimal" + toolchain: "stable" + override: true + + - uses: "actions-rs/cargo@v1" + with: + command: "check" + args: "--manifest-path movies-db-service/Cargo.toml" + + test: + name: "Cargo test" + runs-on: "ubuntu-latest" + steps: + - name: "Check out the repo" + uses: actions/checkout@v3 + + - uses: "actions-rs/toolchain@v1" + with: + profile: "minimal" + toolchain: "stable" + override: true + + - uses: "actions-rs/cargo@v1" + with: + command: "test" + args: "--manifest-path movies-db-service/Cargo.toml" + + fmt: + name: "Cargo format" + runs-on: "ubuntu-latest" + steps: + - name: "Check out the repo" + uses: actions/checkout@v3 + + - uses: "actions-rs/toolchain@v1" + with: + profile: "minimal" + toolchain: "stable" + override: true + + - run: "rustup component add rustfmt" + + - uses: "actions-rs/cargo@v1" + with: + command: "fmt" + args: "--all --manifest-path movies-db-service/Cargo.toml -- --check" + + clippy: + name: "Cargo clippy" + runs-on: "ubuntu-latest" + steps: + - name: "Check out the repo" + uses: actions/checkout@v3 + + - uses: "actions-rs/toolchain@v1" + with: + profile: "minimal" + toolchain: "stable" + override: true + + - run: "rustup component add clippy" + + - uses: "actions-rs/cargo@v1" + with: + command: "clippy" + args: "--manifest-path movies-db-service/Cargo.toml -- -D warnings" \ No newline at end of file diff --git a/movies-db-service/movies-db-cli/src/options.rs b/movies-db-service/movies-db-cli/src/options.rs index d218b00..6e13276 100644 --- a/movies-db-service/movies-db-cli/src/options.rs +++ b/movies-db-service/movies-db-cli/src/options.rs @@ -43,11 +43,11 @@ pub struct Options { pub root_dir: PathBuf, } -impl Into for Options { - fn into(self) -> ServiceOptions { +impl From for ServiceOptions { + fn from(options: Options) -> Self { ServiceOptions { - root_dir: self.root_dir, - http_address: self.address.parse().unwrap(), + root_dir: options.root_dir, + http_address: options.address.parse().unwrap(), } } } diff --git a/movies-db-service/movies-db/src/db/id.rs b/movies-db-service/movies-db/src/db/id.rs index 6d91d3a..3754ba5 100644 --- a/movies-db-service/movies-db/src/db/id.rs +++ b/movies-db-service/movies-db/src/db/id.rs @@ -5,4 +5,4 @@ pub type MovieId = String; /// Generates and returns a new movie random ID pub fn generate_movie_id() -> MovieId { Uuid::new_v4().to_string() -} \ No newline at end of file +} diff --git a/movies-db-service/movies-db/src/db/simple_movies_index.rs b/movies-db-service/movies-db/src/db/simple_movies_index.rs index 0d414d7..980550d 100644 --- a/movies-db-service/movies-db/src/db/simple_movies_index.rs +++ b/movies-db-service/movies-db/src/db/simple_movies_index.rs @@ -21,7 +21,7 @@ impl SimpleMoviesIndex { /// /// # Arguments /// `tags` - The tags to process. - fn process_tags(tags: &mut Vec) { + fn process_tags(tags: &mut [String]) { tags.iter_mut().for_each(|tag| *tag = tag.to_lowercase()); tags.sort(); } @@ -42,9 +42,9 @@ impl MoviesIndex for SimpleMoviesIndex { // check if movie has title if movie.title.is_empty() { error!("Movie has no title"); - return Err(Error::InvalidArgument(format!( - "Movie title must not be empty" - ))); + return Err(Error::InvalidArgument( + "Movie title must not be empty".to_string(), + )); } assert!( @@ -138,13 +138,10 @@ impl MoviesIndex for SimpleMoviesIndex { let movie = &movie_with_date.movie; // if a title query is available and the movie title does not match, skip - match title_query { - Some(ref title_query) => { - if !title_query.matches(&movie.title) { - continue; - } + if let Some(ref title_query) = title_query { + if !title_query.matches(&movie.title) { + continue; } - None => {} } // check that all tags match @@ -194,7 +191,7 @@ impl SimpleMoviesIndex { .map(|(id, movie)| (id.clone(), movie.movie.title.clone())) .collect(); - movies.sort_unstable_by(|(_, lhs), (_, rhs)| lhs.cmp(&rhs)); + movies.sort_unstable_by(|(_, lhs), (_, rhs)| lhs.cmp(rhs)); if order == SortingOrder::Ascending { movies.iter().map(|(id, _)| id.clone()).collect() @@ -207,10 +204,10 @@ impl SimpleMoviesIndex { let mut movies: Vec<(MovieId, DateTime<_>)> = self .movies .iter() - .map(|(id, movie)| (id.clone(), movie.date.clone())) + .map(|(id, movie)| (id.clone(), movie.date)) .collect(); - movies.sort_unstable_by(|(_, lhs), (_, rhs)| lhs.cmp(&rhs)); + movies.sort_unstable_by(|(_, lhs), (_, rhs)| lhs.cmp(rhs)); if order == SortingOrder::Ascending { movies.iter().map(|(id, _)| id.clone()).collect() diff --git a/movies-db-service/movies-db/src/db/sqlite_movies_index.rs b/movies-db-service/movies-db/src/db/sqlite_movies_index.rs index 0c381ec..089298e 100644 --- a/movies-db-service/movies-db/src/db/sqlite_movies_index.rs +++ b/movies-db-service/movies-db/src/db/sqlite_movies_index.rs @@ -91,7 +91,7 @@ impl SqliteMoviesIndex { query_string.push_str(" WHERE m.title LIKE '"); query_string.push_str(&title); - query_string.push_str("'"); + query_string.push('\''); } None => {} } @@ -123,7 +123,7 @@ impl SqliteMoviesIndex { query_string.push_str(" AND m.title LIKE '"); query_string.push_str(&title); - query_string.push_str("'"); + query_string.push('\''); } None => {} } @@ -158,19 +158,13 @@ impl SqliteMoviesIndex { order_and_limit.push_str(&format!(" ORDER BY {} {} ", field, order)); // limit - match query.num_results { - Some(num_results) => { - order_and_limit.push_str(&format!(" LIMIT {} ", num_results)); - } - None => {} + if let Some(limit) = query.num_results { + order_and_limit.push_str(&format!(" LIMIT {} ", limit)); } // offset - match query.start_index { - Some(offset) => { - order_and_limit.push_str(&format!(" OFFSET {} ", offset)); - } - None => {} + if let Some(offset) = query.start_index { + order_and_limit.push_str(&format!(" OFFSET {} ", offset)); } order_and_limit @@ -183,12 +177,9 @@ impl MoviesIndex for SqliteMoviesIndex { where Self: Sized, { - match create_dir_all(&options.root_dir) { - Err(err) => { - error!("Failed to create the root directory: {}", err); - return Err(err.into()); - } - Ok(()) => {} + if let Err(err) = create_dir_all(&options.root_dir) { + error!("Failed to create the root directory: {}", err); + return Err(err.into()); } let mut sqlite_path = options.root_dir.clone(); @@ -201,18 +192,15 @@ impl MoviesIndex for SqliteMoviesIndex { match Connection::open(sqlite_path) { Err(err) => { error!("Failed to open the SQLite database: {}", err); - return Err(Error::IO(format!("Failed to open SQLite DB{}", err))); + Err(Error::IO(format!("Failed to open SQLite DB{}", err))) } Ok(connection) => { - match Self::create_tables(&connection) { - Err(err) => { - error!("Failed to create the tables: {}", err); - return Err(Error::Internal(format!( - "Failed to create the tables: {}", - err - ))); - } - Ok(()) => {} + if let Err(err) = Self::create_tables(&connection) { + error!("Failed to create the tables: {}", err); + return Err(Error::Internal(format!( + "Failed to create the tables: {}", + err + ))); } let connection = Mutex::new(connection); @@ -229,9 +217,9 @@ impl MoviesIndex for SqliteMoviesIndex { // check if movie has title if movie.title.is_empty() { error!("Movie has no title"); - return Err(Error::InvalidArgument(format!( - "Movie title must not be empty" - ))); + return Err(Error::InvalidArgument( + "Movie title must not be empty".to_string(), + )); } let date = chrono::Utc::now().to_rfc3339(); diff --git a/movies-db-service/movies-db/src/service/mod.rs b/movies-db-service/movies-db/src/service/mod.rs index 1b79f05..842a6a4 100644 --- a/movies-db-service/movies-db/src/service/mod.rs +++ b/movies-db-service/movies-db/src/service/mod.rs @@ -1,4 +1,4 @@ -mod service; mod service_handler; +mod service_impl; -pub use service::*; +pub use service_impl::*; diff --git a/movies-db-service/movies-db/src/service/service.rs b/movies-db-service/movies-db/src/service/service_impl.rs similarity index 93% rename from movies-db-service/movies-db/src/service/service.rs rename to movies-db-service/movies-db/src/service/service_impl.rs index cd64b89..a911e06 100644 --- a/movies-db-service/movies-db/src/service/service.rs +++ b/movies-db-service/movies-db/src/service/service_impl.rs @@ -1,10 +1,11 @@ -use std::{marker::PhantomData, sync::RwLock}; +use std::marker::PhantomData; use actix_cors::Cors; use actix_multipart::Multipart; use actix_web::{web, App, HttpServer, Responder, Result}; use log::{debug, error, info, trace}; +use tokio::sync::RwLock; use crate::{Error, Movie, MovieId, MovieSearchQuery, MovieStorage, MoviesIndex, Options}; @@ -91,7 +92,7 @@ where .app_data(handler.clone()) .service(api_v1) }) - .bind(self.options.http_address.clone())? + .bind(self.options.http_address)? .run() .await { @@ -137,8 +138,7 @@ where let movie: Movie = movie.into_inner(); - let mut handler: std::sync::RwLockWriteGuard<'_, ServiceHandler> = - handler.write().unwrap(); + let mut handler = handler.write().await; handler.handle_add_movie(movie).await } @@ -156,7 +156,7 @@ where let query: MovieSearchQuery = query.into_inner(); - let handler = handler.read().unwrap(); + let handler = handler.read().await; handler.handle_search_movies(query).await } @@ -175,7 +175,7 @@ where let id: MovieId = query.into_inner().id; - let handler = handler.read().unwrap(); + let handler = handler.read().await; handler.handle_get_movie(id).await } @@ -194,7 +194,7 @@ where let id: MovieId = query.into_inner().id; - let mut handler = handler.write().unwrap(); + let mut handler = handler.write().await; handler.handle_delete_movie(id).await } @@ -215,7 +215,7 @@ where let id: MovieId = query.into_inner().id; - let mut handler = handler.write().unwrap(); + let mut handler = handler.write().await; handler.handle_upload_movie(id, multipart).await } @@ -234,7 +234,7 @@ where let id: MovieId = query.into_inner().id; - let handler = handler.read().unwrap(); + let handler = handler.read().await; handler.handle_download_movie(id).await } diff --git a/movies-db-service/movies-db/src/storage/file_storage.rs b/movies-db-service/movies-db/src/storage/file_storage.rs index 6ff655a..f83e59b 100644 --- a/movies-db-service/movies-db/src/storage/file_storage.rs +++ b/movies-db-service/movies-db/src/storage/file_storage.rs @@ -123,7 +123,7 @@ impl FileStorage { fn get_movie_data_path(&self, id: &MovieId) -> PathBuf { let mut file_path = self.root_dir.clone(); - file_path.push(format!("{}", id)); + file_path.push(id); file_path }