Skip to content

Commit

Permalink
Merge pull request #20887 from chrysn-pull-requests/fmt
Browse files Browse the repository at this point in the history
static_tests: Add test for Rust code formatting rules
  • Loading branch information
chrysn authored Oct 4, 2024
2 parents 248371e + d0299de commit 13188e1
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 54 deletions.
27 changes: 27 additions & 0 deletions dist/tools/cargo-checks/check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

set -eu

FAILURES=""

while IFS= read -r -d '' CARGOTOML
do
if cargo fmt --quiet --check --manifest-path "${CARGOTOML}"; then
continue
else
FAILURES="${FAILURES} ${CARGOTOML%Cargo.toml}"
fi
done < <(find . -name Cargo.toml -print0)

if [ x"" != x"${FAILURES}" ]; then
echo "Some Rust files are following rustfmt, in particular in:"
echo "${FAILURES}"
echo "You can format the code locally using:"
echo
echo "find -name Cargo.toml -exec cargo fmt --manifest-path '{}' ';'"
if [ -n "${GITHUB_RUN_ID:-}" ]; then
echo
echo "The author of this test regrets not knowing how to provide an easy way to just click a button here that provides the right fixup commits."
fi
exit 1
fi
1 change: 1 addition & 0 deletions dist/tools/ci/static_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ run ./dist/tools/buildsystem_sanity_check/check.sh
run ./dist/tools/feature_resolution/check.sh
run ./dist/tools/boards_supported/check.sh
run ./dist/tools/codespell/check.sh
run ./dist/tools/cargo-checks/check.sh
if [ -z "${GITHUB_RUN_ID}" ]; then
run ./dist/tools/uncrustify/uncrustify.sh --check
else
Expand Down
75 changes: 45 additions & 30 deletions drivers/lsm303agr/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#![no_std]

use lsm303agr::{interface, mode, Lsm303agr, AccelOutputDataRate::Hz50, AccelMode};
use lsm303agr::{interface, mode, AccelMode, AccelOutputDataRate::Hz50, Lsm303agr};

use riot_wrappers::{saul, println, i2c, cstr::cstr, mutex::Mutex};
use saul::{Phydat, registration};
use riot_wrappers::{cstr::cstr, i2c, mutex::Mutex, println, saul};
use saul::{registration, Phydat};

