Skip to content

refactor: adopt C++23 idioms across the firmware - #538

Open
hhvrc wants to merge 3 commits into
developfrom
refactor/modern-cpp
Open

hhvrc wants to merge 3 commits into
developfrom
refactor/modern-cpp

Conversation

@hhvrc

@hhvrc hhvrc commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

No description provided.

hhvrc added 3 commits October 24, 2026 21:57
gen_env_header.py ran git rev-parse in its working directory, which CMake
sets to the build directory. A build directory outside the repository
therefore had no commit and failed on an incomplete openshock_version.h.
Firmware has been built at ESP-IDF's default -Og since the move off
PlatformIO. CI builds of the stable channel (master, final tags and pull
requests into master) now select CONFIG_COMPILER_OPTIMIZATION_SIZE, which
shrinks the image by about 10% (Core-V2 1,292,752 to 1,160,960 bytes) and
frees about 7.6 KB of IRAM on ESP32. -O2 was measured too: it produced a
larger image than -Og for no measurable gain on this I/O-bound firmware.

Develop, beta and local builds stay at -Og so backtraces and debugger
sessions keep every variable. OPENSHOCK_FW_OPTIMIZATION=size|debug
overrides the choice; a local size build gets its own build directory
because an existing sdkconfig wins over the defaults. Variant ids are
unchanged.
- Return std::optional or std::expected instead of bool plus an out
  parameter: config getters, JSON accessors, enum, SemVer and split
  parsers, JSON API responses, GPIO conversion and the OTA helpers.
- Convert::To* become constexpr wrappers over std::from_chars; the
  From* functions and DigitCounter are removed. HexUtils and Checksum
  take string_view and span.
- SemVer::toString uses std::to_chars with checked results, which -O2
  rejected in its earlier form.
- Captive portal parameters report Missing and Invalid separately, so a
  password that fails to decode is no longer treated as absent.
  urlDecode takes a string_view and bounds-checks percent escapes.
- Add util/FunctionRef.h for non-owning callbacks; owning callbacks use
  std::move_only_function.
- Use std::to_underlying, using-aliases and consteval where they apply,
  and drop default cases from exhaustive switches so new enumerators warn.
@hhvrc
hhvrc requested a balanced review from Copilot October 24, 2026 21:01
@hhvrc hhvrc self-assigned this Oct 24, 2026
@github-project-automation github-project-automation Bot moved this to Todo in Roadmap Oct 24, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@coderabbitai

coderabbitai Bot commented Oct 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 118 files, which is 18 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b405a6e6-d630-434b-9664-f7782f0f451a
Commits

Reviewing files that changed from the base of the PR and between 82e79fc and f509d4d.

