Skip to content

add defmt feature - #92

Merged
kaidokert merged 2 commits into
kaidokert:mainfrom
dario23:defmt-feature
Apr 27, 2026
Merged

add defmt feature#92
kaidokert merged 2 commits into
kaidokert:mainfrom
dario23:defmt-feature

Conversation

@dario23

@dario23 dario23 commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

Adds the necessary derives for printing picojson's data types using defmt; gated behind a feature defmt, as is customary in the rust embedded/defmt ecosystem.

Closes #37

Summary by Sourcery

Add optional defmt support across core picojson types to enable structured logging in embedded environments.

New Features:

  • Introduce a defmt feature flag to enable formatted logging of picojson types via the defmt ecosystem.

Enhancements:

  • Derive defmt::Format for key public and internal data structures, including events, numbers, tokenizer states, and error enums when the defmt feature is enabled.
  • Provide a custom defmt::Format implementation for the tokenizer Error type to include detailed position and character information in logs.

Build:

  • Add the optional defmt dependency and wire it to the new defmt feature in Cargo.toml.

CI:

  • Extend the GitHub Actions build matrix to compile the crate with the defmt feature enabled.

Summary by CodeRabbit

  • New Features

    • Added optional defmt feature flag enabling enhanced debug formatting support for JSON parsing types and structures.
  • Chores

    • Extended CI test matrix to validate the new feature configuration.
  • Tests

    • Added comprehensive test coverage for debug formatting functionality.

Adds the necessary `derive`s for printing picojson's data types using
defmt; gated behind a feature `defmt`, as is customary in the
rust embedded/defmt ecosystem.
@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 22f213b4-8275-4403-8d78-7572d5772b1e

📥 Commits

Reviewing files that changed from the base of the PR and between 282f411 and 6f90fa0.

📒 Files selected for processing (5)
  • picojson/Cargo.toml
  • picojson/src/parse_error.rs
  • picojson/src/shared.rs
  • picojson/src/ujson/tokenizer/mod.rs
  • picojson/tests/defmt_test.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • picojson/Cargo.toml

📝 Walkthrough

Walkthrough

This PR adds optional defmt support to the picojson library by introducing a new Cargo feature that enables conditional trait derives and manual implementations of defmt::Format across public types. Changes include a new feature flag, trait derives on structs and enums, two custom defmt::Format implementations, CI test coverage, and validation tests.

Changes

Cohort / File(s) Summary
CI Configuration
.github/workflows/build.yaml
Added a new defmt test matrix entry to run cargo test with the --features defmt flag.
Feature and Dependency Declaration
picojson/Cargo.toml
Added a new optional defmt feature and declared defmt version 1.0 as an optional dependency.
Type Derives for defmt Support
picojson/src/chunk_reader.rs, picojson/src/json_number.rs, picojson/src/json_string.rs, picojson/src/push_parser.rs, picojson/src/shared.rs
Added conditional defmt::Format trait derives via cfg_attr(feature = "defmt", ...) to ChunkReader, NumberResult, JsonNumber, String, Event, and UnexpectedState types.
Custom defmt Format Implementations
picojson/src/parse_error.rs, picojson/src/ujson/tokenizer/mod.rs
Added manual defmt::Format trait implementations for ParseError and tokenizer Error with structured formatting that includes variant details, debug output, and field information. Also added conditional derives to Position and ErrKind.
Test Coverage
picojson/tests/defmt_test.rs
Added new test module gated by the defmt feature that validates all modified public types implement defmt::Format through instantiation and trait-bound assertions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 With defmt's gentle hand we bind,
Each JSON type now formatted kind,
Numbers, strings, and parser states,
Through structured logs they communicate! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'add defmt feature' clearly and accurately describes the primary change—adding a new defmt feature to the crate.
Linked Issues check ✅ Passed The PR successfully implements defmt::Format support for JsonNumber and String types as required by issue #37, plus additional public API types.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing defmt feature support; no unrelated modifications are present in the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@dario23

dario23 commented Apr 15, 2026

Copy link
Copy Markdown
Contributor Author

Added the derives for defmt::Format for all types that had derive(Debug); guess we can discuss if it's necessary/useful for all of them. Open for any other review as well of course.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="picojson/src/ujson/tokenizer/mod.rs" line_range="312-313" />
<code_context>
     }
 }