// FIXME: Is this the way we want to go? It's mimicking the C way, but we could just as well take
// the board config from some YAML.
Expand All @@ -29,8 +29,10 @@ static DRIVER_MAG: registration::Driver<SaulLSM, MagAspect> = registration::Driv
// device is registered. (In an alternative implementation where all SAUL registries are managed by
// XFA, this would be possible; finding the point in time when they are ready to be used would be
// tricky, though.).
static REG: Mutex<[Option<registration::Registration<SaulLSM>>; NDEVICES]> = Mutex::new([None; NDEVICES]);
static REG_MAG: Mutex<[Option<registration::Registration<SaulLSM, MagAspect>>; NDEVICES]> = Mutex::new([None; NDEVICES]);
static REG: Mutex<[Option<registration::Registration<SaulLSM>>; NDEVICES]> =
Mutex::new([None; NDEVICES]);
static REG_MAG: Mutex<[Option<registration::Registration<SaulLSM, MagAspect>>; NDEVICES]> =
Mutex::new([None; NDEVICES]);
// This can't go into ROM because it contains an inner Mutex (and possibly state data from the
// Lsm303agr instance, didn't bother to check)
static LSM: Mutex<[Option<SaulLSM>; NDEVICES]> = Mutex::new([None; NDEVICES]);
Expand All @@ -45,31 +47,40 @@ pub extern "C" fn auto_init_lsm303agr() {
/// Initialize the configured LSM303AGR device, returning an error string for debug if anything
/// goes wrong
fn init() -> Result<(), &'static str> {
let lsm = LSM
.try_leak()
.expect("LSM303AGR init is only called once");
let lsm = LSM.try_leak().expect("LSM303AGR init is only called once");

let reg = REG
.try_leak()
.expect("LSM303AGR init is only called once");
let reg = REG.try_leak().expect("LSM303AGR init is only called once");
let reg_mag = REG_MAG
.try_leak()
.expect("LSM303AGR init is only called once");

for (&i2cdev, (lsm, (reg, reg_mag))) in I2C_DEVICES.iter().zip(lsm.iter_mut().zip(reg.iter_mut().zip(reg_mag.iter_mut()))) {
for (&i2cdev, (lsm, (reg, reg_mag))) in I2C_DEVICES
.iter()
.zip(lsm.iter_mut().zip(reg.iter_mut().zip(reg_mag.iter_mut())))
{
let mut device = Lsm303agr::new_with_i2c(i2c::I2CDevice::new(i2cdev));

let mut init_clock = riot_wrappers::ztimer::Clock::msec();

device.init()
.map_err(|_| "Device initialization failed")?;
device.set_accel_mode_and_odr(&mut init_clock, AccelMode::Normal, Hz50)
device.init().map_err(|_| "Device initialization failed")?;
device
.set_accel_mode_and_odr(&mut init_clock, AccelMode::Normal, Hz50)
.map_err(|_| "Device configuration failed")?;

let lsm = lsm.insert(SaulLSM { device: Mutex::new(device) });

let reg = reg.insert(registration::Registration::new(&DRIVER, lsm, Some(cstr!("LSM303AGR accelerometer"))));
let reg_mag = reg_mag.insert(registration::Registration::new(&DRIVER_MAG, lsm, Some(cstr!("LSM303AGR magnetometer"))));
let lsm = lsm.insert(SaulLSM {
device: Mutex::new(device),
});

let reg = reg.insert(registration::Registration::new(
&DRIVER,
lsm,
Some(cstr!("LSM303AGR accelerometer")),
));
let reg_mag = reg_mag.insert(registration::Registration::new(
&DRIVER_MAG,
lsm,
Some(cstr!("LSM303AGR magnetometer")),
));

reg.register_static();
reg_mag.register_static();
Expand All @@ -89,13 +100,15 @@ impl registration::Drivable for &SaulLSM {

fn read(self) -> Result<Phydat, registration::Error> {
// SAUL doesn't guarantee exclusive access; different threads may read simultaneously.
let mut device = self.device.try_lock()
.ok_or(registration::Error)?;
let mut device = self.device.try_lock().ok_or(registration::Error)?;

let data = device.acceleration()
.map_err(|_| registration::Error)?;
let data = device.acceleration().map_err(|_| registration::Error)?;
// Data is in the +-2g range by default, which doesn't overflow even the i16 SAUL uses
Ok(Phydat::new(&[data.x_mg() as _, data.y_mg() as _, data.z_mg() as _], Some(saul::Unit::GForce), -3))
Ok(Phydat::new(
&[data.x_mg() as _, data.y_mg() as _, data.z_mg() as _],
Some(saul::Unit::GForce),
-3,
))
}
}

Expand All @@ -114,11 +127,13 @@ impl registration::Drivable for MagAspect {

fn read(self) -> Result<Phydat, registration::Error> {
// SAUL doesn't guarantee exclusive access; different threads may read simultaneously.
let mut device = self.0.device.try_lock()
.ok_or(registration::Error)?;

let data = device.magnetic_field()
.map_err(|_| registration::Error)?;
return Ok(Phydat::fit(&[data.x_nt(), data.y_nt(), data.z_nt()], Some(saul::Unit::T), -9))
let mut device = self.0.device.try_lock().ok_or(registration::Error)?;

let data = device.magnetic_field().map_err(|_| registration::Error)?;
return Ok(Phydat::fit(
&[data.x_nt(), data.y_nt(), data.z_nt()],
Some(saul::Unit::T),
-9,
));
}
}
14 changes: 10 additions & 4 deletions examples/rust-async/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// directory for more details.
#![no_std]

use riot_wrappers::riot_main;
use riot_wrappers::println;
use riot_wrappers::riot_main;
use riot_wrappers::ztimer::{Clock, Ticks};

use static_cell::StaticCell;
Expand All @@ -20,16 +20,22 @@ fn main() {
static EXECUTOR: StaticCell<embassy_executor_riot::Executor> = StaticCell::new();
let executor: &'static mut _ = EXECUTOR.init(embassy_executor_riot::Executor::new());
executor.run(|spawner| {
spawner.spawn(amain(spawner)).expect("Starting task for the first time");
spawner
.spawn(amain(spawner))
.expect("Starting task for the first time");
})
}

#[embassy_executor::task]
async fn amain(spawner: embassy_executor::Spawner) {
println!("Running asynchronously:");

spawner.spawn(fast_messages("A")).expect("Starting task for the first time");
spawner.spawn(fast_messages("B")).expect("Task is configured to allow two instances");
spawner
.spawn(fast_messages("A"))
.expect("Starting task for the first time");
spawner
.spawn(fast_messages("B"))
.expect("Task is configured to allow two instances");

let msec = Clock::msec();

Expand Down
53 changes: 39 additions & 14 deletions examples/rust-gcoap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
// directory for more details.
#![no_std]

use riot_wrappers::{riot_main, println};
use riot_wrappers::{gcoap, ztimer, gnrc};
use riot_wrappers::{gcoap, gnrc, ztimer};
use riot_wrappers::{println, riot_main};

use coap_handler_implementations::{ReportingHandlerBuilder, HandlerBuilder};
use coap_handler_implementations::{HandlerBuilder, ReportingHandlerBuilder};

extern crate rust_riotmodules;

Expand All @@ -21,40 +21,65 @@ fn main() {

unsafe { do_vfs_init() };

static PINGS: riot_coap_handler_demos::ping::PingPool = riot_coap_handler_demos::ping::PingPool::new();
static PING_PASSIVE: riot_coap_handler_demos::ping_passive::PingHistoryMutex<{ riot_coap_handler_demos::ping_passive::DEFAULT_SIZE }> = riot_coap_handler_demos::ping_passive::PingHistoryMutex::new();
static PINGS: riot_coap_handler_demos::ping::PingPool =
riot_coap_handler_demos::ping::PingPool::new();
static PING_PASSIVE: riot_coap_handler_demos::ping_passive::PingHistoryMutex<
{ riot_coap_handler_demos::ping_passive::DEFAULT_SIZE },
> = riot_coap_handler_demos::ping_passive::PingHistoryMutex::new();

let handler = coap_message_demos::full_application_tree(None)
.below(&["ps"], riot_coap_handler_demos::ps::ps_tree())
.below(&["led"], riot_coap_handler_demos::led::all_leds())
.below(&["vfs"], riot_coap_handler_demos::vfs::vfs(""))
.below(&["saul"], riot_coap_handler_demos::saul::SaulHandler::new(&["saul"]))
.below(
&["saul"],
riot_coap_handler_demos::saul::SaulHandler::new(&["saul"]),
)
.below(&["netif"], riot_coap_handler_demos::netif::netif())
.below(&["nib", "neigh"], riot_coap_handler_demos::nib::neighbor_cache())
.below(
&["nib", "neigh"],
riot_coap_handler_demos::nib::neighbor_cache(),
)
.below(&["ping"], riot_coap_handler_demos::ping::ping_tree(&PINGS))
.at(&["pinged"], riot_coap_handler_demos::ping_passive::resource(&PING_PASSIVE))
.with_wkc()
;
.at(
&["pinged"],
riot_coap_handler_demos::ping_passive::resource(&PING_PASSIVE),
)
.with_wkc();
let mut handler = riot_wrappers::coap_handler::v0_2::GcoapHandler(handler);

let mut listener = gcoap::SingleHandlerListener::new_catch_all(&mut handler);

static SLOT: static_cell::StaticCell<gnrc::netreg::callback::Slot<riot_coap_handler_demos::ping::PingCallback>> = static_cell::StaticCell::new();
static SLOT: static_cell::StaticCell<
gnrc::netreg::callback::Slot<riot_coap_handler_demos::ping::PingCallback>,
> = static_cell::StaticCell::new();
PINGS.register(SLOT.init(Default::default()));

static PASSIVE_SLOT: static_cell::StaticCell<gnrc::netreg::callback::Slot<&'static riot_coap_handler_demos::ping_passive::PingHistoryMutex<{ riot_coap_handler_demos::ping_passive::DEFAULT_SIZE }>>> = static_cell::StaticCell::new();
static PASSIVE_SLOT: static_cell::StaticCell<
gnrc::netreg::callback::Slot<
&'static riot_coap_handler_demos::ping_passive::PingHistoryMutex<
{ riot_coap_handler_demos::ping_passive::DEFAULT_SIZE },
>,
>,
> = static_cell::StaticCell::new();
PING_PASSIVE.register(PASSIVE_SLOT.init(Default::default()));

gcoap::scope(|greg| {
greg.register(&mut listener);

println!("CoAP server ready; waiting for interfaces to settle before reporting addresses...");
println!(
"CoAP server ready; waiting for interfaces to settle before reporting addresses..."
);

let sectimer = ztimer::Clock::sec();
sectimer.sleep(ztimer::Ticks(2));

for netif in gnrc::Netif::all() {
println!("Active interface from PID {:?} ({:?})", netif.pid(), netif.pid().get_name().unwrap_or("unnamed"));
println!(
"Active interface from PID {:?} ({:?})",
netif.pid(),
netif.pid().get_name().unwrap_or("unnamed")
);
match netif.ipv6_addrs() {
Ok(addrs) => {
for a in &addrs {
Expand Down
2 changes: 1 addition & 1 deletion examples/rust-hello-world/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// directory for more details.
#![no_std]

use riot_wrappers::riot_main;
use riot_wrappers::println;
use riot_wrappers::riot_main;

extern crate rust_riotmodules;

Expand Down
15 changes: 11 additions & 4 deletions sys/shell/democommands/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#![no_std]

use riot_wrappers::println;
use core::fmt::Write;
use riot_wrappers::println;

riot_wrappers::static_command!(static_hello_world, "hello_world", "Print a greeting", hello_world);
riot_wrappers::static_command!(
static_hello_world,
"hello_world",
"Print a greeting",
hello_world
);

pub fn hello_world<'a>(_w: &mut impl Write, args: impl IntoIterator<Item=&'a str>) {
pub fn hello_world<'a>(_w: &mut impl Write, args: impl IntoIterator<Item = &'a str>) {
let mut args = args.into_iter();
let commandname = args.next().expect("How was this started without an argv[0]?");
let commandname = args
.next()
.expect("How was this started without an argv[0]?");

match args.next() {
Some("--help") => println!("Usage: {commandname}"),
Expand Down
2 changes: 1 addition & 1 deletion tests/rust_minimal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// directory for more details.
#![no_std]

use riot_wrappers::riot_main;
use riot_wrappers::println;
use riot_wrappers::riot_main;

extern crate rust_riotmodules;

Expand Down

0 comments on commit 13188e1

Please sign in to comment.