Files selected for processing: 118
  • components/captive_portal/src/captiveportal/CaptivePortalInstance.cpp
  • components/captive_portal/src/captiveportal/Manager.cpp
  • components/chipset/include/Chipset.h
  • components/common/CMakeLists.txt
  • components/common/host_test/main/CMakeLists.txt
  • components/common/host_test/main/test_boarddescriptor.cpp
  • components/common/host_test/main/test_checksum.cpp
  • components/common/host_test/main/test_convert.cpp
  • components/common/host_test/main/test_digitcounter.cpp
  • components/common/host_test/main/test_enums.cpp
  • components/common/host_test/main/test_functionref.cpp
  • components/common/host_test/main/test_hexutils.cpp
  • components/common/host_test/main/test_semver.cpp
  • components/common/host_test/main/test_stringutils.cpp
  • components/common/include/BoardDescriptor.h
  • components/common/include/Checksum.h
  • components/common/include/Convert.h
  • components/common/include/SemVer.h
  • components/common/include/StringHelpers.h
  • components/common/include/enums/AccountLinkResultCode.h
  • components/common/include/enums/FirmwareBootType.h
  • components/common/include/enums/OtaUpdateChannel.h
  • components/common/include/enums/OtaUpdateStep.h
  • components/common/include/enums/ShockerCommandType.h
  • components/common/include/enums/ShockerModelType.h
  • components/common/include/util/DigitCounter.h
  • components/common/include/util/FunctionRef.h
  • components/common/include/util/HexUtils.h
  • components/common/include/util/ManagedTask.h
  • components/common/src/BoardDescriptor.cpp
  • components/common/src/Convert.cpp
  • components/common/src/DigitCounter.cpp
  • components/common/src/SemVer.cpp
  • components/config/host_test/main/CMakeLists.txt
  • components/config/host_test/main/config_test_helpers.cpp
  • components/config/host_test/main/test_corrupt.cpp
  • components/config/host_test/main/test_defaults.cpp
  • components/config/host_test/main/test_legacy.cpp
  • components/config/host_test/main/test_roundtrip.cpp
  • components/config/include/config/Config.h
  • components/config/include/config/WiFiAuthMode.h
  • components/config/include/config/internal/utils.h
  • components/config/src/BackendConfig.cpp
  • components/config/src/CaptivePortalConfig.cpp
  • components/config/src/Config.cpp
  • components/config/src/EStopConfig.cpp
  • components/config/src/OtaUpdateConfig.cpp
  • components/config/src/RFConfig.cpp
  • components/config/src/SerialInputConfig.cpp
  • components/config/src/WiFiConfig.cpp
  • components/config/src/WiFiCredentials.cpp
  • components/config/src/internal/utils.cpp
  • components/core/include/AppHooks.h
  • components/core/include/GatewayConnectionManager.h
  • components/core/include/serialization/CallbackFn.h
  • components/core/include/serialization/JsonAPI.h
  • components/core/include/serialization/JsonSerial.h
  • components/core/include/wifi/WiFiScanManager.h
  • components/core/include/wifi/WiFiScanStatus.h
  • components/core/src/GatewayClient.cpp
  • components/core/src/GatewayConnectionManager.cpp
  • components/core/src/http/JsonAPI.cpp
  • components/core/src/message_handlers/ShockerCommandList.cpp
  • components/core/src/message_handlers/impl/WSGateway.h
  • components/core/src/message_handlers/impl/WSLocal.h
  • components/core/src/message_handlers/websocket/Gateway.cpp
  • components/core/src/message_handlers/websocket/Local.cpp
  • components/core/src/message_handlers/websocket/gateway/Trigger.cpp
  • components/core/src/message_handlers/websocket/gateway/_InvalidMessage.cpp
  • components/core/src/message_handlers/websocket/local/_InvalidMessage.cpp
  • components/core/src/serialization/JsonAPI.cpp
  • components/core/src/serialization/JsonSerial.cpp
  • components/core/src/wifi/WiFiManager.cpp
  • components/core/src/wifi/WiFiScanManager.cpp
  • components/device_control/host_test/main/host_fakes.cpp
  • components/device_control/host_test/main/stubs/config/Config.h
  • components/device_control/host_test/main/test_estop_state_machine.cpp
  • components/device_control/src/CommandHandler.cpp
  • components/device_control/src/EStopManager.cpp
  • components/device_control/src/estop/EStopStateMachine.h
  • components/device_control/src/radio/RFTransmitter.cpp
  • components/fs/include/fs/LfsPartition.h
  • components/fs/include/fs/StaticFs.h
  • components/fs/src/LfsPartition.cpp
  • components/http/CMakeLists.txt
  • components/http/include/http/HTTPRequestManager.h
  • components/http/src/HTTPRequestManager.cpp
  • components/hwutil/CMakeLists.txt
  • components/hwutil/include/hwutil/PartitionUtils.h
  • components/hwutil/src/PartitionUtils.cpp
  • components/logging/include/Logging.h
  • components/osjson/host_test/main/CMakeLists.txt
  • components/osjson/host_test/main/test_generate.cpp
  • components/osjson/host_test/main/test_getters.cpp
  • components/osjson/host_test/main/test_json.cpp
  • components/osjson/host_test/main/test_navigation.cpp
  • components/osjson/host_test/main/test_parse.cpp
  • components/osjson/host_test/main/test_stress.cpp
  • components/osjson/include/json/Json.h
  • components/osjson/src/Json.cpp
  • components/ota/include/OtaUpdateManager.h
  • components/ota/src/OtaUpdateManager.cpp
  • components/protocols/host_test/main/test_sequence.cpp
  • components/protocols/src/Sequence.cpp
  • components/serial_console/include/serial_console/command_handlers/CommandEntry.h
  • components/serial_console/src/SerialInputHandler.cpp
  • components/serial_console/src/command_handlers/authtoken.cpp
  • components/serial_console/src/command_handlers/domain.cpp
  • components/serial_console/src/command_handlers/echo.cpp
  • components/serial_console/src/command_handlers/estop.cpp
  • components/serial_console/src/command_handlers/hostname.cpp
  • components/serial_console/src/command_handlers/keepalive.cpp
  • components/serial_console/src/command_handlers/rftransmit.cpp
  • components/serial_console/src/command_handlers/rftxpin.cpp
  • scripts/build.py
  • scripts/gen_env_header.py
  • scripts/tests/test_build_cli.py
  • scripts/utils/github.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Change file check

⚠️ Missing — this PR does not add a change file under .changes/.

If this change should show up in the release notes, add one with release-tool new "<title>" --kind <added|changed|deprecated|removed|fixed|security|safety|chore>.

@github-actions

Copy link
Copy Markdown
Contributor

Cpp-Linter Report ⚠️

Some files did not pass the configured checks!

clang-format (v21.1.8) reports: 11 file(s) not formatted
  • components/http/include/http/HTTPRequestManager.h
  • components/common/host_test/main/test_hexutils.cpp
  • components/common/include/Checksum.h
  • components/core/src/message_handlers/websocket/Gateway.cpp
  • components/common/include/util/FunctionRef.h
  • components/common/host_test/main/test_functionref.cpp
  • components/osjson/host_test/main/test_navigation.cpp
  • components/common/include/util/ManagedTask.h
  • components/device_control/host_test/main/test_estop_state_machine.cpp
  • components/common/host_test/main/test_checksum.cpp
  • components/core/src/message_handlers/websocket/Local.cpp

Have any feedback or feature suggestions? Share it here.

Comment on lines +252 to +254
} else if (ec == std::errc::result_out_of_range) {
retryAfter = UINT32_MAX;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nah.

Comment on lines +112 to +115
HubInfoResponse out {};

out.hubId = std::move(*hubId);
out.hubName = std::move(*hubName);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why sint this out = { .whatever = move(*thing) }

CONFIG_LOCK_READ(false);

out = _configData.rf;
CONFIG_LOCK_READ(std::nullopt);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nullopt? what?

}
}
template<typename T> // T inherits from ConfigBase<T>
bool FromJsonStrParsed(T& val, JSON::JsonView json, std::string_view name, bool (*StringParser)(T&, std::string_view), T defaultVal)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why use FunctionRef everywhere else but not here?

constexpr uint32_t Crc32(const T& data)
{
const auto bytes = std::bit_cast<std::array<uint8_t, sizeof(T)>>(data);
return Crc32(bytes.data(), bytes.size());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cant we pass in bytes directly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs a deeper review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is move only function used here

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants