Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce stricter clippy lints #182

Merged
merged 2 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
allow-unwrap-in-tests = true
allow-expect-in-tests = true
5 changes: 4 additions & 1 deletion src/builtins/impls/crypto.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -125,7 +125,10 @@ pub mod x509 {

use anyhow::{bail, Result};

/// A X509 certificate
type X509 = HashMap<String, serde_json::Value>;

/// A JSON Web Key
type Jwk = HashMap<String, serde_json::Value>;

/// Returns one or more certificates from the given string containing PEM or
Expand Down
7 changes: 6 additions & 1 deletion src/builtins/impls/io.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -20,8 +20,13 @@ pub mod jwt {

use anyhow::{bail, Result};

/// The headers part of a JWT
type Headers = serde_json::Value;

/// The payload part of a JWT
type Payload = serde_json::Value;

/// A JSON Web Key
type Jwk = serde_json::Value;

/// Decodes a JSON Web Token and outputs it as an object.
Expand Down
5 changes: 4 additions & 1 deletion src/builtins/impls/opa.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -21,8 +21,11 @@ use serde::Serialize;
/// Metadata about the OPA runtime
#[derive(Serialize)]
pub struct Runtime {
/// A map of the current environment variables
env: HashMap<String, String>,
/// The version of OPA runtime. This is currently set to an empty string
version: String,
/// The commit hash of the OPA runtime. This is currently set to an empty
commit: String,
}

Expand Down
9 changes: 6 additions & 3 deletions src/builtins/impls/time.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -35,6 +35,7 @@ pub enum TimestampWithOptionalTimezone {
}

impl TimestampWithOptionalTimezone {
/// Converts the timestamp into a [`DateTime`] in the UTC timezone
fn into_datetime(self) -> Result<DateTime<Tz>> {
let (ts, tz) = match self {
Self::Timestamp(ts) => (ts, Tz::UTC),
Expand Down Expand Up @@ -89,8 +90,10 @@ pub fn diff(ns1: serde_json::Value, ns2: serde_json::Value) -> Result<(u8, u8, u

/// Returns the current time since epoch in nanoseconds.
#[tracing::instrument(name = "time.now_ns", skip(ctx))]
pub fn now_ns<C: EvaluationContext>(ctx: &mut C) -> i64 {
ctx.now().timestamp_nanos_opt().unwrap()
pub fn now_ns<C: EvaluationContext>(ctx: &mut C) -> Result<i64> {
ctx.now()
.timestamp_nanos_opt()
.context("Timestamp out of range")
}

/// Returns the duration in nanoseconds represented by a string.
Expand Down
17 changes: 16 additions & 1 deletion src/builtins/traits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,9 +32,14 @@ pub trait Builtin<C>: Send + Sync {
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, anyhow::Error>> + Send + 'a>>;
}

/// A wrapper around a builtin function with various const markers, to help
/// implement the [`Builtin`] trait
#[derive(Clone)]
struct WrappedBuiltin<F, C, const ASYNC: bool, const RESULT: bool, const CONTEXT: bool, P> {
/// The actual function to call
func: F,

/// Phantom data to help with the type inference
_marker: PhantomData<fn() -> (C, P)>,
}

Expand Down Expand Up @@ -63,12 +68,15 @@ pub(crate) trait BuiltinFunc<
P: 'static,
>: Sized + Send + Sync + 'static
{
/// Call the function, with a list of arguments, each argument being a JSON
/// reprensentation of the parameter value.
fn call<'a>(
&'a self,
context: &'a mut C,
args: &'a [&'a [u8]],
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, anyhow::Error>> + Send + 'a>>;

/// Wrap the function into a [`Builtin`] trait object
fn wrap(self) -> Box<dyn Builtin<C>> {
Box::new(WrappedBuiltin {
func: self,
Expand All @@ -77,6 +85,7 @@ pub(crate) trait BuiltinFunc<
}
}

/// A macro to count the number of items
macro_rules! count {
() => (0usize);
( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
Expand All @@ -99,6 +108,8 @@ macro_rules! unwrap {
};
}

/// A helper macro used by the [`trait_impl`] macro to generate the right
/// function call, depending on whether the function takes a context or not
macro_rules! call {
($self:ident, $ctx:expr, ($($pname:ident),*), context = true) => {
$self($ctx, $($pname),*)
Expand All @@ -111,6 +122,8 @@ macro_rules! call {
};
}

/// A helper macro used by the [`trait_impl`] macro to generate the body of the
/// call method in the trait
macro_rules! trait_body {
(($($pname:ident: $ptype:ident),*), async = $async:tt, result = $result:tt, context = $context:tt) => {
fn call<'a>(
Expand All @@ -134,6 +147,8 @@ macro_rules! trait_body {
};
}

/// A macro which implements the [`BuiltinFunc`] trait for a given number of
/// parameters
macro_rules! trait_impl {
($($pname:ident: $ptype:ident),*) => {
// Implementation for a non-async, non-result function, without context
Expand Down
10 changes: 9 additions & 1 deletion src/context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Trait definition for the context passed through builtin evaluation

#![allow(clippy::module_name_repetitions)]

use std::collections::HashMap;
Expand Down Expand Up @@ -55,8 +57,10 @@ pub trait EvaluationContext: Send + 'static {

/// The default evaluation context implementation
pub struct DefaultContext {
/// The cache used to store values during evaluation
cache: HashMap<String, serde_json::Value>,

/// The time at which the evaluation started
#[cfg(feature = "time")]
evaluation_time: chrono::DateTime<chrono::Utc>,
}
Expand Down Expand Up @@ -116,6 +120,7 @@ impl EvaluationContext for DefaultContext {
}
}

/// Test utilities
pub mod tests {
use anyhow::Result;
#[cfg(feature = "time")]
Expand All @@ -126,11 +131,14 @@ pub mod tests {

/// A context used in tests
pub struct TestContext {
/// The inner [`DefaultContext`]
inner: DefaultContext,

/// The mocked time
#[cfg(feature = "time")]
clock: chrono::DateTime<chrono::Utc>,

/// The seed used for the random number generator
#[cfg(feature = "rng")]
seed: u64,
}
Expand Down
15 changes: 14 additions & 1 deletion src/funcs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -12,11 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Typed functions exported by the OPA WASM module

use anyhow::{Context, Result};
use wasmtime::{AsContextMut, Caller, Instance, Memory, TypedFunc};

use crate::types::{Addr, Ctx, EntrypointId, Heap, NulStr, OpaError, Value};

/// Get a [`TypedFunc`] for the given export name from a wasmtime [`Caller`]
fn from_caller<Params, Results, T>(
name: &'static str,
caller: &mut Caller<'_, T>,
Expand All @@ -34,6 +37,7 @@ where
.with_context(|| format!("exported function {name:?} does not have the right signature"))
}

/// Get a [`TypedFunc`] for the given export name from a wasmtime [`Instance`]
fn from_instance<Params, Results, T>(
name: &'static str,
mut store: impl AsContextMut<Data = T>,
Expand All @@ -52,17 +56,25 @@ where
.with_context(|| format!("exported function {name:?} does not have the right signature"))
}

/// A helper trait which helps extracting a WASM function to be called from a
/// Rust context
pub trait Func: Sized {
/// The name of the WASM export to extract
const EXPORT: &'static str;
/// The type of the parameters of the function
type Params: wasmtime::WasmParams;
/// The type of the results of the function
type Results: wasmtime::WasmResults;

/// Create a new instance of the function from a `TypedFunc`
fn from_func(func: TypedFunc<Self::Params, Self::Results>) -> Self;

/// Create a new instance of the function from a wasmtime [`Caller`]
fn from_caller<T>(caller: &mut Caller<'_, T>) -> Result<Self> {
Ok(Self::from_func(from_caller(Self::EXPORT, caller)?))
}

/// Create a new instance of the function from a wasmtime [`Instance`]
fn from_instance<T>(store: impl AsContextMut<Data = T>, instance: &Instance) -> Result<Self> {
Ok(Self::from_func(from_instance(
Self::EXPORT,
Expand Down Expand Up @@ -395,6 +407,7 @@ impl OpaJsonDump {
Ok(NulStr(res))
}

/// Decode the JSON value at the given memory pointer
pub async fn decode<V: for<'de> serde::Deserialize<'de>, T: Send>(
&self,
mut store: impl AsContextMut<Data = T>,
Expand Down
18 changes: 15 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -13,9 +13,21 @@
// limitations under the License.

#![doc = include_str!("../README.md")]
#![deny(missing_docs, clippy::pedantic)]
#![deny(
missing_docs,
clippy::all,
clippy::pedantic,
clippy::missing_docs_in_private_items,
clippy::panic, // Disallow panics
clippy::print_stderr, // Disallow directly writing to stderr. Use tracing instead
clippy::print_stdout, // Disallow directly writing to stdout. Use tracing instead
clippy::unwrap_used, // Disallow the use of Result::{unwrap,expect}. Propagate errors instaed
clippy::unwrap_in_result,
clippy::expect_used,
)]
#![allow(clippy::blocks_in_conditions)]

pub mod builtins;
mod builtins;
mod context;
mod funcs;
#[cfg(feature = "loader")]
Expand Down
4 changes: 3 additions & 1 deletion src/loader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Helpers to load OPA compiled bundles

use std::path::Path;

use anyhow::Context;
Expand Down
Loading
Loading