Skip to content

Make Serializer and Deserializer pub and expose incomplete_enum mechanism #73

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

jordens
Copy link

@jordens jordens commented Apr 22, 2025

Summary

miniconf is a library we use to access (get/set over serial, mqtt, store in flash) settings on embedded devices. It is a serde-based hierarchical heterogeneous key-value access mechanism.
We'd like to generate a schema for the settings trees and found serde-reflection very useful for this (thanks!).

We implement the trace_value/trace_type functionality in Tracer using our intermediate miniconf::TreeSerialize/TreeDeserialize traits. See below for what that looks like.

For trace_value and trace_type_once we would like Serializer and Deserializer to be pub. Happy to split that out of this PR if it's uncontroversial.

For trace_type we also need a way to mark the top level enum in incomplete_enums before tracing again (see trace_type).

Test Plan

git clone https://github.com/quartiq/miniconf.git
cd miniconf
# note that miniconf is using this serde-reflection branch in miniconf/Cargo.toml
cargo run -p miniconf --example trace --all-features

Code: https://github.com/quartiq/miniconf/blob/898c4222cc83574c8db44dfe7f63e318736af6ef/miniconf/examples/trace.rs#L131-L173

/// Trace a leaf value
pub fn trace_value<T: TreeSerialize, K: Keys>(
    tracer: &mut Tracer,
    samples: &mut Samples,
    keys: K,
    value: &T,
) -> Result<(Format, Value), Error<serde_reflection::Error>> {
    value.serialize_by_key(keys, Serializer::new(tracer, samples))
}

/// Trace a leaf type once
pub fn trace_type_once<'de, T: TreeDeserialize<'de>, K: Keys>(
    tracer: &mut Tracer,
    samples: &'de Samples,
    keys: K,
) -> Result<Format, Error<serde_reflection::Error>> {
    let mut format = Format::unknown();
    T::probe_by_key(keys, Deserializer::new(tracer, samples, &mut format))?;
    format.reduce();
    Ok(format)
}

/// Trace a leaf type until complete
pub fn trace_type<'de, T: TreeDeserialize<'de>, K: Keys + Clone>(
    tracer: &mut Tracer,
    samples: &'de Samples,
    keys: K,
) -> Result<Format, Error<serde_reflection::Error>> {
    loop {
        let format = trace_type_once::<T, _>(tracer, samples, keys.clone())?;
        if let Format::TypeName(name) = &format {
            if let Some(progress) = tracer.pend_enum(name) {
                debug_assert!(
                    !matches!(progress, EnumProgress::Pending),
                    "failed to make progress tracing enum {name}"
                );
                // Restart the analysis to find more variants.
                continue;
            }
        }
        return Ok(format);
    }
}

@ma2bd
Copy link
Contributor

ma2bd commented May 4, 2025

Interesting. We may want to mark the newly public function(s) as #[doc(hidden)].

Introduces a third EnumProgress variant to mark enums as pending
re-analysis. This now keeps them marked as incomplete but lets the
Deserialize make progress. It upholds the promise the the registry can only
be complete if incomplete_enums is empty.

* add docs to Serializer::new, Deserializer::new
* expose EnumProgress
* make incomplete_enums only pub(crate) again
@jordens jordens marked this pull request as ready for review May 5, 2025 12:37
@jordens jordens requested a review from ma2bd as a code owner May 5, 2025 12:37
@jordens
Copy link
Author

jordens commented May 5, 2025

I think I found a decent way to keep up the invariant that only if incomplete_enums is empty, a complete registry can be returned and I left out the doc hiding. AFAICT it would not have made a difference w.r.t. semver rules anyway.
Let me know if you still prefer to hide the new API.

@jordens jordens changed the title Make Serializer and Deserializer pub, access incomplete_enum mechanism Make Serializer and Deserializer pub and expose incomplete_enum mechanism May 5, 2025
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.

2 participants