diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml new file mode 100644 index 0000000..9815a0b --- /dev/null +++ b/.github/workflows/pr-checks.yml @@ -0,0 +1,37 @@ +name: Pull request checks + +on: + pull_request: + +permissions: + contents: read + +concurrency: + group: pr-checks-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + rust: + name: Rust format, lint, and test + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Cache Rust build artifacts + uses: Swatinem/rust-cache@v2 + + - name: Check formatting + run: cargo fmt --all -- --check + + - name: Run Clippy + run: cargo clippy --all-targets --all-features --locked -- -D warnings + + - name: Run tests + run: cargo test --all-targets --all-features --locked diff --git a/src/handlers/admin.rs b/src/handlers/admin.rs index 9723175..ab4a36c 100644 --- a/src/handlers/admin.rs +++ b/src/handlers/admin.rs @@ -50,7 +50,6 @@ struct AdminInvitesTemplate { } struct PermissionOptionView { - input_id: String, value: &'static str, label: &'static str, description: &'static str, @@ -62,7 +61,6 @@ struct InviteView { link: String, note: Option, created_by: String, - created_at: String, expires_at: String, } @@ -238,9 +236,7 @@ fn permission_options(active_permissions: &[Permission]) -> Vec Result, AppError> { let mut permissions = Vec::new(); for value in values { - let Some(permission) = Permission::from_str(value) else { + let Some(permission) = Permission::parse(value) else { return Err(AppError::BadRequest("Unknown permission selected.")); }; @@ -274,7 +270,6 @@ impl InviteView { created_by: invite .created_by_username .unwrap_or_else(|| "Deleted user".to_owned()), - created_at: invite.created_at.format("%Y-%m-%d %H:%M UTC").to_string(), expires_at: invite.expires_at.format("%Y-%m-%d %H:%M UTC").to_string(), } } diff --git a/src/permissions.rs b/src/permissions.rs index c6716a7..a33e74d 100644 --- a/src/permissions.rs +++ b/src/permissions.rs @@ -45,7 +45,7 @@ impl Permission { } } - pub fn from_str(value: &str) -> Option { + pub fn parse(value: &str) -> Option { match value { "user.permissions.edit" => Some(Self::UserPermissionsEdit), "user.invites.create" => Some(Self::UserInvitesCreate), diff --git a/src/repositories/publications.rs b/src/repositories/publications.rs index 4c9e965..6e29adc 100644 --- a/src/repositories/publications.rs +++ b/src/repositories/publications.rs @@ -519,7 +519,8 @@ pub async fn create_publication( fn publication_summary_from_row(row: sqlx::postgres::PgRow) -> PublicationSummary { let title = row.get::("title"); - let contributor_names: Vec = row.get::, _>("contributor_names") + let contributor_names: Vec = row + .get::, _>("contributor_names") .into_iter() .filter(|n| !n.is_empty()) .collect(); diff --git a/src/repositories/user_permissions.rs b/src/repositories/user_permissions.rs index 1d70f14..507649d 100644 --- a/src/repositories/user_permissions.rs +++ b/src/repositories/user_permissions.rs @@ -21,7 +21,7 @@ pub async fn list_permissions_for_user( Ok(rows .into_iter() - .filter_map(|row| Permission::from_str(row.get("permission"))) + .filter_map(|row| Permission::parse(row.get("permission"))) .collect()) }