diff --git a/.bazelrc b/.bazelrc index d178c6da..64cb40a1 100644 --- a/.bazelrc +++ b/.bazelrc @@ -59,4 +59,9 @@ coverage --test_env=LLVM_PROFILE_CONTINUOUS_MODE=1 coverage --cxxopt -mllvm coverage --cxxopt -runtime-counter-relocation +# Clippy linting (enabled by default) +build --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect +build --output_groups=+clippy_checks +build --@rules_rust//rust/settings:clippy.toml=@score_rust_policies//clippy/strict:clippy.toml + import quality/sanitizer/sanitizer.bazelrc diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml new file mode 100644 index 00000000..fcd1595e --- /dev/null +++ b/.github/workflows/clippy.yml @@ -0,0 +1,28 @@ +# ******************************************************************************* +# Copyright (c) 2025 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +name: Bazel Clippy + +on: + pull_request: + types: [opened, reopened, synchronize] + push: + branches: + - main + merge_group: + types: [checks_requested] + +jobs: + bazel-clippy: + uses: eclipse-score/cicd-workflows/.github/workflows/static-analysis.yml@main + with: + bazel-target: "build //:clippy" diff --git a/BUILD b/BUILD index 16329a50..ffbe3283 100644 --- a/BUILD +++ b/BUILD @@ -13,6 +13,7 @@ load("@aspect_rules_lint//format:defs.bzl", "format_multirun", "format_test") load("@rules_python//python:pip.bzl", "compile_pip_requirements") +load("@rules_rust//rust:defs.bzl", "rust_clippy") load("@score_tooling//:defs.bzl", "copyright_checker") compile_pip_requirements( @@ -55,3 +56,29 @@ format_test( tags = ["manual"], workspace = "//:LICENSE", ) + +rust_clippy( + name = "clippy", + testonly = True, + tags = ["manual"], + visibility = ["//:__subpackages__"], + deps = [ + "//score/mw/com/example/com-api-example/com-api-gen:com-api-gen", + "//score/mw/com/example/com-api-example:com-api-example", + "//score/mw/com/example/ipc_bridge:ipc_bridge_rs", + "//score/mw/com/example/ipc_bridge:ipc_bridge_gen_rs", + "//score/mw/com/example/com-api-example:com-api-example-test", + "//score/mw/com/impl/plumbing:sample_ptr_rs", + "//score/mw/com/impl/rust:common", + "//score/mw/com/impl/rust:macros", + "//score/mw/com/impl/rust:mw_com", + "//score/mw/com/impl/rust:proxy_bridge_rs", + "//score/mw/com/impl/rust:skeleton_bridge_rs", + "//score/mw/com/impl/rust/com-api/com-api:com-api", + "//score/mw/com/impl/rust/com-api/com-api-concept:com-api-concept", + "//score/mw/com/impl/rust/com-api/com-api-concept:com-api-concept-test", + "//score/mw/com/impl/rust/com-api/com-api-runtime-lola:com-api-runtime-lola", + "//score/mw/com/impl/rust/com-api/com-api-runtime-mock:com-api-runtime-mock", + "//score/mw/com/impl/rust/test:proxy_bridge_integration_test", + ], +) diff --git a/MODULE.bazel b/MODULE.bazel index 847493c5..3d73da76 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -92,6 +92,7 @@ bazel_dep(name = "aspect_rules_lint", version = "1.10.2") bazel_dep(name = "googletest", version = "1.15.0") bazel_dep(name = "google_benchmark", version = "1.9.1") bazel_dep(name = "rules_rust", version = "0.61.0") +bazel_dep(name = "score_rust_policies", version = "0.0.2", dev_dependency = True) bazel_dep(name = "buildifier_prebuilt", version = "6.3.3") bazel_dep(name = "score_crates", version = "0.0.4", repo_name = "crate_index") diff --git a/README.md b/README.md index c371e059..9478db09 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,12 @@ bazel test //... bazel build //score/mw/com:all ``` +## Clippy + +- Clippy runs by default via `.bazelrc` when building Rust targets. +- Use `bazel build //:clippy` for an explicit lint-only target, or `bazel build //score/mw/com/...` while developing. +- The Clippy config comes from `@score_rust_policies//clippy/strict:clippy.toml`. + ## Project Structure ``` diff --git a/score/mw/com/example/com-api-example/BUILD b/score/mw/com/example/com-api-example/BUILD index 2d646337..1d6f1f62 100644 --- a/score/mw/com/example/com-api-example/BUILD +++ b/score/mw/com/example/com-api-example/BUILD @@ -26,7 +26,11 @@ rust_binary( rust_test( name = "com-api-example-test", crate = ":com-api-example", - tags = ["manual"], + tags = [ + "manual", + "no-clippy", + ], + visibility = ["//:__subpackages__"], deps = [ "//score/mw/com/example/com-api-example/com-api-gen", "//score/mw/com/impl/rust/com-api/com-api", diff --git a/score/mw/com/example/com-api-example/basic-consumer-producer.rs b/score/mw/com/example/com-api-example/basic-consumer-producer.rs index 743bc28b..ad092954 100644 --- a/score/mw/com/example/com-api-example/basic-consumer-producer.rs +++ b/score/mw/com/example/com-api-example/basic-consumer-producer.rs @@ -64,18 +64,14 @@ fn use_consumer(runtime: &R) -> VehicleConsumer { .find(|desc| desc.get_instance_identifier().as_ref() == "/My/Funk/ServiceName") .unwrap(); - let consumer = consumer_builder.build().unwrap(); - // - consumer + consumer_builder.build().unwrap() } fn use_producer(runtime: &R) -> VehicleOfferedProducer { let producer_builder = runtime.producer_builder::>( InstanceSpecifier::new("/My/Funk/ServiceName").unwrap(), ); - let producer = producer_builder.build().unwrap(); - let offered_producer = producer.offer().unwrap(); - offered_producer + producer_builder.build().unwrap().offer().unwrap() } fn run_with_runtime(name: &str, runtime: &R) { diff --git a/score/mw/com/example/ipc_bridge/BUILD b/score/mw/com/example/ipc_bridge/BUILD index 3979affd..4e9f0673 100644 --- a/score/mw/com/example/ipc_bridge/BUILD +++ b/score/mw/com/example/ipc_bridge/BUILD @@ -67,7 +67,7 @@ rust_library( name = "ipc_bridge_gen_rs", srcs = ["ipc_bridge_gen.rs"], visibility = [ - "//score/mw/com:__subpackages__", + "//:__subpackages__", ], deps = [ ":ipc_bridge_gen_cpp", @@ -82,6 +82,7 @@ rust_binary( data = ["etc/mw_com_config.json"], features = ["link_std_cpp_lib"], rustc_flags = ["-Clink-arg=-lstdc++"], + visibility = ["//:__subpackages__"], deps = [ ":ipc_bridge_gen_rs", "//score/mw/com/impl/rust:mw_com", diff --git a/score/mw/com/example/ipc_bridge/ipc_bridge.rs b/score/mw/com/example/ipc_bridge/ipc_bridge.rs index 38630689..7c018058 100644 --- a/score/mw/com/example/ipc_bridge/ipc_bridge.rs +++ b/score/mw/com/example/ipc_bridge/ipc_bridge.rs @@ -69,16 +69,16 @@ fn run + Send>(future: F) { futures::executor::block_on(future); } -fn run_recv_mode(instance_specifier: mw_com::InstanceSpecifier) { - let handles = loop { - let handles = mw_com::proxy::find_service(instance_specifier.clone()) - .expect("Instance specifier resolution failed"); - if handles.len() > 0 { - break handles; - } else { - println!("No service found, retrying in 1 second"); - sleep(SERVICE_DISCOVERY_SLEEP_DURATION); - } + fn run_recv_mode(instance_specifier: mw_com::InstanceSpecifier) { + let handles = loop { + let handles = mw_com::proxy::find_service(instance_specifier.clone()) + .expect("Instance specifier resolution failed"); + if !handles.is_empty() { + break handles; + } else { + println!("No service found, retrying in 1 second"); + sleep(SERVICE_DISCOVERY_SLEEP_DURATION); + } }; let ipc_bridge_gen_rs::IpcBridge::Proxy { diff --git a/score/mw/com/example/ipc_bridge/ipc_bridge_gen.rs b/score/mw/com/example/ipc_bridge/ipc_bridge_gen.rs index 19c3fdba..4add2aaa 100644 --- a/score/mw/com/example/ipc_bridge/ipc_bridge_gen.rs +++ b/score/mw/com/example/ipc_bridge/ipc_bridge_gen.rs @@ -9,31 +9,27 @@ * https://www.apache.org/licenses/LICENSE-2.0 * * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -///! This is the "generated" part for the ipc_bridge proxy. Its main purpose is to provide the imports -///! of the type- and name-dependent part of the FFI and create the respective user-facing objects. -use std::default::Default; +********************************************************************************/ +#![allow(clippy::not_unsafe_ptr_arg_deref)] +//! This is the "generated" part for the ipc_bridge proxy. Its main purpose is to provide the imports +//! of the type- and name-dependent part of the FFI and create the respective user-facing objects. use std::ffi::c_char; pub const MAX_SUCCESSORS: libc::size_t = 16; pub const MAX_LANES: libc::size_t = 16; #[repr(u32)] +#[derive(Default)] pub enum StdTimestampSyncState { #[allow(non_camel_case_types)] kStdTimestampSyncState_InSync = 0, #[allow(non_camel_case_types)] kStdTimestampSyncState_NotInSync = 1, #[allow(non_camel_case_types)] + #[default] kStdTimestampSyncState_Invalid = 255, } -impl Default for StdTimestampSyncState { - fn default() -> Self { - StdTimestampSyncState::kStdTimestampSyncState_Invalid - } -} - #[repr(C)] #[derive(Default)] pub struct StdTimestamp { @@ -43,7 +39,7 @@ pub struct StdTimestamp { } #[repr(u32)] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub enum EventDataQualifier { /// @brief Event data available, normal operation. /// @@ -61,6 +57,7 @@ pub enum EventDataQualifier { /// on the reason for non-availability. /// /// The remaining information in the scope of the event (except extendedQualifier) must not be evaluated. + #[default] EventDataNotAvailable = 2, /// @brief There is no event data available, due to the event data being invalid (e.g. CRC error) or due to a /// timeout. @@ -69,12 +66,6 @@ pub enum EventDataQualifier { EventDataInvalid = 255, } -impl Default for EventDataQualifier { - fn default() -> Self { - EventDataQualifier::EventDataNotAvailable - } -} - #[repr(C)] #[derive(Default)] pub struct MapApiLaneBoundaryData { diff --git a/score/mw/com/impl/plumbing/BUILD b/score/mw/com/impl/plumbing/BUILD index 67128aa3..73c4a113 100644 --- a/score/mw/com/impl/plumbing/BUILD +++ b/score/mw/com/impl/plumbing/BUILD @@ -686,7 +686,7 @@ rust_library( name = "sample_ptr_rs", srcs = ["sample_ptr.rs"], visibility = [ - "//score/mw/com:__subpackages__", + "//:__subpackages__", ], deps = ["@crate_index//:libc"], ) diff --git a/score/mw/com/impl/rust/BUILD b/score/mw/com/impl/rust/BUILD index c5f1db9d..e5094165 100644 --- a/score/mw/com/impl/rust/BUILD +++ b/score/mw/com/impl/rust/BUILD @@ -17,6 +17,7 @@ load("//score/mw:common_features.bzl", "COMPILER_WARNING_FEATURES") rust_library( name = "common", srcs = ["common.rs"], + visibility = ["//:__subpackages__"], ) cc_library( @@ -66,7 +67,7 @@ rust_library( name = "proxy_bridge_rs", srcs = ["proxy_bridge.rs"], visibility = [ - "//score/mw/com:__subpackages__", + "//:__subpackages__", ], deps = [ ":proxy_bridge_cpp", @@ -80,7 +81,7 @@ rust_library( name = "skeleton_bridge_rs", srcs = ["skeleton_bridge.rs"], visibility = [ - "//score/mw/com:__subpackages__", + "//:__subpackages__", ], deps = [ ":common", @@ -93,6 +94,7 @@ rust_library( proc_macro_deps = [ "@crate_index//:paste", ], + visibility = ["//:__subpackages__"], deps = [ ":common", ":proxy_bridge_rs", diff --git a/score/mw/com/impl/rust/com-api/com-api-concept/BUILD b/score/mw/com/impl/rust/com-api/com-api-concept/BUILD index 294f4893..30cce709 100644 --- a/score/mw/com/impl/rust/com-api/com-api-concept/BUILD +++ b/score/mw/com/impl/rust/com-api/com-api-concept/BUILD @@ -28,6 +28,10 @@ rust_library( rust_test( name = "com-api-concept-test", crate = ":com-api-concept", - tags = ["manual"], + tags = [ + "manual", + "no-clippy", + ], + visibility = ["//:__subpackages__"], deps = [":com-api-concept"], ) diff --git a/score/mw/com/impl/rust/com-api/com-api-concept/com_api_concept.rs b/score/mw/com/impl/rust/com-api/com-api-concept/com_api_concept.rs index c8078498..2cd51c62 100644 --- a/score/mw/com/impl/rust/com-api/com-api-concept/com_api_concept.rs +++ b/score/mw/com/impl/rust/com-api/com-api-concept/com_api_concept.rs @@ -195,15 +195,13 @@ impl InstanceSpecifier { let service_name = service_name.strip_prefix('/').unwrap(); // Check each character - let is_legal_char = |c| { - (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' - }; + let is_legal_char = |c: char| c.is_ascii_alphanumeric() || c == '_'; //validation of each path segment !service_name.is_empty() && service_name.split('/').all(|parts| { // No empty segments (reject trailing "/" and "//" in the middle) - !parts.is_empty() && parts.chars().all(|c| is_legal_char(c)) + !parts.is_empty() && parts.chars().all(is_legal_char) }) } @@ -249,9 +247,9 @@ pub enum FindServiceSpecifier { } /// Convert an InstanceSpecifier into a FindServiceSpecifier -impl Into for InstanceSpecifier { - fn into(self) -> FindServiceSpecifier { - FindServiceSpecifier::Specific(self) +impl From for FindServiceSpecifier { + fn from(val: InstanceSpecifier) -> Self { + FindServiceSpecifier::Specific(val) } } @@ -269,7 +267,6 @@ impl Into for InstanceSpecifier { /// /// Since it is yet to be proven whether this trait can be implemented safely (assumption is: no) it /// is unsafe for now. The expectation is that very few users ever need to implement this manually. - /// A `Sample` provides a reference to a memory buffer of an event with immutable value. /// /// By implementing the `Deref` trait implementations of the trait support the `.` operator for dereferencing. @@ -437,7 +434,7 @@ where /// # Returns /// /// A 'Result' containing the allocated sample buffer on success and an 'Error' on failure. - fn allocate<'a>(&'a self) -> Result>; + fn allocate(&self) -> Result>; /// Allocate, initialize, and send an event sample in one step. /// diff --git a/score/mw/com/impl/rust/com-api/com-api-concept/reloc.rs b/score/mw/com/impl/rust/com-api/com-api-concept/reloc.rs index 8cbdc2b4..ce88502c 100644 --- a/score/mw/com/impl/rust/com-api/com-api-concept/reloc.rs +++ b/score/mw/com/impl/rust/com-api/com-api-concept/reloc.rs @@ -11,6 +11,13 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +/// Marker trait for relocatable types used across FFI boundaries. +/// +/// # Safety +/// +/// Implementors must ensure the type has no self-references or other invariants that would be +/// violated by moving the value in memory. Only types that remain valid under relocation should +/// implement this trait. pub unsafe trait Reloc {} unsafe impl Reloc for () {} diff --git a/score/mw/com/impl/rust/com-api/com-api-runtime-lola/runtime.rs b/score/mw/com/impl/rust/com-api/com-api-runtime-lola/runtime.rs index b69c931f..4c026c29 100644 --- a/score/mw/com/impl/rust/com-api/com-api-runtime-lola/runtime.rs +++ b/score/mw/com/impl/rust/com-api/com-api-runtime-lola/runtime.rs @@ -82,7 +82,7 @@ where event: &'a LolaEvent, } -unsafe impl<'a, T> Send for LolaBinding<'a, T> where T: Send {} +unsafe impl Send for LolaBinding<'_, T> where T: Send {} #[derive(Debug)] enum SampleBinding<'a, T> @@ -104,7 +104,7 @@ where static ID_COUNTER: AtomicUsize = AtomicUsize::new(0); -impl<'a, T> From for Sample<'a, T> +impl From for Sample<'_, T> where T: Reloc + Send + Debug, { @@ -116,7 +116,7 @@ where } } -impl<'a, T> Deref for Sample<'a, T> +impl Deref for Sample<'_, T> where T: Reloc + Send + Debug, { @@ -130,9 +130,9 @@ where } } -impl<'a, T> com_api_concept::Sample for Sample<'a, T> where T: Send + Reloc + Debug {} +impl com_api_concept::Sample for Sample<'_, T> where T: Send + Reloc + Debug {} -impl<'a, T> PartialEq for Sample<'a, T> +impl PartialEq for Sample<'_, T> where T: Send + Reloc + Debug, { @@ -141,9 +141,9 @@ where } } -impl<'a, T> Eq for Sample<'a, T> where T: Send + Reloc + Debug {} +impl Eq for Sample<'_, T> where T: Send + Reloc + Debug {} -impl<'a, T> PartialOrd for Sample<'a, T> +impl PartialOrd for Sample<'_, T> where T: Send + Reloc + Debug, { @@ -152,7 +152,7 @@ where } } -impl<'a, T> Ord for Sample<'a, T> +impl Ord for Sample<'_, T> where T: Send + Reloc + Debug, { @@ -185,7 +185,7 @@ where } } -impl<'a, T> Deref for SampleMut<'a, T> +impl Deref for SampleMut<'_, T> where T: Reloc, { @@ -196,7 +196,7 @@ where } } -impl<'a, T> DerefMut for SampleMut<'a, T> +impl DerefMut for SampleMut<'_, T> where T: Reloc, { @@ -236,7 +236,7 @@ where } -impl<'a, T> AsMut> for SampleMaybeUninit<'a, T> +impl AsMut> for SampleMaybeUninit<'_, T> where T: Reloc + Send + Debug, { @@ -360,7 +360,7 @@ where { type SampleMaybeUninit<'a> = SampleMaybeUninit<'a, T> where Self: 'a; - fn allocate<'a>(&'a self) -> com_api_concept::Result> { + fn allocate(&self) -> com_api_concept::Result> { Ok(SampleMaybeUninit { data: MaybeUninit::uninit(), lifetime: PhantomData, diff --git a/score/mw/com/impl/rust/com-api/com-api-runtime-mock/runtime.rs b/score/mw/com/impl/rust/com-api/com-api-runtime-mock/runtime.rs index 1c310805..8660a029 100644 --- a/score/mw/com/impl/rust/com-api/com-api-runtime-mock/runtime.rs +++ b/score/mw/com/impl/rust/com-api/com-api-runtime-mock/runtime.rs @@ -84,7 +84,7 @@ where event: &'a MockEvent, } -unsafe impl<'a, T> Send for MockBinding<'a, T> where T: Send {} +unsafe impl Send for MockBinding<'_, T> where T: Send {} #[derive(Debug)] enum SampleBinding<'a, T> @@ -106,7 +106,7 @@ where static ID_COUNTER: AtomicUsize = AtomicUsize::new(0); -impl<'a, T> From for Sample<'a, T> +impl From for Sample<'_, T> where T: Reloc + Send + Debug, { @@ -118,7 +118,7 @@ where } } -impl<'a, T> Deref for Sample<'a, T> +impl Deref for Sample<'_, T> where T: Reloc + Send + Debug, { @@ -132,9 +132,9 @@ where } } -impl<'a, T> com_api_concept::Sample for Sample<'a, T> where T: Send + Reloc + Debug {} +impl com_api_concept::Sample for Sample<'_, T> where T: Send + Reloc + Debug {} -impl<'a, T> PartialEq for Sample<'a, T> +impl PartialEq for Sample<'_, T> where T: Send + Reloc + Debug, { @@ -143,9 +143,9 @@ where } } -impl<'a, T> Eq for Sample<'a, T> where T: Send + Reloc + Debug {} +impl Eq for Sample<'_, T> where T: Send + Reloc + Debug {} -impl<'a, T> PartialOrd for Sample<'a, T> +impl PartialOrd for Sample<'_, T> where T: Send + Reloc + Debug, { @@ -154,7 +154,7 @@ where } } -impl<'a, T> Ord for Sample<'a, T> +impl Ord for Sample<'_, T> where T: Send + Reloc + Debug, { @@ -187,7 +187,7 @@ where } } -impl<'a, T> Deref for SampleMut<'a, T> +impl Deref for SampleMut<'_, T> where T: Reloc, { @@ -198,7 +198,7 @@ where } } -impl<'a, T> DerefMut for SampleMut<'a, T> +impl DerefMut for SampleMut<'_, T> where T: Reloc, { @@ -237,7 +237,7 @@ where } } -impl<'a, T> AsMut> for SampleMaybeUninit<'a, T> +impl AsMut> for SampleMaybeUninit<'_, T> where T: Reloc + Send + Debug, { @@ -361,7 +361,7 @@ where { type SampleMaybeUninit<'a> = SampleMaybeUninit<'a, T> where Self: 'a; - fn allocate<'a>(&'a self) -> com_api_concept::Result> { + fn allocate(&self) -> com_api_concept::Result> { Ok(SampleMaybeUninit { data: MaybeUninit::uninit(), lifetime: PhantomData, diff --git a/score/mw/com/impl/rust/proxy_bridge.rs b/score/mw/com/impl/rust/proxy_bridge.rs index 63243efa..b2915794 100644 --- a/score/mw/com/impl/rust/proxy_bridge.rs +++ b/score/mw/com/impl/rust/proxy_bridge.rs @@ -10,16 +10,16 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -///! This module provides boilerplate for a generated bridge between the Rust and C++ code for the -///! proxy side of a service. -///! -///! It contains any code that does not depend on a user-defined type or can be made generic over -///! the user-defined type, e.g. when the type isn't relevant for the enclosing type's layout and -///! no type safety is needed on API level. For any actions that are type-dependent, the action -///! needs to be implemented by external code. This happens by implementing `EventOps` and -///! `ProxyOps` for the user-defined type. The implementation typically will call the respective -///! generated FFI functions to operate on the typed objects like the event itself or the sample -///! pointer. See the documentation of the respective traits for more details. +//! This module provides boilerplate for a generated bridge between the Rust and C++ code for the +//! proxy side of a service. +//! +//! It contains any code that does not depend on a user-defined type or can be made generic over +//! the user-defined type, e.g. when the type isn't relevant for the enclosing type's layout and +//! no type safety is needed on API level. For any actions that are type-dependent, the action +//! needs to be implemented by external code. This happens by implementing `EventOps` and +//! `ProxyOps` for the user-defined type. The implementation typically will call the respective +//! generated FFI functions to operate on the typed objects like the event itself or the sample +//! pointer. See the documentation of the respective traits for more details. use std::collections::VecDeque; use std::ffi::CString; @@ -93,15 +93,16 @@ mod ffi { data: *mut (), } - impl Into<*mut (dyn FnMut() + Send + 'static)> for FatPtr { - fn into(self) -> *mut (dyn FnMut() + Send + 'static) { + impl From for *mut (dyn FnMut() + Send + 'static) { + fn from(val: FatPtr) -> Self { // SAFETY: Since we're transmuting into a pointer and using that pointer is unsafe // anyway, the `transmute` is not unsafe since it's a pure relabelling that, by itself, // does not introduce undefined behavior. - unsafe { transmute(self) } + unsafe { transmute(val) } } } + #[allow(clippy::not_unsafe_ptr_arg_deref)] impl From<*mut (dyn FnMut() + Send + 'static)> for FatPtr { fn from(ptr: *mut (dyn FnMut() + Send + 'static)) -> Self { // SAFETY: Since we're transmuting into a pair of pointers and using those pointers is @@ -271,6 +272,7 @@ impl ProxyManager { /// /// # Errors /// If the creation of the proxy fails, this function will return `Err(())`. + #[allow(clippy::result_unit_err)] pub fn new(handle: &HandleType) -> Result { ProxyWrapperGuard::new(handle).map(|proxy| Self(Arc::new(proxy))) } @@ -313,12 +315,12 @@ pub trait EventOps: Sized { /// /// This function must be called with a pointer to a valid event of the type `T`. The event behind /// the pointer must not have been deleted already. -unsafe fn native_get_new_samples<'a, T: EventOps>( - native: *mut ffi::ProxyEvent, - callback: impl FnMut(*mut sample_ptr_rs::SamplePtr), -) -> usize { - unsafe { ::get_new_samples(native, callback) } -} + unsafe fn native_get_new_samples( + native: *mut ffi::ProxyEvent, + callback: impl FnMut(*mut sample_ptr_rs::SamplePtr), + ) -> usize { + unsafe { ::get_new_samples(native, callback) } + } /// # Safety /// @@ -452,7 +454,7 @@ impl<'a, const N: usize, T: EventOps> IntoIterator for SampleContainer<'a, N, T> type Item = SamplePtr<'a, T>; type IntoIter = std::iter::Rev>; - fn into_iter(mut self) -> Self::IntoIter { + fn into_iter(self) -> Self::IntoIter { self.samples.into_iter().rev() } } @@ -682,9 +684,13 @@ impl HandleContainer { unsafe { ffi::mw_com_impl_handle_container_get_size(self.inner) as usize } } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + /// Returns the first handle in the container, or 'None' if the container is empty. pub fn first(&self) -> Option<&HandleType> { - if self.len() > 0 { + if !self.is_empty() { Some(self.index(0)) } else { None @@ -725,6 +731,7 @@ impl Drop for HandleContainer { /// /// Returns a list of found instances, which can be empty in case there aren't any. If an error /// occurred during the search or no container is returned, this function will return `Err(())`. +#[allow(clippy::result_unit_err)] pub fn find_service(instance_specifier: InstanceSpecifier) -> Result { // SAFETY: Since we only pass the pointer received by the create FFI function, the call is // safe. @@ -749,14 +756,14 @@ where _event: PhantomData<&'a NativeProxyEvent>, } -impl<'a, T: EventOps> SamplePtr<'a, T> { +impl SamplePtr<'_, T> { /// Retrieve a reference to the data pointed to by the sample pointer. pub fn get_ref(&self) -> &T { ::get_sample_ref(&self.sample_ptr) } } -impl<'a, T> Drop for SamplePtr<'a, T> +impl Drop for SamplePtr<'_, T> where T: EventOps, { @@ -770,7 +777,7 @@ where } } -impl<'a, T> Deref for SamplePtr<'a, T> +impl Deref for SamplePtr<'_, T> where T: EventOps, { diff --git a/score/mw/com/impl/rust/skeleton_bridge.rs b/score/mw/com/impl/rust/skeleton_bridge.rs index 8c3c662f..9f151947 100644 --- a/score/mw/com/impl/rust/skeleton_bridge.rs +++ b/score/mw/com/impl/rust/skeleton_bridge.rs @@ -41,6 +41,7 @@ pub trait OfferState {} impl OfferState for UnOffered {} impl OfferState for Offered {} +#[allow(clippy::result_unit_err)] pub trait SkeletonOps: Sized { fn send(&self, event: *mut ffi::SkeletonEvent) -> common::Result<()>; } @@ -72,6 +73,7 @@ impl SkeletonEvent { } impl SkeletonEvent { + #[allow(clippy::result_unit_err)] pub fn send(&self, stamped_data: T) -> common::Result<()> { stamped_data.send(self.event) } diff --git a/score/mw/com/impl/rust/test/BUILD b/score/mw/com/impl/rust/test/BUILD index c87919da..56cea7cf 100644 --- a/score/mw/com/impl/rust/test/BUILD +++ b/score/mw/com/impl/rust/test/BUILD @@ -17,10 +17,11 @@ rust_test( name = "proxy_bridge_integration_test", srcs = ["proxy_skeleton_bridge_int_test.rs"], data = ["//score/mw/com/example/ipc_bridge:etc/mw_com_config.json"], - tags = ["manual"], - visibility = [ - "//score/mw/com:__subpackages__", + tags = [ + "manual", + "no-clippy", ], + visibility = ["//:__subpackages__"], deps = [ "//score/mw/com/example/ipc_bridge:ipc_bridge_gen_rs", "//score/mw/com/impl/rust:proxy_bridge_rs",