+#[cfg(feature = "defmt")]
+impl defmt::Format for Error {
+    fn format(&self, f: defmt::Formatter) {
+        defmt::write!(
</code_context>
<issue_to_address>
**suggestion:** Consider delegating to the existing `Debug` impl via `defmt::Debug2Format` to avoid format duplication.

Right now `Error` has two separate formatting implementations that must be kept in sync. To avoid drift, implement `defmt::Format` in terms of the existing `Debug` impl, e.g. call `defmt::Debug2Format(self)` inside `defmt::write!` so any future `Debug` changes are automatically reflected in defmt output.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread picojson/src/ujson/tokenizer/mod.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
picojson/src/ujson/tokenizer/mod.rs (1)

220-224: Optional: Consider adding defmt::Format to Tokenizer.

The Tokenizer struct doesn't have a defmt::Format derive, though all its fields now support formatting. While parser state formatting might be verbose and infrequently needed in embedded contexts, adding the derive could be helpful for debugging parser behavior.

📝 Optional addition
 /// Low-level JSON tokenizer that tracks parsing state and line/column positions.
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub struct Tokenizer<T: BitBucket = u32, D = u8> {
     state: State,
     context: ParseContext<T, D>,
     position: Position,
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@picojson/src/ujson/tokenizer/mod.rs` around lines 220 - 224, Add a
defmt::Format derive to the Tokenizer struct and constrain its generics so the
fields support formatting: add #[derive(defmt::Format)] above pub struct
Tokenizer and change the generic bounds to something like Tokenizer<T: BitBucket
+ defmt::Format, D: defmt::Format> (ensuring State, ParseContext<T,D>, and
Position implement defmt::Format as well via their own derives or bounds); this
enables defmt logging of the Tokenizer (fields: state, context, position)
without changing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@picojson/src/ujson/tokenizer/mod.rs`:
- Around line 220-224: Add a defmt::Format derive to the Tokenizer struct and
constrain its generics so the fields support formatting: add
#[derive(defmt::Format)] above pub struct Tokenizer and change the generic
bounds to something like Tokenizer<T: BitBucket + defmt::Format, D:
defmt::Format> (ensuring State, ParseContext<T,D>, and Position implement
defmt::Format as well via their own derives or bounds); this enables defmt
logging of the Tokenizer (fields: state, context, position) without changing
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0bab9aaf-7b6b-44da-bfec-f8b9165c3691

📥 Commits

Reviewing files that changed from the base of the PR and between 0a80d74 and 282f411.

📒 Files selected for processing (17)
  • .github/workflows/build.yaml
  • picojson/Cargo.toml
  • picojson/src/chunk_reader.rs
  • picojson/src/escape_processor.rs
  • picojson/src/event_processor.rs
  • picojson/src/int_parser.rs
  • picojson/src/json_number.rs
  • picojson/src/json_string.rs
  • picojson/src/parse_error.rs
  • picojson/src/push_parser.rs
  • picojson/src/shared.rs
  • picojson/src/slice_input_buffer.rs
  • picojson/src/stream_buffer.rs
  • picojson/src/ujson/bitstack/mod.rs
  • picojson/src/ujson/tokenizer/mod.rs
  • picojson/tests/push_parser_stress_test.rs
  • picojson/tests/selective_extraction.rs

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request adds support for the defmt logging framework by introducing a defmt feature and deriving defmt::Format for numerous internal and public types. A critical issue was identified in Cargo.toml where the specified defmt version (1.0.1) is non-existent on crates.io, which would cause dependency resolution to fail.

Comment thread picojson/Cargo.toml Outdated
@kaidokert

Copy link
Copy Markdown
Owner

Thanks for putting this up and sorry for late review

@kaidokert

kaidokert commented Apr 20, 2026

Copy link
Copy Markdown
Owner

Added the derives for defmt::Format for all types that had derive(Debug); guess we can discuss if it's necessary/useful for all of them.

That was my first thought looking at it actually - you may not need most of them, unless we add specific unit tests specifically verifying defmt that would require them.

The key things that likely would need defmt are all public-exported structs and enums ( list here , about ~13 of them ). Of course these may transitively require some inner types to be defmt as well.

I'm also gonna guess tagging SliceParser, StreamParser, PushParser is probably also unnecessary - or at least not a full derive with all the internals.

Would you mind try doing those other ~10 only ?

Removed the annotations on inner types that don't propagate
to public interfaces.
@kaidokert
kaidokert merged commit 11a03e6 into kaidokert:main Apr 27, 2026
39 checks passed
@kaidokert

Copy link
Copy Markdown
Owner

Merged this with the trimmed state - will make a new release, PTAL and let me know if this works

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add defmt support

2 participants